NumPy-源码解析-四十六-

60 阅读1小时+

NumPy 源码解析(四十六)

.\numpy\numpy\_core\code_generators\generate_numpy_api.py

#!/usr/bin/env python3
# 导入标准库模块
import os
import argparse

# 导入自定义模块和部分子模块
import genapi
from genapi import \
        TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi

# 导入numpy_api模块
import numpy_api

# use annotated api when running under cpychecker
h_template = r"""
#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)

typedef struct {
        PyObject_HEAD
        npy_bool obval;
} PyBoolScalarObject;

extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];

%s

#else

#if defined(PY_ARRAY_UNIQUE_SYMBOL)
    #define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
    #define _NPY_VERSION_CONCAT_HELPER2(x, y) x ## y
    #define _NPY_VERSION_CONCAT_HELPER(arg) \
        _NPY_VERSION_CONCAT_HELPER2(arg, PyArray_RUNTIME_VERSION)
    #define PyArray_RUNTIME_VERSION \
        _NPY_VERSION_CONCAT_HELPER(PY_ARRAY_UNIQUE_SYMBOL)
#endif

/* By default do not export API in an .so (was never the case on windows) */
#ifndef NPY_API_SYMBOL_ATTRIBUTE
    #define NPY_API_SYMBOL_ATTRIBUTE NPY_VISIBILITY_HIDDEN
#endif

#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
extern NPY_API_SYMBOL_ATTRIBUTE void **PyArray_API;
extern NPY_API_SYMBOL_ATTRIBUTE int PyArray_RUNTIME_VERSION;
#else
#if defined(PY_ARRAY_UNIQUE_SYMBOL)
NPY_API_SYMBOL_ATTRIBUTE void **PyArray_API;
NPY_API_SYMBOL_ATTRIBUTE int PyArray_RUNTIME_VERSION;
#else
static void **PyArray_API = NULL;
static int PyArray_RUNTIME_VERSION = 0;
#endif
#endif

%s

/*
 * The DType classes are inconvenient for the Python generation so exposed
 * manually in the header below  (may be moved).
 */
#include "numpy/_public_dtype_api_table.h"

#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
static int
_import_array(void)
{
  int st;
  PyObject *numpy = PyImport_ImportModule("numpy._core._multiarray_umath");
  if (numpy == NULL && PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
    PyErr_Clear();
    numpy = PyImport_ImportModule("numpy.core._multiarray_umath");
  }

  if (numpy == NULL) {
      return -1;
  }

  PyObject *c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
  Py_DECREF(numpy);
  if (c_api == NULL) {
      return -1;
  }

  if (!PyCapsule_CheckExact(c_api)) {
      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
      Py_DECREF(c_api);
      return -1;
  }
  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
  Py_DECREF(c_api);
  if (PyArray_API == NULL) {
      PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
      return -1;
  }

  /*
   * On exceedingly few platforms these sizes may not match, in which case
   * We do not support older NumPy versions at all.
   */
  if (sizeof(Py_ssize_t) != sizeof(Py_intptr_t) &&
        PyArray_RUNTIME_VERSION < NPY_2_0_API_VERSION) {
  /*
   * 报告运行时错误,指出模块是针对 NumPy 2.0 编译的,但在 NumPy 1.x 上运行。
   * 在 `sizeof(size_t) != sizeof(inptr_t)` 的特定平台上,不支持此功能。
   */
  PyErr_Format(PyExc_RuntimeError,
        "module compiled against NumPy 2.0 but running on NumPy 1.x. "
        "Unfortunately, this is not supported on niche platforms where "
        "`sizeof(size_t) != sizeof(inptr_t)`.");
  }
  /*
   * 执行 NumPy C API 版本的运行时检查。目前,NumPy 2.0 在实际上是 ABI 向后兼容的
   * (在公开的特征子集中)。
   */
  if (NPY_VERSION < PyArray_GetNDArrayCVersion()) {
      PyErr_Format(PyExc_RuntimeError, "module compiled against "\
             "ABI version 0x%%x but this version of numpy is 0x%%x", \
             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
      return -1;
  }
  PyArray_RUNTIME_VERSION = (int)PyArray_GetNDArrayCFeatureVersion();
  /*
   * 执行 NumPy 运行时版本特性的检查,确保模块编译时与运行时的 C API 版本匹配。
   */
  if (NPY_FEATURE_VERSION > PyArray_RUNTIME_VERSION) {
      PyErr_Format(PyExc_RuntimeError,
             "module was compiled against NumPy C-API version 0x%%x "
             "(NumPy " NPY_FEATURE_VERSION_STRING ") "
             "but the running NumPy has C-API version 0x%%x. "
             "Check the section C-API incompatibility at the "
             "Troubleshooting ImportError section at "
             "https://numpy.org/devdocs/user/troubleshooting-importerror.html"
             "#c-api-incompatibility "
             "for indications on how to solve this problem.",
             (int)NPY_FEATURE_VERSION, PyArray_RUNTIME_VERSION);
      return -1;
  }

  /*
   * 执行运行时检查,确保模块的字节顺序与头文件(npy_endian.h)中设置的顺序一致,
   * 作为一种安全保障。
   */
  st = PyArray_GetEndianness();
  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
      PyErr_SetString(PyExc_RuntimeError,
                      "FATAL: module compiled as unknown endian");
      return -1;
  }
#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
  // 如果模块编译为大端序,但在运行时检测到不同的字节序,抛出错误并返回-1
  if (st != NPY_CPU_BIG) {
      PyErr_SetString(PyExc_RuntimeError,
                      "FATAL: module compiled as big endian, but "
                      "detected different endianness at runtime");
      return -1;
  }
#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
  // 如果模块编译为小端序,但在运行时检测到不同的字节序,抛出错误并返回-1
  if (st != NPY_CPU_LITTLE) {
      PyErr_SetString(PyExc_RuntimeError,
                      "FATAL: module compiled as little endian, but "
                      "detected different endianness at runtime");
      return -1;
  }
#endif

// 如果检测字节序没有问题,返回0表示成功
return 0;
}

#define import_array() { \
  // 调用 _import_array() 导入 numpy 扩展模块,若失败则打印错误信息并返回 NULL
  if (_import_array() < 0) { \
    PyErr_Print(); \
    PyErr_SetString( \
        PyExc_ImportError, \
        "numpy._core.multiarray failed to import" \
    ); \
    return NULL; \
  } \
}

#define import_array1(ret) { \
  // 调用 _import_array() 导入 numpy 扩展模块,若失败则打印错误信息并返回指定的 ret 值
  if (_import_array() < 0) { \
    PyErr_Print(); \
    PyErr_SetString( \
        PyExc_ImportError, \
        "numpy._core.multiarray failed to import" \
    ); \
    return ret; \
  } \
}

#define import_array2(msg, ret) { \
  // 调用 _import_array() 导入 numpy 扩展模块,若失败则打印自定义错误信息 msg 并返回指定的 ret 值
  if (_import_array() < 0) { \
    PyErr_Print(); \
    PyErr_SetString(PyExc_ImportError, msg); \
    return ret; \
  } \
}

#endif

#endif
    # 遍历 scalar_bool_values 字典中的每对键值对
    for name, val in scalar_bool_values.items():
        # 获取索引值
        index = val[0]
        # 将 BoolValuesApi 实例添加到 multiarray_api_dict 字典中
        multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)

    # 遍历 types_api 字典中的每对键值对
    for name, val in types_api.items():
        # 获取索引值
        index = val[0]
        # 如果 val 的长度为 1,internal_type 被设为 None;否则,使用 val 的第二个元素作为 internal_type
        internal_type = None if len(val) == 1 else val[1]
        # 将 TypeApi 实例添加到 multiarray_api_dict 字典中
        multiarray_api_dict[name] = TypeApi(
            name, index, 'PyTypeObject', api_name, internal_type)

    # 检查 multiarray_api_dict 和 multiarray_api_index 字典的长度是否相等,若不等则抛出异常
    if len(multiarray_api_dict) != len(multiarray_api_index):
        # 获取两个字典的键集合,并计算其差异
        keys_dict = set(multiarray_api_dict.keys())
        keys_index = set(multiarray_api_index.keys())
        raise AssertionError(
            "Multiarray API size mismatch - "
            "index has extra keys {}, dict has extra keys {}"
            .format(keys_index - keys_dict, keys_dict - keys_index)
        )

    # 初始化一个空列表 extension_list
    extension_list = []
    # 遍历 multiarray_api_index 字典中的每对键值对,按照顺序生成 API 的定义字符串并添加到 extension_list 中
    for name, index in genapi.order_dict(multiarray_api_index):
        api_item = multiarray_api_dict[name]
        # 在 NumPy 2.0 中,API 可能存在空洞(后续可能填充),在这种情况下,添加 `NULL` 来填充
        while len(init_list) < api_item.index:
            init_list.append("        NULL")

        # 生成并添加 api_item 的数组 API 字符串定义到 extension_list 中
        extension_list.append(api_item.define_from_array_api_string())
        # 添加 api_item 的数组 API 定义到 init_list 中
        init_list.append(api_item.array_api_define())
        # 添加 api_item 的内部定义到 module_list 中
        module_list.append(api_item.internal_define())

    # 在 init_list 中添加足够数量的 `NULL` 来填充到 unused_index_max
    while len(init_list) <= unused_index_max:
        init_list.append("        NULL")

    # 根据 header 模板 h_template,生成包含 module_list 和 extension_list 的字符串 s
    s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
    # 将生成的字符串 s 写入 header_file 文件中
    genapi.write_file(header_file, s)

    # 根据 c-code 模板 c_template,生成以逗号分隔的 init_list 字符串 s
    s = c_template % ',\n'.join(init_list)
    # 将生成的字符串 s 写入 c_file 文件中
    genapi.write_file(c_file, s)

    # 返回 targets 变量
    return targets
# 主程序入口函数
def main():
    # 创建命令行参数解析器对象
    parser = argparse.ArgumentParser()
    # 添加命令行参数选项 "-o" 或 "--outdir",指定输出目录路径,类型为字符串
    parser.add_argument(
        "-o",
        "--outdir",
        type=str,
        help="Path to the output directory"
    )
    # 添加命令行参数选项 "-i" 或 "--ignore",指定一个被忽略的输入,类型为字符串
    parser.add_argument(
        "-i",
        "--ignore",
        type=str,
        help="An ignored input - may be useful to add a "
             "dependency between custom targets"
    )
    # 解析命令行参数,将结果存储在args变量中
    args = parser.parse_args()

    # 获取当前工作目录,并与输出目录参数拼接,生成输出目录的绝对路径
    outdir_abs = os.path.join(os.getcwd(), args.outdir)

    # 调用函数生成 API,将输出目录的绝对路径作为参数传递
    generate_api(outdir_abs)


if __name__ == "__main__":
    # 如果当前脚本被直接运行,则调用主函数main()
    main()

.\numpy\numpy\_core\code_generators\generate_ufunc_api.py

# 导入标准库模块 os,用于操作操作系统相关功能
import os
# 导入 argparse 库,用于命令行参数解析
import argparse

# 导入 genapi 模块
import genapi
# 从 genapi 模块中导入 TypeApi 和 FunctionApi 类
from genapi import TypeApi, FunctionApi
# 导入 numpy_api 模块
import numpy_api

# 定义 C 语言头文件模板字符串
h_template = r"""
#ifdef _UMATHMODULE

extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;

%s

#else

#if defined(PY_UFUNC_UNIQUE_SYMBOL)
#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
#endif

/* By default do not export API in an .so (was never the case on windows) */
#ifndef NPY_API_SYMBOL_ATTRIBUTE
    #define NPY_API_SYMBOL_ATTRIBUTE NPY_VISIBILITY_HIDDEN
#endif

#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
extern NPY_API_SYMBOL_ATTRIBUTE void **PyUFunc_API;
#else
#if defined(PY_UFUNC_UNIQUE_SYMBOL)
NPY_API_SYMBOL_ATTRIBUTE void **PyUFunc_API;
#else
static void **PyUFunc_API=NULL;
#endif
#endif

%s

static inline int
_import_umath(void)
{
  PyObject *numpy = PyImport_ImportModule("numpy._core._multiarray_umath");
  if (numpy == NULL && PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
    PyErr_Clear();
    numpy = PyImport_ImportModule("numpy._core._multiarray_umath");
    if (numpy == NULL && PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
      PyErr_Clear();
      numpy = PyImport_ImportModule("numpy.core._multiarray_umath");
    }
  }

  if (numpy == NULL) {
      PyErr_SetString(PyExc_ImportError,
                      "_multiarray_umath failed to import");
      return -1;
  }

  PyObject *c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
  Py_DECREF(numpy);
  if (c_api == NULL) {
      PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
      return -1;
  }

  if (!PyCapsule_CheckExact(c_api)) {
      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
      Py_DECREF(c_api);
      return -1;
  }
  PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
  Py_DECREF(c_api);
  if (PyUFunc_API == NULL) {
      PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
      return -1;
  }
  return 0;
}

# 定义宏,用于导入 umath 模块,并处理异常
#define import_umath() \
    do {\
        UFUNC_NOFPE\
        if (_import_umath() < 0) {\
            PyErr_Print();\
            PyErr_SetString(PyExc_ImportError,\
                    "numpy._core.umath failed to import");\
            return NULL;\
        }\
    } while(0)

# 定义宏,用于导入 umath 模块,并处理异常,返回指定返回值
#define import_umath1(ret) \
    do {\
        UFUNC_NOFPE\
        if (_import_umath() < 0) {\
            PyErr_Print();\
            PyErr_SetString(PyExc_ImportError,\
                    "numpy._core.umath failed to import");\
            return ret;\
        }\
    } while(0)

# 定义宏,用于导入 umath 模块,并处理异常,返回指定返回值和自定义错误消息
#define import_umath2(ret, msg) \
    do {\
        UFUNC_NOFPE\
        if (_import_umath() < 0) {\
            PyErr_Print();\
            PyErr_SetString(PyExc_ImportError, msg);\
            return ret;\
        }\
    } while(0)

# 定义宏,用于导入 ufunc 模块,并处理异常
#define import_ufunc() \
    do {\
        UFUNC_NOFPE\
        if (_import_umath() < 0) {\
            PyErr_Print();\
            PyErr_SetString(PyExc_ImportError,\
                    "numpy._core.umath failed to import");\
        }\
    } while(0)


static inline int
PyUFunc_ImportUFuncAPI()
{
    # 如果 PyUFunc_API 指针为 NULL(不太可能的情况),则执行以下操作
    if (NPY_UNLIKELY(PyUFunc_API == NULL)) {
        # 调用 import_umath1 函数,参数为 -1,用于初始化 umath1 模块
        import_umath1(-1);
    }
    # 返回整数值 0,表示函数执行成功
    return 0;
# Python 脚本的结尾,标识代码块的结束
}

# C 代码的预处理指令,标识代码块的结束
#endif

# C 代码模板字符串,包含 C 语言的注释
c_template = r"""
/* These pointers will be stored in the C-object for use in other
    extension modules
*/

# 定义生成 API 的函数,接收输出目录和是否强制覆盖的标志
def generate_api(output_dir, force=False):
    # 基础文件名
    basename = 'ufunc_api'

    # 构造头文件和 C 文件的完整路径
    h_file = os.path.join(output_dir, '__%s.h' % basename)
    c_file = os.path.join(output_dir, '__%s.c' % basename)
    targets = (h_file, c_file)

    # 源文件列表
    sources = ['ufunc_api_order.txt']
    
    # 调用具体的 API 生成函数
    do_generate_api(targets, sources)
    
    # 返回生成的文件路径
    return targets

# 执行 API 生成的具体功能函数
def do_generate_api(targets, sources):
    # 解析目标文件路径
    header_file = targets[0]
    c_file = targets[1]

    # 合并并生成 UFunc API 的索引
    ufunc_api_index = genapi.merge_api_dicts((
            numpy_api.ufunc_funcs_api,
            numpy_api.ufunc_types_api))
    genapi.check_api_dict(ufunc_api_index)

    # 获取 UFunc API 函数列表
    ufunc_api_list = genapi.get_api_functions('UFUNC_API', numpy_api.ufunc_funcs_api)

    # 创建字典,名称映射到 FunctionApi 实例
    ufunc_api_dict = {}
    api_name = 'PyUFunc_API'
    for f in ufunc_api_list:
        name = f.name
        index = ufunc_api_index[name][0]
        annotations = ufunc_api_index[name][1:]
        ufunc_api_dict[name] = FunctionApi(f.name, index, annotations,
                                           f.return_type, f.args, api_name)

    # 处理 UFunc API 类型
    for name, val in numpy_api.ufunc_types_api.items():
        index = val[0]
        ufunc_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)

    # 设置对象 API
    module_list = []
    extension_list = []
    init_list = []

    # 遍历排序后的 API 索引,生成模块列表、扩展列表和初始化列表
    for name, index in genapi.order_dict(ufunc_api_index):
        api_item = ufunc_api_dict[name]

        # 对于 NumPy 2.0 中可能存在的 API 空洞,填充 NULL
        while len(init_list) < api_item.index:
            init_list.append("        NULL")

        extension_list.append(api_item.define_from_array_api_string())
        init_list.append(api_item.array_api_define())
        module_list.append(api_item.internal_define())

    # 写入头文件
    s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
    genapi.write_file(header_file, s)

    # 写入 C 代码文件
    s = c_template % ',\n'.join(init_list)
    genapi.write_file(c_file, s)

    # 返回生成的文件路径
    return targets

# 主函数,用于命令行参数解析和调用 API 生成函数
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-o",
        "--outdir",
        type=str,
        help="Path to the output directory"
    )
    args = parser.parse_args()

    # 绝对路径化输出目录
    outdir_abs = os.path.join(os.getcwd(), args.outdir)

    # 调用生成 API 函数
    generate_api(outdir_abs)

# 程序入口,判断是否为主程序并执行主函数
if __name__ == "__main__":
    main()

.\numpy\numpy\_core\code_generators\generate_umath.py

"""
Generate the code to build all the internal ufuncs. At the base is the defdict:
a dictionary of Ufunc classes. This is fed to make_code to generate
__umath_generated.c
"""
# 导入必要的库
import os  # 系统操作相关
import re  # 正则表达式模块
import struct  # 解析和打包基于字节的数据结构,如 C 结构体
import sys  # 系统相关的参数和功能
import textwrap  # 文本包装和填充模块
import argparse  # 命令行解析模块

# identity objects
# 定义几个常量和对象
Zero = "PyLong_FromLong(0)"  # 表示整数 0 的 PyLong 对象
One = "PyLong_FromLong(1)"  # 表示整数 1 的 PyLong 对象
True_ = "(Py_INCREF(Py_True), Py_True)"  # 表示布尔值 True 的对象
False_ = "(Py_INCREF(Py_False), Py_False)"  # 表示布尔值 False 的对象
None_ = object()  # 表示 None 的对象
AllOnes = "PyLong_FromLong(-1)"  # 表示整数 -1 的 PyLong 对象
MinusInfinity = 'PyFloat_FromDouble(-NPY_INFINITY)'  # 表示负无穷大的浮点数对象
ReorderableNone = "(Py_INCREF(Py_None), Py_None)"  # 表示可重新排序的 None 对象

class docstrings:
    @staticmethod
    def get(place):
        """
        Returns the C #definition name of docstring according
        to ufunc place. C #definitions are generated by generate_umath_doc.py
        in a separate C header.
        """
        return 'DOC_' + place.upper().replace('.', '_')

# Sentinel value to specify using the full type description in the
# function name
class FullTypeDescr:
    pass

class FuncNameSuffix:
    """Stores the suffix to append when generating functions names.
    """
    def __init__(self, suffix):
        self.suffix = suffix

class TypeDescription:
    """Type signature for a ufunc.

    Attributes
    ----------
    type : str
        Character representing the nominal type.
    func_data : str or None or FullTypeDescr or FuncNameSuffix, optional
        The string representing the expression to insert into the data
        array, if any.
    in_ : str or None, optional
        The typecode(s) of the inputs.
    out : str or None, optional
        The typecode(s) of the outputs.
    astype : dict or None, optional
        If astype['x'] is 'y', uses PyUFunc_x_x_As_y_y/PyUFunc_xx_x_As_yy_y
        instead of PyUFunc_x_x/PyUFunc_xx_x.
    cfunc_alias : str or none, optional
        Appended to inner loop C function name, e.g., FLOAT_{cfunc_alias}. See make_arrays.
        NOTE: it doesn't support 'astype'
    dispatch : str or None, optional
        Dispatch-able source name without its extension '.dispatch.c' that
        contains the definition of ufunc, dispatched at runtime depending on the
        specified targets of the dispatch-able source.
        NOTE: it doesn't support 'astype'
    """
    def __init__(self, type, f=None, in_=None, out=None, astype=None, cfunc_alias=None,
                 dispatch=None):
        self.type = type  # ufunc 的类型标识符
        self.func_data = f  # 插入到数据数组中的表达式字符串,如果有的话
        if astype is None:
            astype = {}
        self.astype_dict = astype  # astype 参数的字典形式
        if in_ is not None:
            in_ = in_.replace('P', type)  # 输入类型的类型码,可能会替换 'P' 为具体类型
        self.in_ = in_
        if out is not None:
            out = out.replace('P', type)  # 输出类型的类型码,可能会替换 'P' 为具体类型
        self.out = out
        self.cfunc_alias = cfunc_alias  # 用于内部循环 C 函数名的附加字符串
        self.dispatch = dispatch  # 可调度的源文件名,不包含 '.dispatch.c' 后缀
    # 定义一个方法用于完成签名设置,接收输入和输出的数量参数 nin 和 nout
    def finish_signature(self, nin, nout):
        # 如果输入数据为空,则使用类型 self.type 复制 nin 次来初始化 self.in_
        if self.in_ is None:
            self.in_ = self.type * nin
        # 断言 self.in_ 的长度必须等于 nin
        assert len(self.in_) == nin
        # 如果输出数据为空,则使用类型 self.type 复制 nout 次来初始化 self.out
        if self.out is None:
            self.out = self.type * nout
        # 断言 self.out 的长度必须等于 nout
        assert len(self.out) == nout
        # 根据 self.type 在 self.astype_dict 中获取对应的数据类型,赋值给 self.astype
        self.astype = self.astype_dict.get(self.type, None)
def TD(types, f=None, astype=None, in_=None, out=None, cfunc_alias=None,
       dispatch=None):
    """
    Generate a TypeDescription instance for each item in types
    """
    # 如果提供了函数 f,则根据 types 和 f 构建函数数据
    if f is not None:
        # 如果 f 是字符串,则使用 build_func_data 函数构建函数数据
        if isinstance(f, str):
            func_data = build_func_data(types, f)
        # 否则,检查 f 的长度是否与 types 相匹配
        elif len(f) != len(types):
            raise ValueError("Number of types and f do not match")
        else:
            func_data = f
    else:
        # 如果未提供 f,则初始化 func_data 为 None
        func_data = (None,) * len(types)
    
    # 如果输入类型 in_ 是字符串,则将其扩展成与 types 相同长度的元组
    if isinstance(in_, str):
        in_ = (in_,) * len(types)
    # 如果 in_ 是 None,则初始化为与 types 相同长度的 None 元组
    elif in_ is None:
        in_ = (None,) * len(types)
    # 否则,检查 in_ 的长度是否与 types 相匹配
    elif len(in_) != len(types):
        raise ValueError("Number of types and inputs do not match")
    
    # 如果输出类型 out 是字符串,则将其扩展成与 types 相同长度的元组
    if isinstance(out, str):
        out = (out,) * len(types)
    # 如果 out 是 None,则初始化为与 types 相同长度的 None 元组
    elif out is None:
        out = (None,) * len(types)
    # 否则,检查 out 的长度是否与 types 相匹配
    elif len(out) != len(types):
        raise ValueError("Number of types and outputs do not match")
    
    # 初始化一个空列表 tds,用于存储 TypeDescription 实例
    tds = []
    for t, fd, i, o in zip(types, func_data, in_, out):
        # 遍历四个列表 types, func_data, in_, out,每次迭代取出一个元素 t, fd, i, o
        # 创建一个空列表 tds 用来存储 TypeDescription 对象
        tds.append(TypeDescription(
            t, f=fd, in_=i, out=o, astype=astype, cfunc_alias=cfunc_alias,
            dispatch=dispt
        ))
    # 返回填充了 TypeDescription 对象的列表 tds
    return tds
class Ufunc:
    """描述一个ufunc。

    Attributes
    ----------
    nin : 输入参数数量
    nout : 输出参数数量
    identity : 两个参数函数的单位元素(比如Zero)
    docstring : ufunc 的文档字符串
    typereso : 类型解析函数,类型为 PyUFunc_TypeResolutionFunc
    type_descriptions : TypeDescription 对象列表
    signature : 通用的ufunc签名(比如用于matmul)
    indexed : 为这些类型字符添加索引循环(ufunc.at)

    """
    def __init__(self, nin, nout, identity, docstring, typereso,
                 *type_descriptions, signature=None, indexed=''):
        self.nin = nin
        self.nout = nout
        if identity is None:
            identity = None_
        self.identity = identity
        self.docstring = docstring
        self.typereso = typereso
        self.type_descriptions = []
        self.signature = signature
        self.indexed = indexed
        for td in type_descriptions:
            self.type_descriptions.extend(td)
        for td in self.type_descriptions:
            td.finish_signature(self.nin, self.nout)

        check_td_order(self.type_descriptions)


# 避免依赖于区域设置的字符串处理实用工具。

import string
UPPER_TABLE = bytes.maketrans(bytes(string.ascii_lowercase, "ascii"),
                              bytes(string.ascii_uppercase, "ascii"))

def english_upper(s):
    """应用英文大小写规则将ASCII字符串转换为全大写。

    这是一个内部实用函数,用于替换对str.upper()的调用,以避免随区域设置更改而改变行为。
    特别是,土耳其语具有拉丁字母"I"的带点和不带点的变体,因此在"tr"区域设置中,
    "i".upper() != "I"。

    Parameters
    ----------
    s : str
        输入的字符串

    Returns
    -------
    uppered : str
        转换为大写后的字符串

    Examples
    --------
    >>> from numpy.lib.utils import english_upper
    >>> s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_'
    >>> english_upper(s)
    'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
    >>> english_upper('')
    ''
    """
    uppered = s.translate(UPPER_TABLE)
    return uppered


# defdict 中的每个条目都是一个 Ufunc 对象。

# name: [字符集合,用于定义它的字符串,
#        使用函数接口的字符集合,
#        给定数据函数的字符串元组,
#        (输入,输出)或者(输入字符串,输出字符串)指定的字符代码签名,
#        单位元素,
#        文档字符串,
#        输出规范(可选)
#        ]

chartoname = {
    '?': 'bool',
    'b': 'byte',
    'B': 'ubyte',
    'h': 'short',
    'H': 'ushort',
    'i': 'int',
    'I': 'uint',
    'l': 'long',
    'L': 'ulong',
    # 我们有时需要int64,但是没有明显的字符表示它,下面使用k并将其定义为`int64`。
    'k': 'int64',
    'K': 'uint64',
    'q': 'longlong',
    'Q': 'ulonglong',
    'e': 'half',
}
    'f': 'float',
    # 'f' 表示对应的数据类型是浮点数(单精度)
    'd': 'double',
    # 'd' 表示对应的数据类型是双精度浮点数
    'g': 'longdouble',
    # 'g' 表示对应的数据类型是长双精度浮点数
    'F': 'cfloat',
    # 'F' 表示对应的数据类型是复数浮点数(单精度)
    'D': 'cdouble',
    # 'D' 表示对应的数据类型是复数双精度浮点数
    'G': 'clongdouble',
    # 'G' 表示对应的数据类型是复数长双精度浮点数
    'M': 'datetime',
    # 'M' 表示对应的数据类型是日期时间对象
    'm': 'timedelta',
    # 'm' 表示对应的数据类型是时间间隔对象
    'O': 'OBJECT',
    # 'O' 表示对应的数据类型是Python对象
    # '.' is like 'O', but calls a method of the object instead
    # of a function
    'P': 'OBJECT',
    # 'P' 表示对应的数据类型是Python对象,但是调用对象的方法而不是函数
}
# 定义字符串变量,包含不支持的对象和布尔类型字符
no_obj_bool = 'bBhHiIlLqQefdgFDGmM'
# 将不支持的对象字符加上 '?' 构成字符串
noobj = '?' + no_obj_bool
# 包含所有可能类型的字符串
all = '?bBhHiIlLqQefdgFDGOmM'

# 单字符变量赋值
O = 'O'
P = 'P'

# 各种整数类型的字符
ints = 'bBhHiIlLqQ'
# 短整数类型的字符
sints = 'bhilq'
# 无符号整数类型的字符
uints = 'BHILQ'
# 时间类型的字符
times = 'Mm'
# 仅时间差类型的字符
timedeltaonly = 'm'
# 含有 'O' 的整数类型字符
intsO = ints + O
# 含有 '?' 的整数类型字符
bints = '?' + ints
# 含有 '?O' 的整数类型字符
bintsO = bints + O
# 浮点数类型字符
flts = 'efdg'
# 含有 'O' 的浮点数类型字符
fltsO = flts + O
# 含有 'P' 的浮点数类型字符
fltsP = flts + P
# 复数类型字符
cmplx = 'FDG'
# 复数向量类型字符
cmplxvec = 'FD'
# 含有 'O' 的复数类型字符
cmplxO = cmplx + O
# 含有 'P' 的复数类型字符
cmplxP = cmplx + P
# 不精确数值类型字符
inexact = flts + cmplx
# 不精确向量类型字符
inexactvec = 'fd'
# 不含整数类型字符的字符集
noint = inexact + O
# 不含整数类型字符但含 'P' 的字符集
nointP = inexact + P
# 含有 'P' 的所有可能类型字符集
allP = bints + times + flts + cmplxP
# 不含布尔类型但含对象的字符集
nobool_or_obj = noobj[1:]
# 不含布尔类型和日期时间类型的字符集
nobool_or_datetime = noobj[1:-1] + O  # 包括 m - timedelta64
# 整数和浮点数类型的字符集
intflt = ints + flts
# 整数、浮点数和复数类型的字符集
intfltcmplx = ints + flts + cmplx
# 不含复数类型的字符集
nocmplx = bints + times + flts
# 不含复数类型但含有 'O' 的字符集
nocmplxO = nocmplx + O
# 不含复数类型但含有 'P' 的字符集
nocmplxP = nocmplx + P
# 不含时间类型或对象的字符集
notimes_or_obj = bints + inexact
# 不含日期时间类型或对象的字符集
nodatetime_or_obj = bints + inexact
# 不含布尔类型和时间类型或对象的字符集
no_bool_times_obj = ints + inexact

# 找到对应于 int64 的代码
int64 = 'k'
# 找到对应于 uint64 的代码
uint64 = 'K'

# 此字典描述了所有 ufunc 的实现,生成所有函数名称及其对应的 ufunc 签名。
# TD 是一个对象,将字符代码列表扩展为 TypeDescriptions 数组。
defdict = {
    'add':
        Ufunc(2, 1, Zero,
              docstrings.get('numpy._core.umath.add'),
              'PyUFunc_AdditionTypeResolver',
              TD('?', cfunc_alias='logical_or', dispatch=[('loops_logical', '?')]),
              TD(no_bool_times_obj, dispatch=[
                  ('loops_arithm_fp', 'fdFD'),
                  ('loops_autovec', ints),
              ]),
              [TypeDescription('M', FullTypeDescr, 'Mm', 'M'),
               TypeDescription('m', FullTypeDescr, 'mm', 'm'),
               TypeDescription('M', FullTypeDescr, 'mM', 'M'),
              ],
              TD(O, f='PyNumber_Add'),
              indexed=intfltcmplx
              ),
    'subtract':
        Ufunc(2, 1, None,  # Zero is only a unit to the right, not the left
              docstrings.get('numpy._core.umath.subtract'),
              'PyUFunc_SubtractionTypeResolver',
              TD(no_bool_times_obj, dispatch=[
                  ('loops_arithm_fp', 'fdFD'),
                  ('loops_autovec', ints),
              ]),
              [TypeDescription('M', FullTypeDescr, 'Mm', 'M'),
               TypeDescription('m', FullTypeDescr, 'mm', 'm'),
               TypeDescription('M', FullTypeDescr, 'MM', 'm'),
              ],
              TD(O, f='PyNumber_Subtract'),
              indexed=intfltcmplx
              ),
    'multiply':
    # 创建一个通用函数对象,用于执行乘法运算
    Ufunc(2, 1, One,  # 定义函数的基本参数和特性
          docstrings.get('numpy._core.umath.multiply'),  # 获取乘法运算的文档字符串
          'PyUFunc_MultiplicationTypeResolver',  # 指定乘法类型解析器
          TD('?', cfunc_alias='logical_and',  # 定义类型描述符,设置C函数别名为logical_and
             dispatch=[('loops_logical', '?')]),  # 指定分发规则,逻辑运算为布尔值
          TD(no_bool_times_obj, dispatch=[  # 定义无布尔值乘法对象的类型描述符和分发规则
              ('loops_arithm_fp', 'fdFD'),  # 浮点数运算循环
              ('loops_autovec', ints),      # 自动向量化循环
          ]),
          [TypeDescription('m', FullTypeDescr, 'mq', 'm'),  # 描述操作数类型的类型描述符列表
           TypeDescription('m', FullTypeDescr, 'qm', 'm'),
           TypeDescription('m', FullTypeDescr, 'md', 'm'),
           TypeDescription('m', FullTypeDescr, 'dm', 'm'),
          ],
          TD(O, f='PyNumber_Multiply'),  # 定义对象类型描述符,使用PyNumber_Multiply函数
          indexed=intfltcmplx  # 指定索引方式为整数、浮点数和复数
          ),
#'true_divide' : aliased to divide in umathmodule.c:initumath
# 创建名为'true_divide'的'Ufunc'对象
'floor_divide':
    # 创建名为'floor_divide'的'Ufunc'对象,参数为(2, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(2, 1, None, # One is only a unit to the right, not the left
          # 获取'floor_divide'的文档字符串
          docstrings.get('numpy._core.umath.floor_divide'),
          # 获取类别为'PyUFunc_DivisionTypeResolver'的类型解析器
          'PyUFunc_DivisionTypeResolver',
          # 创建类型描述对象,针对整数
          TD(ints, cfunc_alias='divide', dispatch=[('loops_arithmetic', 'bBhHiIlLqQ')]),
          # 创建类型描述对象,针对浮点数
          TD(flts),
          # 创建类型描述对象列表,包括('m', FullTypeDescr, 'mq', 'm'),('m', FullTypeDescr, 'md', 'm'),('m', FullTypeDescr, 'mm', 'q')
          [TypeDescription('m', FullTypeDescr, 'mq', 'm'),
           TypeDescription('m', FullTypeDescr, 'md', 'm'),
           TypeDescription('m', FullTypeDescr, 'mm', 'q'),
          ],
          # 创建类型描述对象,针对任意类型,调用'PyNumber_FloorDivide'函数
          TD(O, f='PyNumber_FloorDivide'),
          # indexed为浮点数和整数
          indexed=flts + ints
          ),
# 创建名为'divide'的'Ufunc'对象
'divide':
    # 创建名为'divide'的'Ufunc'对象,参数为(2, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(2, 1, None, # One is only a unit to the right, not the left
          # 获取'divide'的文档字符串
          docstrings.get('numpy._core.umath.divide'),
          # 获取类别为'PyUFunc_TrueDivisionTypeResolver'的类型解析器
          'PyUFunc_TrueDivisionTypeResolver',
          # 创建类型描述对象,针对浮点数和复数,调用'divide'的别名函数
          TD(flts+cmplx, cfunc_alias='divide', dispatch=[('loops_arithm_fp', 'fd')]),
          # 创建类型描述对象列表,包括('m', FullTypeDescr, 'mq', 'm', cfunc_alias='divide'),('m', FullTypeDescr, 'md', 'm', cfunc_alias='divide'),('m', FullTypeDescr, 'mm', 'd', cfunc_alias='divide')
          [TypeDescription('m', FullTypeDescr, 'mq', 'm', cfunc_alias='divide'),
           TypeDescription('m', FullTypeDescr, 'md', 'm', cfunc_alias='divide'),
           TypeDescription('m', FullTypeDescr, 'mm', 'd', cfunc_alias='divide'),
          ],
          # 创建类型描述对象,针对任意类型,调用'PyNumber_TrueDivide'函数
          TD(O, f='PyNumber_TrueDivide'),
          # indexed为浮点数
          indexed=flts
          ),
# 创建名为'conjugate'的'Ufunc'对象
'conjugate':
    # 创建名为'conjugate'的'Ufunc'对象,参数为(1, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(1, 1, None,
          # 获取'conjugate'的文档字符串
          docstrings.get('numpy._core.umath.conjugate'),
          # 类别为None
          None,
          # 创建类型描述对象,针对整数、浮点数和复数,根据具体情况调用不同的循环函数
          TD(ints+flts+cmplx, dispatch=[
              ('loops_arithm_fp', 'FD'),
              ('loops_autovec', ints),
          ]),
          # 创建类型描述对象,针对任意类型,调用'conjugate'函数
          TD(P, f='conjugate'),
          ),
# 创建名为'fmod'的'Ufunc'对象
'fmod':
    # 创建名为'fmod'的'Ufunc'对象,参数为(2, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(2, 1, None,
          # 获取'fmod'的文档字符串
          docstrings.get('numpy._core.umath.fmod'),
          # 类别为None
          None,
          # 创建类型描述对象,针对整数,调用'loops_modulo'函数
          TD(ints, dispatch=[('loops_modulo', ints)]),
          # 创建类型描述对象,针对浮点数,调用'fmod'函数,将结果转换为浮点数类型
          TD(flts, f='fmod', astype={'e': 'f'}),
          # 创建类型描述对象,针对任意类型,调用'fmod'函数
          TD(P, f='fmod'),
          ),
# 创建名为'square'的'Ufunc'对象
'square':
    # 创建名为'square'的'Ufunc'对象,参数为(1, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(1, 1, None,
          # 获取'square'的文档字符串
          docstrings.get('numpy._core.umath.square'),
          # 类别为None
          None,
          # 创建类型描述对象,针对整数和浮点数,根据具体情况调用不同的循环函数
          TD(ints+inexact, dispatch=[
              ('loops_unary_fp', 'fd'),
              ('loops_arithm_fp', 'FD'),
              ('loops_autovec', ints),
          ]),
          # 创建类型描述对象,针对任意类型,调用'Py_square'函数
          TD(O, f='Py_square'),
          ),
# 创建名为'reciprocal'的'Ufunc'对象
'reciprocal':
    # 创建名为'reciprocal'的'Ufunc'对象,参数为(1, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(1, 1, None,
          # 获取'reciprocal'的文档字符串
          docstrings.get('numpy._core.umath.reciprocal'),
          # 类别为None
          None,
          # 创建类型描述对象,针对整数和浮点数,根据具体情况调用不同的循环函数
          TD(ints+inexact, dispatch=[
              ('loops_unary_fp', 'fd'),
              ('loops_autovec', ints),
          ]),
          # 创建类型描述对象,针对任意类型,调用'Py_reciprocal'函数
          TD(O, f='Py_reciprocal'),
          ),
# 创建名为'_ones_like'的'Ufunc'对象
# 虽然不再被numpy.ones_like使用,但仍被一些内部调用所使用
'_ones_like':
    # 创建名为'_ones_like'的'Ufunc'对象,参数为(1, 1, None)
    # 第一个参数为输入数量,第二个参数为输出数量,第三个参数为None
    Ufunc(1, 1, None,
          # 获取'_ones_like'的文档字符串
          docstrings.get('numpy._core.umath._ones_like'),
          # 获取类别为'PyUFunc_OnesLikeTypeResolver'的类型解析器
          'PyUFunc_OnesLikeTypeResolver',
          # 类别为None对象
          TD(noobj),
          # 创建类型描述对象,针对任意类型,调用'Py_get_one'函数
          TD(O, f='Py_get_one'),
          ),
# 创建名为'power'的'Ufunc'对象
    # 使用 Ufunc 类创建一个函数对象,参数依次为:输入参数数量为2,输出参数数量为1,无特定用途
    # 使用 docstrings.get 方法获取 'numpy._core.umath.power' 对应的文档字符串
    # TD(ints): 使用整数类型的类型描述符
    # TD('e', f='pow', astype={'e': 'f'}): 使用浮点数类型描述符 'e',将其视为 'f' 类型的幂函数
    # TD('fd', dispatch=[('loops_umath_fp', 'fd')]): 使用双浮点数类型描述符 'fd',使用 'loops_umath_fp' 分派器进行浮点数计算
    # TD(inexact, f='pow', astype={'e': 'f'}): 使用不精确类型的类型描述符,将其视为 'f' 类型的幂函数
    # TD(O, f='npy_ObjectPower'): 使用对象类型描述符,调用 'npy_ObjectPower' 函数
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.power'),
          None,
          TD(ints),
          TD('e', f='pow', astype={'e': 'f'}),
          TD('fd', dispatch=[('loops_umath_fp', 'fd')]),
          TD(inexact, f='pow', astype={'e': 'f'}),
          TD(O, f='npy_ObjectPower'),
          ),
'float_power':
    # 创建一个名为'float_power'的Ufunc对象,表示浮点数的乘方运算
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.float_power'),  # 使用numpy内部的文档字符串
          None,  # 没有类型解析器
          TD('dgDG', f='pow'),  # 类型描述,表示支持双精度和单精度浮点数的乘方运算
          ),

'absolute':
    # 创建一个名为'absolute'的Ufunc对象,表示取绝对值运算
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.absolute'),  # 使用numpy内部的文档字符串
          'PyUFunc_AbsoluteTypeResolver',  # 使用PyUFunc_AbsoluteTypeResolver类型解析器
          TD(bints+flts+timedeltaonly, dispatch=[
              ('loops_unary_fp', 'fd'),  # 分派到浮点数类型的一元操作循环
              ('loops_logical', '?'),   # 分派到逻辑运算的循环
              ('loops_autovec', ints + 'e'),  # 自动向量化循环
          ]),
          TD(cmplx, dispatch=[('loops_unary_complex', 'FD')],  # 对于复数类型的一元复杂操作循环
             out=('f', 'd', 'g')),  # 输出为单精度、双精度和长双精度浮点数
          TD(O, f='PyNumber_Absolute'),  # 对象的PyNumber_Absolute操作
          ),

'_arg':
    # 创建一个名为'_arg'的Ufunc对象,表示取幅角运算
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath._arg'),  # 使用numpy内部的文档字符串
          None,  # 没有类型解析器
          TD(cmplx, out=('f', 'd', 'g')),  # 对复数类型输出为单精度、双精度和长双精度浮点数
          ),

'negative':
    # 创建一个名为'negative'的Ufunc对象,表示取负运算
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.negative'),  # 使用numpy内部的文档字符串
          'PyUFunc_NegativeTypeResolver',  # 使用PyUFunc_NegativeTypeResolver类型解析器
          TD(ints+flts+timedeltaonly, dispatch=[('loops_unary', ints+'fdg')]),  # 对整数和浮点数的一元操作循环
          TD(cmplx, f='neg'),  # 对复数的负运算
          TD(O, f='PyNumber_Negative'),  # 对象的PyNumber_Negative操作
          ),

'positive':
    # 创建一个名为'positive'的Ufunc对象,表示取正运算
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.positive'),  # 使用numpy内部的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 使用PyUFunc_SimpleUniformOperationTypeResolver类型解析器
          TD(ints+flts+timedeltaonly),  # 对整数、浮点数和时间间隔的操作
          TD(cmplx, f='pos'),  # 对复数的正运算
          TD(O, f='PyNumber_Positive'),  # 对象的PyNumber_Positive操作
          ),

'sign':
    # 创建一个名为'sign'的Ufunc对象,表示符号函数运算
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.sign'),  # 使用numpy内部的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 使用PyUFunc_SimpleUniformOperationTypeResolver类型解析器
          TD(nobool_or_datetime, dispatch=[('loops_autovec', ints)]),  # 对于非布尔和日期时间类型的自动向量化循环
          ),

'greater':
    # 创建一个名为'greater'的Ufunc对象,表示大于比较运算
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.greater'),  # 使用numpy内部的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用PyUFunc_SimpleBinaryComparisonTypeResolver类型解析器
          TD(bints, out='?'),  # 对布尔整数类型输出为布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 类型描述,处理64位整数的比较运算
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],  # 类型描述,处理64位无符号整数的比较运算
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 对于非精确和时间类型的比较运算
          TD('O', out='?'),  # 对象类型的比较运算
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 类型描述,处理对象的比较运算
          ),

'greater_equal':
    # 创建一个名为'greater_equal'的Ufunc对象,表示大于等于比较运算
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.greater_equal'),  # 使用numpy内部的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用PyUFunc_SimpleBinaryComparisonTypeResolver类型解析器
          TD(bints, out='?'),  # 对布尔整数类型输出为布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 类型描述,处理64位整数的比较运算
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],  # 类型描述,处理64位无符号整数的比较运算
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 对于非精确和时间类型的比较运算
          TD('O', out='?'),  # 对象类型的比较运算
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 类型描述,处理对象的比较运算
          ),

'less':
    # 创建一个名为'less'的Ufunc对象,表示小于比较运算
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.less'),  # 使用numpy内部的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用PyUFunc_SimpleBinaryComparisonTypeResolver类型解析器
          TD(bints, out='?'),  # 对布尔整数类型输出为布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 类型描述,处理64位整数的比较运算
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],  # 类型描述,处理64位无符号整数的比较运算
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 对于非精确和时间类型的比较运算
          TD('O', out='?'),  # 对象类型的比较运算
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 类型描述,处理对象的比较运算
          ),
'less_equal':
    # 创建一个二元通用函数对象,用于执行小于等于比较操作
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.less_equal'),  # 获取小于等于操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD(bints, out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 输入参数类型描述
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 分派方式描述
          TD('O', out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 输入参数类型描述
          ),
'equal':
    # 创建一个二元通用函数对象,用于执行相等比较操作
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.equal'),  # 获取相等操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD(bints, out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 输入参数类型描述
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 分派方式描述
          TD('O', out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 输入参数类型描述
          ),
'not_equal':
    # 创建一个二元通用函数对象,用于执行不等比较操作
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.not_equal'),  # 获取不等操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD(bints, out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('q', FullTypeDescr, 'qQ', '?'),  # 输入参数类型描述
           TypeDescription('q', FullTypeDescr, 'Qq', '?')],
          TD(inexact+times, out='?', dispatch=[('loops_comparison', bints+'fd')]),  # 分派方式描述
          TD('O', out='?'),  # 输出类型描述,返回布尔值
          [TypeDescription('O', FullTypeDescr, 'OO', 'O')],  # 输入参数类型描述
          ),
'logical_and':
    # 创建一个二元通用函数对象,用于执行逻辑与操作
    Ufunc(2, 1, True_,
          docstrings.get('numpy._core.umath.logical_and'),  # 获取逻辑与操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD(nodatetime_or_obj, out='?', dispatch=[
              ('loops_logical', '?'),  # 逻辑运算循环类型描述
              ('loops_autovec', ints),  # 自动向量化循环类型描述
          ]),
          TD(O, f='npy_ObjectLogicalAnd'),  # 输出类型描述,使用对象逻辑与功能
          ),
'logical_not':
    # 创建一个一元通用函数对象,用于执行逻辑非操作
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.logical_not'),  # 获取逻辑非操作的文档字符串
          None,  # 无类型解析器
          TD(nodatetime_or_obj, out='?', dispatch=[
              ('loops_logical', '?'),  # 逻辑运算循环类型描述
              ('loops_autovec', ints),  # 自动向量化循环类型描述
          ]),
          TD(O, f='npy_ObjectLogicalNot'),  # 输出类型描述,使用对象逻辑非功能
          ),
'logical_or':
    # 创建一个二元通用函数对象,用于执行逻辑或操作
    Ufunc(2, 1, False_,
          docstrings.get('numpy._core.umath.logical_or'),  # 获取逻辑或操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD(nodatetime_or_obj, out='?', dispatch=[
              ('loops_logical', '?'),  # 逻辑运算循环类型描述
              ('loops_autovec', ints),  # 自动向量化循环类型描述
          ]),
          TD(O, f='npy_ObjectLogicalOr'),  # 输出类型描述,使用对象逻辑或功能
          ),
'logical_xor':
    # 创建一个二元通用函数对象,用于执行逻辑异或操作
    Ufunc(2, 1, False_,
          docstrings.get('numpy._core.umath.logical_xor'),  # 获取逻辑异或操作的文档字符串
          'PyUFunc_SimpleBinaryComparisonTypeResolver',  # 使用简单的二元比较类型解析器
          TD('?', out='?', cfunc_alias='not_equal',  # 输出类型描述,返回布尔值,并使用不等函数别名
                           dispatch=[('loops_comparison', '?')]),  # 分派方式描述
          TD(no_bool_times_obj, out='?', dispatch=[
              ('loops_autovec', ints),  # 自动向量化循环类型描述
          ]),
          # TODO: 使用 obj.logical_xor() 似乎几乎没用:
          TD(P, f='logical_xor'),  # 输出类型描述,使用逻辑异或功能
          ),
'maximum':
    # 创建一个二元通用函数对象,用于返回两个数组中对应元素的最大值
    # 调用Ufunc类的构造函数,传入以下参数:
    # 1. 2:操作数数量为2
    # 2. 1:输出一个结果
    # 3. ReorderableNone:不支持重新排序的操作类型
    # 4. docstrings.get('numpy._core.umath.maximum'):获取 'numpy._core.umath.maximum' 的文档字符串
    # 5. 'PyUFunc_SimpleUniformOperationTypeResolver':指定操作类型解析器为简单统一类型解析器
    # 6. TD('?', cfunc_alias='logical_or', dispatch=[('loops_logical', '?')]):
    #    类型描述对象,操作数类型为布尔型,对应的C函数别名为 'logical_or',分派到逻辑运算循环
    # 7. TD(no_obj_bool, dispatch=[('loops_minmax', ints+'fdg')]):
    #    类型描述对象,不带对象的布尔型,分派到最小最大值循环,支持整数和浮点数
    # 8. TD(O, f='npy_ObjectMax'):
    #    类型描述对象,对象类型,对应的C函数为 'npy_ObjectMax'
    # indexed=flts + ints:支持浮点数和整数索引
'minimum':
    # 创建一个名为 'minimum' 的 Ufunc 对象,这是一个通用函数对象,用于执行最小值操作
    Ufunc(2, 1, ReorderableNone,
          docstrings.get('numpy._core.umath.minimum'),  # 获取最小值函数的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 类型解析器的标识符
          TD('?', cfunc_alias='logical_and',  # 类型描述符,用于布尔运算的逻辑与
                  dispatch=[('loops_logical', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(no_obj_bool, dispatch=[('loops_minmax', ints+'fdg')]),  # 类型描述符,处理非对象布尔运算和整数/浮点数
          TD(O, f='npy_ObjectMin'),  # 类型描述符,处理对象的最小值操作
          indexed=flts + ints,  # 指定支持的数据类型
          ),

'clip':
    # 创建一个名为 'clip' 的 Ufunc 对象,用于对数组进行截断操作
    Ufunc(3, 1, ReorderableNone,
          docstrings.get('numpy._core.umath.clip'),  # 获取截断函数的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 类型解析器的标识符
          TD(noobj),  # 类型描述符,指定输入参数和输出的类型
          [TypeDescription('O', 'npy_ObjectClip', 'OOO', 'O')]  # 类型描述符列表,处理对象的截断操作
          ),

'fmax':
    # 创建一个名为 'fmax' 的 Ufunc 对象,用于执行浮点数的最大值操作
    Ufunc(2, 1, ReorderableNone,
          docstrings.get('numpy._core.umath.fmax'),  # 获取最大值函数的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 类型解析器的标识符
          TD('?', cfunc_alias='logical_or',  # 类型描述符,用于布尔运算的逻辑或
                  dispatch=[('loops_logical', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(no_obj_bool, dispatch=[('loops_minmax', 'fdg')]),  # 类型描述符,处理非对象布尔运算和浮点数/整数
          TD(O, f='npy_ObjectMax'),  # 类型描述符,处理对象的最大值操作
          indexed=flts + ints,  # 指定支持的数据类型
          ),

'fmin':
    # 创建一个名为 'fmin' 的 Ufunc 对象,用于执行浮点数的最小值操作
    Ufunc(2, 1, ReorderableNone,
          docstrings.get('numpy._core.umath.fmin'),  # 获取最小值函数的文档字符串
          'PyUFunc_SimpleUniformOperationTypeResolver',  # 类型解析器的标识符
          TD('?', cfunc_alias='logical_and',  # 类型描述符,用于布尔运算的逻辑与
                  dispatch=[('loops_logical', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(no_obj_bool, dispatch=[('loops_minmax', 'fdg')]),  # 类型描述符,处理非对象布尔运算和浮点数/整数
          TD(O, f='npy_ObjectMin'),  # 类型描述符,处理对象的最小值操作
          indexed=flts + ints,  # 指定支持的数据类型
          ),

'logaddexp':
    # 创建一个名为 'logaddexp' 的 Ufunc 对象,用于执行对数加法操作
    Ufunc(2, 1, MinusInfinity,  # 设置 Ufunc 对象的特殊标志,如无穷小值
          docstrings.get('numpy._core.umath.logaddexp'),  # 获取对数加法函数的文档字符串
          None,  # 没有指定类型解析器
          TD(flts, f="logaddexp", astype={'e': 'f'})  # 类型描述符,指定输入输出的数据类型和特殊处理
          ),

'logaddexp2':
    # 创建一个名为 'logaddexp2' 的 Ufunc 对象,用于执行以2为底的对数加法操作
    Ufunc(2, 1, MinusInfinity,  # 设置 Ufunc 对象的特殊标志,如无穷小值
          docstrings.get('numpy._core.umath.logaddexp2'),  # 获取对数加法函数的文档字符串
          None,  # 没有指定类型解析器
          TD(flts, f="logaddexp2", astype={'e': 'f'})  # 类型描述符,指定输入输出的数据类型和特殊处理
          ),

'bitwise_and':
    # 创建一个名为 'bitwise_and' 的 Ufunc 对象,用于执行位与操作
    Ufunc(2, 1, AllOnes,  # 设置 Ufunc 对象的特殊标志,如全1值
          docstrings.get('numpy._core.umath.bitwise_and'),  # 获取位与函数的文档字符串
          None,  # 没有指定类型解析器
          TD('?', cfunc_alias='logical_and',  # 类型描述符,用于布尔运算的逻辑与
                  dispatch=[('loops_logical', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(ints, dispatch=[('loops_autovec', ints)]),  # 类型描述符,处理整数类型的自动向量化
          TD(O, f='PyNumber_And'),  # 类型描述符,处理对象的位与操作
          ),

'bitwise_or':
    # 创建一个名为 'bitwise_or' 的 Ufunc 对象,用于执行位或操作
    Ufunc(2, 1, Zero,  # 设置 Ufunc 对象的特殊标志,如零值
          docstrings.get('numpy._core.umath.bitwise_or'),  # 获取位或函数的文档字符串
          None,  # 没有指定类型解析器
          TD('?', cfunc_alias='logical_or',  # 类型描述符,用于布尔运算的逻辑或
                  dispatch=[('loops_logical', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(ints, dispatch=[('loops_autovec', ints)]),  # 类型描述符,处理整数类型的自动向量化
          TD(O, f='PyNumber_Or'),  # 类型描述符,处理对象的位或操作
          ),

'bitwise_xor':
    # 创建一个名为 'bitwise_xor' 的 Ufunc 对象,用于执行位异或操作
    Ufunc(2, 1, Zero,  # 设置 Ufunc 对象的特殊标志,如零值
          docstrings.get('numpy._core.umath.bitwise_xor'),  # 获取位异或函数的文档字符串
          None,  # 没有指定类型解析器
          TD('?', cfunc_alias='not_equal',  # 类型描述符,用于布尔运算的不等操作
                  dispatch=[('loops_comparison', '?')]),  # 分派信息,指定如何处理布尔类型的运算
          TD(ints, dispatch=[('loops_autovec', ints)]),  # 类型描述符,处理整数类型的自动向量化
          TD(O, f='PyNumber_Xor'),  # 类型描述符,处理对象的位异或操作
          ),

'invert':
    # 创建一个名为 'invert' 的 Ufunc 对象,用于执行位反转操作
    Ufunc(1, 1, None,  # 设置 Ufunc 对象的特殊标志,这里没有特殊标志
          docstrings.get('numpy._core.umath.invert'),  # 获取位反转函数的文档字符串
          None,  # 没有指定类型解析器
          TD(ints, f='PyNumber_Invert')  # 类型描述符,处理整数类型的位反转操作
          ),
    # 调用 Ufunc 类的构造函数,传入以下参数:
    Ufunc(1, 1, None,
          # 使用 docstrings 字典获取 'numpy._core.umath.invert' 键对应的文档字符串作为参数
          docstrings.get('numpy._core.umath.invert'),
          # 第五个参数为 None
          None,
          # 使用 TD 类创建对象,参数为一个 '?' 字符串,设置 cfunc_alias 为 'logical_not',dispatch 属性为 [('loops_logical', '?')]
          TD('?', cfunc_alias='logical_not', dispatch=[('loops_logical', '?')]),
          # 使用 TD 类创建对象,参数为 ints 变量,设置 dispatch 属性为 [('loops_autovec', ints)]
          TD(ints, dispatch=[('loops_autovec', ints)]),
          # 使用 TD 类创建对象,参数为 O 变量,设置 f 属性为 'PyNumber_Invert'
          TD(O, f='PyNumber_Invert'),
          ),
'left_shift':
    # 定义名为 'left_shift' 的 Ufunc 对象,执行位左移操作
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.left_shift'),
          None,
          TD(ints, dispatch=[('loops_autovec', ints)]),
          TD(O, f='PyNumber_Lshift'),
          ),

'right_shift':
    # 定义名为 'right_shift' 的 Ufunc 对象,执行位右移操作
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.right_shift'),
          None,
          TD(ints, dispatch=[('loops_autovec', ints)]),
          TD(O, f='PyNumber_Rshift'),
          ),

'heaviside':
    # 定义名为 'heaviside' 的 Ufunc 对象,计算海维赛德阶跃函数
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.heaviside'),
          None,
          TD(flts, f='heaviside', astype={'e': 'f'}),
          ),

'degrees':
    # 定义名为 'degrees' 的 Ufunc 对象,将角度从弧度转换为度
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.degrees'),
          None,
          TD(fltsP, f='degrees', astype={'e': 'f'}),
          ),

'rad2deg':
    # 定义名为 'rad2deg' 的 Ufunc 对象,将弧度转换为度
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.rad2deg'),
          None,
          TD(fltsP, f='rad2deg', astype={'e': 'f'}),
          ),

'radians':
    # 定义名为 'radians' 的 Ufunc 对象,将角度从度转换为弧度
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.radians'),
          None,
          TD(fltsP, f='radians', astype={'e': 'f'}),
          ),

'deg2rad':
    # 定义名为 'deg2rad' 的 Ufunc 对象,将度转换为弧度
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.deg2rad'),
          None,
          TD(fltsP, f='deg2rad', astype={'e': 'f'}),
          ),

'arccos':
    # 定义名为 'arccos' 的 Ufunc 对象,计算反余弦值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arccos'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='acos', astype={'e': 'f'}),
          TD(P, f='arccos'),
          ),

'arccosh':
    # 定义名为 'arccosh' 的 Ufunc 对象,计算反双曲余弦值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arccosh'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='acosh', astype={'e': 'f'}),
          TD(P, f='arccosh'),
          ),

'arcsin':
    # 定义名为 'arcsin' 的 Ufunc 对象,计算反正弦值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arcsin'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='asin', astype={'e': 'f'}),
          TD(P, f='arcsin'),
          ),

'arcsinh':
    # 定义名为 'arcsinh' 的 Ufunc 对象,计算反双曲正弦值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arcsinh'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='asinh', astype={'e': 'f'}),
          TD(P, f='arcsinh'),
          ),

'arctan':
    # 定义名为 'arctan' 的 Ufunc 对象,计算反正切值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arctan'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='atan', astype={'e': 'f'}),
          TD(P, f='arctan'),
          ),

'arctanh':
    # 定义名为 'arctanh' 的 Ufunc 对象,计算反双曲正切值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.arctanh'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='atanh', astype={'e': 'f'}),
          TD(P, f='arctanh'),
          ),

'cos':
    # 定义名为 'cos' 的 Ufunc 对象,计算余弦值
    # 调用 Ufunc 类的构造函数,传入以下参数:
    # - 1: 输入参数个数
    # - 1: 输出参数个数
    # - None: 占位符参数
    # - docstrings.get('numpy._core.umath.cos'): 获取 'numpy._core.umath.cos' 对应的文档字符串
    # - None: 占位符参数
    # - TD('e', dispatch=[('loops_umath_fp', 'e')]): 创建类型描述符 'e',设置分派信息为 [('loops_umath_fp', 'e')]
    # - TD('f', dispatch=[('loops_trigonometric', 'f')]): 创建类型描述符 'f',设置分派信息为 [('loops_trigonometric', 'f')]
    # - TD('d', dispatch=[('loops_trigonometric', 'd')]): 创建类型描述符 'd',设置分派信息为 [('loops_trigonometric', 'd')]
    # - TD('g' + cmplx, f='cos'): 创建类型描述符 'g' + cmplx,并指定 f 参数为 'cos'
    # - TD(P, f='cos'): 创建类型描述符 P,并指定 f 参数为 'cos'
'sin':
    # 创建一个 Ufunc 实例,执行单参数 sin 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.sin'),  # 获取 sin 函数的文档字符串
          None,
          TD('e', dispatch=[('loops_umath_fp', 'e')]),  # 对于浮点数类型 'e',使用 'loops_umath_fp' 循环分派
          TD('f', dispatch=[('loops_trigonometric', 'f')]),  # 对于浮点数类型 'f',使用 'loops_trigonometric' 循环分派
          TD('d', dispatch=[('loops_trigonometric', 'd')]),  # 对于浮点数类型 'd',使用 'loops_trigonometric' 循环分派
          TD('g' + cmplx, f='sin'),  # 对于复数类型 'g' + cmplx,执行 sin 函数
          TD(P, f='sin'),  # 使用通用循环分派器执行 sin 函数
          ),
'tan':
    # 创建一个 Ufunc 实例,执行单参数 tan 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.tan'),  # 获取 tan 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='tan', astype={'e': 'f'}),  # 对于 inexact 类型,执行 tan 函数,并将 'e' 转换为 'f'
          TD(P, f='tan'),  # 使用通用循环分派器执行 tan 函数
          ),
'cosh':
    # 创建一个 Ufunc 实例,执行单参数 cosh 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.cosh'),  # 获取 cosh 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='cosh', astype={'e': 'f'}),  # 对于 inexact 类型,执行 cosh 函数,并将 'e' 转换为 'f'
          TD(P, f='cosh'),  # 使用通用循环分派器执行 cosh 函数
          ),
'sinh':
    # 创建一个 Ufunc 实例,执行单参数 sinh 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.sinh'),  # 获取 sinh 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='sinh', astype={'e': 'f'}),  # 对于 inexact 类型,执行 sinh 函数,并将 'e' 转换为 'f'
          TD(P, f='sinh'),  # 使用通用循环分派器执行 sinh 函数
          ),
'tanh':
    # 创建一个 Ufunc 实例,执行单参数 tanh 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.tanh'),  # 获取 tanh 函数的文档字符串
          None,
          TD('e', dispatch=[('loops_umath_fp', 'e')]),  # 使用 'loops_umath_fp' 循环分派对应于 'e' 类型的数据
          TD('fd', dispatch=[('loops_hyperbolic', 'fd')]),  # 使用 'loops_hyperbolic' 循环分派对应于 'fd' 类型的数据
          TD(inexact, f='tanh', astype={'e': 'f'}),  # 对于 inexact 类型,执行 tanh 函数,并将 'e' 转换为 'f'
          TD(P, f='tanh'),  # 使用通用循环分派器执行 tanh 函数
          ),
'exp':
    # 创建一个 Ufunc 实例,执行单参数 exp 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.exp'),  # 获取 exp 函数的文档字符串
          None,
          TD('e', dispatch=[('loops_umath_fp', 'e')]),  # 使用 'loops_umath_fp' 循环分派对应于 'e' 类型的数据
          TD('fd', dispatch=[('loops_exponent_log', 'fd')]),  # 使用 'loops_exponent_log' 循环分派对应于 'fd' 类型的数据
          TD('fdg' + cmplx, f='exp'),  # 对于复数类型 'fdg' + cmplx,执行 exp 函数
          TD(P, f='exp'),  # 使用通用循环分派器执行 exp 函数
          ),
'exp2':
    # 创建一个 Ufunc 实例,执行单参数 exp2 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.exp2'),  # 获取 exp2 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='exp2', astype={'e': 'f'}),  # 对于 inexact 类型,执行 exp2 函数,并将 'e' 转换为 'f'
          TD(P, f='exp2'),  # 使用通用循环分派器执行 exp2 函数
          ),
'expm1':
    # 创建一个 Ufunc 实例,执行单参数 expm1 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.expm1'),  # 获取 expm1 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='expm1', astype={'e': 'f'}),  # 对于 inexact 类型,执行 expm1 函数,并将 'e' 转换为 'f'
          TD(P, f='expm1'),  # 使用通用循环分派器执行 expm1 函数
          ),
'log':
    # 创建一个 Ufunc 实例,执行单参数 log 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.log'),  # 获取 log 函数的文档字符串
          None,
          TD('e', dispatch=[('loops_umath_fp', 'e')]),  # 使用 'loops_umath_fp' 循环分派对应于 'e' 类型的数据
          TD('fd', dispatch=[('loops_exponent_log', 'fd')]),  # 使用 'loops_exponent_log' 循环分派对应于 'fd' 类型的数据
          TD('fdg' + cmplx, f='log'),  # 对于复数类型 'fdg' + cmplx,执行 log 函数
          TD(P, f='log'),  # 使用通用循环分派器执行 log 函数
          ),
'log2':
    # 创建一个 Ufunc 实例,执行单参数 log2 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.log2'),  # 获取 log2 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd' 类型的数据
          TD(inexact, f='log2', astype={'e': 'f'}),  # 对于 inexact 类型,执行 log2 函数,并将 'e' 转换为 'f'
          TD(P, f='log2'),  # 使用通用循环分派器执行 log2 函数
          ),
'log10':
    # 创建一个 Ufunc 实例,执行单参数 log10 函数
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.log10'),  # 获取 log10 函数的文档字符串
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),  # 使用 'loops_umath_fp' 循环分派对应于 'efd
    # 调用 Ufunc 类的构造函数,参数依次为:1, 1, None
    # 第四个参数为获取 'numpy._core.umath.log1p' 的文档字符串
    # 第五个参数为 None
    # 第六个参数为 TD 类的实例化对象,使用 'efd' 参数,包括一个名为 'loops_umath_fp' 的调度项,其值为 'efd'
    # 第七个参数为 TD 类的实例化对象,使用 inexact 参数,设置 'f' 为 'log1p',astype 字段设定为 {'e': 'f'}
    # 第八个参数为 TD 类的实例化对象,使用 P 参数,设置 'f' 为 'log1p'
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.log1p'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(inexact, f='log1p', astype={'e': 'f'}),
          TD(P, f='log1p'),
          ),
'sqrt':
    # 创建一个名为'sqrt'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.sqrt,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.sqrt'),
          None,
          TD('e', f='sqrt', astype={'e': 'f'}),
          TD(inexactvec, dispatch=[('loops_unary_fp', 'fd')]),
          TD('fdg' + cmplx, f='sqrt'),
          TD(P, f='sqrt'),
          ),

'cbrt':
    # 创建一个名为'cbrt'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.cbrt,分发方式为('loops_umath_fp', 'efd')
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.cbrt'),
          None,
          TD('efd', dispatch=[('loops_umath_fp', 'efd')]),
          TD(flts, f='cbrt', astype={'e': 'f'}),
          TD(P, f='cbrt'),
          ),

'ceil':
    # 创建一个名为'ceil'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.ceil,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.ceil'),
          None,
          TD('e', f='ceil', astype={'e': 'f'}),
          TD(inexactvec, dispatch=[('loops_unary_fp', 'fd')]),
          TD('fdg', f='ceil'),
          TD(O, f='npy_ObjectCeil'),
          ),

'trunc':
    # 创建一个名为'trunc'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.trunc,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.trunc'),
          None,
          TD('e', f='trunc', astype={'e': 'f'}),
          TD(inexactvec, dispatch=[('loops_unary_fp', 'fd')]),
          TD('fdg', f='trunc'),
          TD(O, f='npy_ObjectTrunc'),
          ),

'fabs':
    # 创建一个名为'fabs'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.fabs,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.fabs'),
          None,
          TD(flts, f='fabs', astype={'e': 'f'}),
          TD(P, f='fabs'),
       ),

'floor':
    # 创建一个名为'floor'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.floor,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.floor'),
          None,
          TD('e', f='floor', astype={'e': 'f'}),
          TD(inexactvec, dispatch=[('loops_unary_fp', 'fd')]),
          TD('fdg', f='floor'),
          TD(O, f='npy_ObjectFloor'),
          ),

'rint':
    # 创建一个名为'rint'的通用函数对象,接受1个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.rint,无特殊分发方式
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.rint'),
          None,
          TD('e', f='rint', astype={'e': 'f'}),
          TD(inexactvec, dispatch=[('loops_unary_fp', 'fd')]),
          TD('fdg' + cmplx, f='rint'),
          TD(P, f='rint'),
          ),

'arctan2':
    # 创建一个名为'arctan2'的通用函数对象,接受2个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.arctan2,无特殊分发方式
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.arctan2'),
          None,
          TD('e', f='atan2', astype={'e': 'f'}),
          TD('fd', dispatch=[('loops_umath_fp', 'fd')]),
          TD('g', f='atan2', astype={'e': 'f'}),
          TD(P, f='arctan2'),
          ),

'remainder':
    # 创建一个名为'remainder'的通用函数对象,接受2个参数,返回1个结果,无特定类型,文档字符串来源于numpy._core.umath.remainder,使用'PyUFunc_RemainderTypeResolver'进行类型解析
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.remainder'),
          'PyUFunc_RemainderTypeResolver',
          TD(ints, dispatch=[('loops_modulo', ints)]),
          TD(flts),
          [TypeDescription('m', FullTypeDescr, 'mm', 'm')],
          TD(O, f='PyNumber_Remainder'),
          ),

'divmod':
    # 创建一个名为'divmod'的通用函数对象,接受2个参数,返回2个结果,无特定类型,文档字符串来源于numpy._core.umath.divmod,使用'PyUFunc_DivmodTypeResolver'进行类型解析
    Ufunc(2, 2, None,
          docstrings.get('numpy._core.umath.divmod'),
          'PyUFunc_DivmodTypeResolver',
          TD(ints, dispatch=[('loops_modulo', ints)]),
          TD(flts),
          [TypeDescription('m', FullTypeDescr, 'mm', 'qm')],
          # TD(O, f='PyNumber_Divmod'),  # gh-9730
          ),

'hypot':
    # 创建一个名为'hypot'的通用函数对象,接受2个参数,返回1个结果,无特定类型,文档字符串待补充
    # 调用 Ufunc 类执行一个特定的数学函数(这里是 hypot 函数),使用以下参数:
    # 参数1: 2,指定函数的输入参数个数
    # 参数2: 1,指定函数的输出参数个数
    # 参数3: Zero,指定输出的初始值
    # 参数4: docstrings.get('numpy._core.umath.hypot'),获取 hypot 函数的文档字符串
    # 参数5: None,此处没有提供额外的选项
    # 参数6: TD(flts, f='hypot', astype={'e': 'f'}),类型描述对象,描述输入数据类型和函数名称
    # 参数7: TD(P, f='hypot'),类型描述对象,描述参数和函数名称
    Ufunc(2, 1, Zero,
          docstrings.get('numpy._core.umath.hypot'),
          None,
          TD(flts, f='hypot', astype={'e': 'f'}),
          TD(P, f='hypot'),
          ),
'isnan':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理 NaN 检测
    Ufunc(1, 1, None,
          # 获取关于 isnan 函数的文档字符串
          docstrings.get('numpy._core.umath.isnan'),
          'PyUFunc_IsFiniteTypeResolver',
          # 设置类型描述,指定无对象(noobj),输出为布尔类型('?'),并根据分发模式选择不同的实现
          TD(noobj, out='?', dispatch=[
              ('loops_unary_fp_le', inexactvec),
              ('loops_autovec', bints),
          ]),
          ),
'isnat':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理 NaT(Not a Time)检测
    Ufunc(1, 1, None,
          # 获取关于 isnat 函数的文档字符串
          docstrings.get('numpy._core.umath.isnat'),
          'PyUFunc_IsNaTTypeResolver',
          # 设置类型描述,指定以 times 为基础,输出为布尔类型('?')
          TD(times, out='?'),
          ),
'isinf':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理无穷大检测
    Ufunc(1, 1, None,
          # 获取关于 isinf 函数的文档字符串
          docstrings.get('numpy._core.umath.isinf'),
          'PyUFunc_IsFiniteTypeResolver',
          # 设置类型描述,指定无对象(noobj),输出为布尔类型('?'),并根据分发模式选择不同的实现
          TD(noobj, out='?', dispatch=[
              ('loops_unary_fp_le', inexactvec),
              ('loops_autovec', bints + 'mM'),
          ]),
          ),
'isfinite':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理有限数检测
    Ufunc(1, 1, None,
          # 获取关于 isfinite 函数的文档字符串
          docstrings.get('numpy._core.umath.isfinite'),
          'PyUFunc_IsFiniteTypeResolver',
          # 设置类型描述,指定无对象(noobj),输出为布尔类型('?'),并根据分发模式选择不同的实现
          TD(noobj, out='?', dispatch=[
              ('loops_unary_fp_le', inexactvec),
              ('loops_autovec', bints),
          ]),
          ),
'signbit':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理符号位检测
    Ufunc(1, 1, None,
          # 获取关于 signbit 函数的文档字符串
          docstrings.get('numpy._core.umath.signbit'),
          None,
          # 设置类型描述,指定浮点数类型(flts),输出为布尔类型('?'),并根据分发模式选择不同的实现
          TD(flts, out='?', dispatch=[('loops_unary_fp_le', inexactvec)]),
          ),
'copysign':
    # 创建一个具有两个输入参数和单个输出参数的通用函数对象,处理符号复制
    Ufunc(2, 1, None,
          # 获取关于 copysign 函数的文档字符串
          docstrings.get('numpy._core.umath.copysign'),
          None,
          # 设置类型描述,指定浮点数类型(flts)
          TD(flts),
          ),
'nextafter':
    # 创建一个具有两个输入参数和单个输出参数的通用函数对象,处理浮点数邻近值
    Ufunc(2, 1, None,
          # 获取关于 nextafter 函数的文档字符串
          docstrings.get('numpy._core.umath.nextafter'),
          None,
          # 设置类型描述,指定浮点数类型(flts)
          TD(flts),
          ),
'spacing':
    # 创建一个具有单个输入参数和单个输出参数的通用函数对象,处理浮点数间距
    Ufunc(1, 1, None,
          # 获取关于 spacing 函数的文档字符串
          docstrings.get('numpy._core.umath.spacing'),
          None,
          # 设置类型描述,指定浮点数类型(flts)
          TD(flts),
          ),
'modf':
    # 创建一个具有单个输入参数和两个输出参数的通用函数对象,处理浮点数分解
    Ufunc(1, 2, None,
          # 获取关于 modf 函数的文档字符串
          docstrings.get('numpy._core.umath.modf'),
          None,
          # 设置类型描述,指定浮点数类型(flts)
          TD(flts),
          ),
'ldexp' :
    # 创建一个具有两个输入参数和单个输出参数的通用函数对象,处理指数运算
    Ufunc(2, 1, None,
          # 获取关于 ldexp 函数的文档字符串
          docstrings.get('numpy._core.umath.ldexp'),
          None,
          # 设置类型描述,包含多个可能的输入类型和输出类型组合,具体依赖于浮点数和整数类型的组合
          [TypeDescription('e', None, 'ei', 'e'),
          TypeDescription('f', None, 'fi', 'f', dispatch='loops_exponent_log'),
          TypeDescription('e', FuncNameSuffix('int64'), 'e'+int64, 'e'),
          TypeDescription('f', FuncNameSuffix('int64'), 'f'+int64, 'f'),
          TypeDescription('d', None, 'di', 'd', dispatch='loops_exponent_log'),
          TypeDescription('d', FuncNameSuffix('int64'), 'd'+int64, 'd'),
          TypeDescription('g', None, 'gi', 'g'),
          TypeDescription('g', FuncNameSuffix('int64'), 'g'+int64, 'g'),
          ],
          ),
'frexp' :
    # 创建一个具有单个输入参数和两个输出参数的通用函数对象,处理浮点数分解
    Ufunc(1, 2, None,
          # 获取关于 frexp 函数的文档字符串
          docstrings.get('numpy._core.umath.frexp'),
          None,
          # 设置类型描述,包含多个可能的输入类型和输出类型组合,具体依赖于浮点数和整数类型的组合
          [TypeDescription('e', None, 'e', 'ei'),
          TypeDescription('f', None, 'f', 'fi', dispatch='loops_exponent_log'),
          TypeDescription('d', None, 'd', 'di', dispatch='loops_exponent_log'),
          TypeDescription('g', None, 'g', 'gi'),
          ],
          ),
'gcd' :
    # 创建一个通用函数对象,处理最大公约数计算
    # 使用 Ufunc 类创建一个通用函数对象,并传入多个参数进行初始化
    Ufunc(
        # 第一个参数:通用函数的输入参数数量为 2
        2,
        # 第二个参数:通用函数的输出参数数量为 1
        1,
        # 第三个参数:通用函数的输出参数类型为 Zero
        Zero,
        # 第四个参数:从 docstrings 中获取 numpy._core.umath.gcd 的文档字符串
        docstrings.get('numpy._core.umath.gcd'),
        # 第五个参数:指定类型解析器为 "PyUFunc_SimpleUniformOperationTypeResolver"
        "PyUFunc_SimpleUniformOperationTypeResolver",
        # 第六个参数:输入参数类型描述符为 TD(ints)
        TD(ints),
        # 第七个参数:输出参数类型描述符为 TD('O'),并指定函数 'npy_ObjectGCD'
        TD('O', f='npy_ObjectGCD'),
    )
'lcm' :
    # 创建一个 Ufunc 对象,用于最小公倍数的计算,接受两个参数并返回一个值
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.lcm'),  # 获取 lcm 函数的文档字符串
          "PyUFunc_SimpleUniformOperationTypeResolver",  # 操作类型解析器
          TD(ints),  # 参数类型描述,ints 表示整数
          TD('O', f='npy_ObjectLCM'),  # 输出类型描述,'O' 表示对象类型,使用 npy_ObjectLCM 函数处理
          ),

'bitwise_count':
    # 创建一个 Ufunc 对象,用于按位计数,接受一个参数并返回一个值
    Ufunc(1, 1, None,
          docstrings.get('numpy._core.umath.bitwise_count'),  # 获取 bitwise_count 函数的文档字符串
          None,  # 操作类型解析器为 None
          TD(ints, dispatch=[('loops_autovec', ints)], out='B'),  # 参数类型描述,ints 表示整数,'B' 表示布尔类型
          TD(P, f='bit_count'),  # 输出类型描述,使用 bit_count 函数处理
          ),

'matmul' :
    # 创建一个 Ufunc 对象,用于矩阵乘法,接受两个参数并返回一个值
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.matmul'),  # 获取 matmul 函数的文档字符串
          "PyUFunc_SimpleUniformOperationTypeResolver",  # 操作类型解析器
          TD(notimes_or_obj),  # 参数类型描述,notimes_or_obj 表示非 times 或对象类型
          TD(O),  # 输出类型描述,O 表示对象
          signature='(n?,k),(k,m?)->(n?,m?)',  # 签名描述,表示接受的参数形状和返回的结果形状
          ),

'vecdot':
    # 创建一个 Ufunc 对象,用于向量点乘,接受两个参数并返回一个标量
    Ufunc(2, 1, None,
          docstrings.get('numpy._core.umath.vecdot'),  # 获取 vecdot 函数的文档字符串
          "PyUFunc_SimpleUniformOperationTypeResolver",  # 操作类型解析器
          TD(notimes_or_obj),  # 参数类型描述,notimes_or_obj 表示非 times 或对象类型
          TD(O),  # 输出类型描述,O 表示对象
          signature='(n),(n)->()',  # 签名描述,表示接受的参数形状和返回的结果形状
          ),

'str_len':
    # 创建一个 Ufunc 对象,用于计算字符串长度,接受一个参数并返回一个值
    Ufunc(1, 1, Zero,
          docstrings.get('numpy._core.umath.str_len'),  # 获取 str_len 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isalpha':
    # 创建一个 Ufunc 对象,用于检查字符是否为字母,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isalpha'),  # 获取 isalpha 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isdigit':
    # 创建一个 Ufunc 对象,用于检查字符是否为数字,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isdigit'),  # 获取 isdigit 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isspace':
    # 创建一个 Ufunc 对象,用于检查字符是否为空白字符,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isspace'),  # 获取 isspace 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isalnum':
    # 创建一个 Ufunc 对象,用于检查字符是否为字母或数字,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isalnum'),  # 获取 isalnum 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'islower':
    # 创建一个 Ufunc 对象,用于检查字符是否为小写字母,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.islower'),  # 获取 islower 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isupper':
    # 创建一个 Ufunc 对象,用于检查字符是否为大写字母,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isupper'),  # 获取 isupper 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'istitle':
    # 创建一个 Ufunc 对象,用于检查字符串是否为 titlecased,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.istitle'),  # 获取 istitle 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isdecimal':
    # 创建一个 Ufunc 对象,用于检查字符是否为十进制数字,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isdecimal'),  # 获取 isdecimal 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'isnumeric':
    # 创建一个 Ufunc 对象,用于检查字符是否为数字,接受一个参数并返回一个布尔值
    Ufunc(1, 1, False_,
          docstrings.get('numpy._core.umath.isnumeric'),  # 获取 isnumeric 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'find':
    # 创建一个 Ufunc 对象,用于在字符串中查找子字符串,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath.find'),  # 获取 find 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'rfind':
    # 创建一个 Ufunc 对象,用于在字符串中反向查找子字符串,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath.rfind'),  # 获取 rfind 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'count':
    # 创建一个 Ufunc 对象,用于统计子字符串出现的次数,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath.count'),  # 获取 count 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'index':
    # 创建一个 Ufunc 对象,用于在字符串中查找子字符串的位置,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath.index'),  # 获取 index 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'rindex':
    # 创建一个 Ufunc 对象,用于在字符串中反向查找子字符串的位置,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath.rindex'),  # 获取 rindex 函数的文档字符串
          None,  # 操作类型解析器为 None
          ),

'_replace':
    # 创建一个 Ufunc 对象,用于替换字符串中的子字符串,接受四个参数并返回一个值
    Ufunc(4, 1, None,
          docstrings.get('numpy._core.umath._replace'),  # 获取 _replace 函数的文档字符串
          None,  # 操作类型
    # 调用 Ufunc 类的构造函数,传入参数 4, 1, False, 并设置其 docstrings 属性为 'numpy._core.umath.endswith'
    Ufunc(4, 1, False_,
          docstrings.get('numpy._core.umath.endswith'),
          None,
          ),
{
    '_strip_chars':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._strip_chars'),
              None,
              ),
    # 创建一个名为 _strip_chars 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._strip_chars' 对应的文档字符串作为文档
    '_lstrip_chars':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._lstrip_chars'),
              None,
              ),
    # 创建一个名为 _lstrip_chars 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._lstrip_chars' 对应的文档字符串作为文档
    '_rstrip_chars':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._rstrip_chars'),
              None,
              ),
    # 创建一个名为 _rstrip_chars 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._rstrip_chars' 对应的文档字符串作为文档
    '_strip_whitespace':
        Ufunc(1, 1, None,
              docstrings.get('numpy._core.umath._strip_whitespace'),
              None,
              ),
    # 创建一个名为 _strip_whitespace 的 Ufunc 对象,参数为 (1, 1)
    # 使用 docstrings 中与 'numpy._core.umath._strip_whitespace' 对应的文档字符串作为文档
    '_lstrip_whitespace':
        Ufunc(1, 1, None,
              docstrings.get('numpy._core.umath._lstrip_whitespace'),
              None,
              ),
    # 创建一个名为 _lstrip_whitespace 的 Ufunc 对象,参数为 (1, 1)
    # 使用 docstrings 中与 'numpy._core.umath._lstrip_whitespace' 对应的文档字符串作为文档
    '_rstrip_whitespace':
        Ufunc(1, 1, None,
              docstrings.get('numpy._core.umath._rstrip_whitespace'),
              None,
              ),
    # 创建一个名为 _rstrip_whitespace 的 Ufunc 对象,参数为 (1, 1)
    # 使用 docstrings 中与 'numpy._core.umath._rstrip_whitespace' 对应的文档字符串作为文档
    '_expandtabs_length':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._expandtabs_length'),
              None,
              ),
    # 创建一个名为 _expandtabs_length 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._expandtabs_length' 对应的文档字符串作为文档
    '_expandtabs':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._expandtabs'),
              None,
              ),
    # 创建一个名为 _expandtabs 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._expandtabs' 对应的文档字符串作为文档
    '_center':
        Ufunc(3, 1, None,
              docstrings.get('numpy._core.umath._center'),
              None,
              ),
    # 创建一个名为 _center 的 Ufunc 对象,参数为 (3, 1)
    # 使用 docstrings 中与 'numpy._core.umath._center' 对应的文档字符串作为文档
    '_ljust':
        Ufunc(3, 1, None,
              docstrings.get('numpy._core.umath._ljust'),
              None,
              ),
    # 创建一个名为 _ljust 的 Ufunc 对象,参数为 (3, 1)
    # 使用 docstrings 中与 'numpy._core.umath._ljust' 对应的文档字符串作为文档
    '_rjust':
        Ufunc(3, 1, None,
              docstrings.get('numpy._core.umath._rjust'),
              None,
              ),
    # 创建一个名为 _rjust 的 Ufunc 对象,参数为 (3, 1)
    # 使用 docstrings 中与 'numpy._core.umath._rjust' 对应的文档字符串作为文档
    '_zfill':
        Ufunc(2, 1, None,
              docstrings.get('numpy._core.umath._zfill'),
              None,
              ),
    # 创建一个名为 _zfill 的 Ufunc 对象,参数为 (2, 1)
    # 使用 docstrings 中与 'numpy._core.umath._zfill' 对应的文档字符串作为文档
    '_partition_index':
        Ufunc(3, 3, None,
              docstrings.get('numpy._core.umath._partition_index'),
              None,
              ),
    # 创建一个名为 _partition_index 的 Ufunc 对象,参数为 (3, 3)
    # 使用 docstrings 中与 'numpy._core.umath._partition_index' 对应的文档字符串作为文档
    '_rpartition_index':
        Ufunc(3, 3, None,
              docstrings.get('numpy._core.umath._rpartition_index'),
              None,
              ),
    # 创建一个名为 _rpartition_index 的 Ufunc 对象,参数为 (3, 3)
    # 使用 docstrings 中与 'numpy._core.umath._rpartition_index' 对应的文档字符串作为文档
    '_partition':
        Ufunc(2, 3, None,
              docstrings.get('numpy._core.umath._partition'),
              None,
              ),
    # 创建一个名为 _partition 的 Ufunc 对象,参数为 (2, 3)
    # 使用 docstrings 中与 'numpy._core.umath._partition' 对应的文档字符串作为文档
    '_rpartition':
        Ufunc(2, 3, None,
              docstrings.get('numpy._core.umath._rpartition'),
              None,
              ),
    # 创建一个名为 _rpartition 的 Ufunc 对象,参数为 (2, 3)
    # 使用 docstrings 中与 'numpy._core.umath._rpartition' 对应的文档字符串作为文档
}

def indent(st, spaces):
    # 根据给定的 spaces 数量生成等量的空格作为缩进字符串
    indentation = ' '*spaces
    # 将字符串 st 中的每个换行符替换为缩进字符串加换行符,实现整体缩进
    indented = indentation + st.replace('\n', '\n'+indentation)
    # 使用正则表达式去除缩进后面可能存在的空格,确保格式化的文本没有末尾空白
    indented = re.sub(r' +$', r'', indented)
    return indented

# 定义一个字典,将给定的 (nin, nout) 和 type 元组映射到对应的后缀字符串
arity_lookup = {
    (1, 1): {
        'e': 'e_e',
        'f': 'f_f',
        'd': 'd_d',
        'g': 'g_g',
        'F': 'F_F',
        'D': 'D_D',
        'G': 'G_G',
        'O': 'O_O',
        'P': 'O_O_method',
    },
    (2, 1): {
        'e': 'ee_e',
        'f': 'ff_f',
        'd': 'dd_d',
        'g': 'gg_g',
        'F': 'FF_F',
        'D': 'DD_D',
        'G': 'GG_G',
        'O': 'OO_O',
        'P': 'OO_O_method',
    },
    (3, 1): {
        'O': 'OOO_O',
    }
}
    # functions array contains an entry for every type implemented NULL
    # should be placed where PyUfunc_ style function will be filled in
    # later
    # 初始化空列表用于存储 code1 的代码段
    code1list = []
    # 初始化空列表用于存储 code2 的代码段
    code2list = []
    # 初始化空字典用于存储函数名和函数相关信息的映射关系
    dispdict  = {}
    # 获取已排序的函数名列表
    names = sorted(funcdict.keys())
    # 遍历 dispdict 中的每个函数名和对应的函数列表
    for dname, funcs in dispdict.items():
        # 在 code2list 中添加预处理指令,根据条件编译是否禁用优化
        code2list.append(textwrap.dedent(f"""
            #ifndef NPY_DISABLE_OPTIMIZATION
            #include "{dname}.dispatch.h"
            #endif
        """))
        # 遍历函数列表中的每个函数信息元组,生成相关代码段
        for (ufunc_name, func_idx, cfunc_name, inout) in funcs:
            # 在 code2list 中添加函数调度跟踪信息和调用宏的代码段
            code2list.append(textwrap.dedent(f"""\
                NPY_CPU_DISPATCH_TRACE("{ufunc_name}", "{''.join(inout)}");
                NPY_CPU_DISPATCH_CALL_XB({ufunc_name}_functions[{func_idx}] = {cfunc_name});
            """))
    # 返回 code1list 和 code2list 的字符串形式连接结果
    return "\n".join(code1list), "\n".join(code2list)
# 定义一个函数,根据给定的函数字典生成一组代码字符串列表
def make_ufuncs(funcdict):
    # 初始化一个空的代码字符串列表
    code3list = []
    # 对函数字典的键进行排序,并存储在变量 names 中
    names = sorted(funcdict.keys())
    # 将代码字符串列表中的所有元素连接成一个单独的字符串,并返回结果
    return '\n'.join(code3list)


# 定义一个函数,根据给定的函数字典和文件名生成一段代码字符串
def make_code(funcdict, filename):
    # 调用 make_arrays 函数,返回两个代码字符串 code1 和 code2
    code1, code2 = make_arrays(funcdict)
    # 调用 make_ufuncs 函数,生成代码字符串 code3
    code3 = make_ufuncs(funcdict)
    # 对 code2 和 code3 的每一行进行缩进,缩进量为4个空格
    code2 = indent(code2, 4)
    code3 = indent(code3, 4)
    # 构建包含三重引号的多行字符串,用于生成最终的代码文件内容
    code = textwrap.dedent(r"""

    /** Warning this file is autogenerated!!!

        Please make changes to the code generator program (%s)
    **/
    #include "ufunc_object.h"
    #include "ufunc_type_resolution.h"
    #include "loops.h"
    #include "matmul.h"
    #include "clip.h"
    #include "dtypemeta.h"
    #include "_umath_doc_generated.h"

    %s
    /* Returns a borrowed ref of the second value in the matching info tuple */
    PyObject *
    get_info_no_cast(PyUFuncObject *ufunc, PyArray_DTypeMeta *op_dtype,
                     int ndtypes);

    static int
    InitOperators(PyObject *dictionary) {
        PyObject *f, *identity;

    %s
    %s

        return 0;
    }
    """) % (os.path.basename(filename), code1, code2, code3)
    # 返回生成的代码字符串
    return code


# 主函数,程序入口
def main():
    # 创建一个参数解析器对象
    parser = argparse.ArgumentParser()
    # 添加一个命令行参数选项 '-o' 或 '--outfile',用于指定输出文件的路径
    parser.add_argument(
        "-o",
        "--outfile",
        type=str,
        help="Path to the output directory"
    )
    # 解析命令行参数
    args = parser.parse_args()

    # 获取当前脚本文件的文件名,存储在变量 filename 中
    filename = __file__
    # 调用 make_code 函数生成代码,并将结果存储在变量 code 中
    code = make_code(defdict, filename)

    # 如果未指定输出文件路径,则默认使用 '__umath_generated.c'
    if not args.outfile:
        # 这是基于 distutils 的构建方式
        outfile = '__umath_generated.c'
    else:
        # 否则,将输出文件路径设置为当前工作目录下的指定路径
        outfile = os.path.join(os.getcwd(), args.outfile)

    # 打开输出文件,以写入模式写入生成的代码
    with open(outfile, 'w') as f:
        f.write(code)


# 当脚本直接执行时,调用主函数 main
if __name__ == "__main__":
    main()

.\numpy\numpy\_core\code_generators\generate_umath_doc.py

# 导入必要的模块
import sys  # 系统相关的操作
import os   # 系统路径操作
import textwrap  # 文本包装模块,用于处理文档字符串格式
import argparse  # 命令行参数解析模块

# 将当前文件所在目录加入到系统路径中
sys.path.insert(0, os.path.dirname(__file__))
import ufunc_docstrings as docstrings  # 导入自定义模块 ufunc_docstrings,并命名为 docstrings
sys.path.pop(0)  # 移除刚才添加的路径,保持环境干净

# 格式化文档字符串,使其符合特定格式
def normalize_doc(docstring):
    docstring = textwrap.dedent(docstring).strip()  # 去除文档字符串的缩进并去除首尾空白
    docstring = docstring.encode('unicode-escape').decode('ascii')  # 将非 ASCII 字符转义为 Unicode 转义序列
    docstring = docstring.replace(r'"', r'\"')  # 转义双引号
    docstring = docstring.replace(r"'", r"\'")  # 转义单引号
    # 将文档字符串按换行符分割,重新连接成多行字符串,以避免某些编译器不喜欢过长的 C 代码字符串字面量
    docstring = '\\n\"\"'.join(docstring.split(r"\n"))
    return docstring

# 写入生成的 C 代码到目标文件
def write_code(target):
    with open(target, 'w') as fid:
        fid.write(
            "#ifndef NUMPY_CORE_INCLUDE__UMATH_DOC_GENERATED_H_\n"
            "#define NUMPY_CORE_INCLUDE__UMATH_DOC_GENERATED_H_\n"
        )
        # 遍历文档字符串字典,生成 C 代码宏定义
        for place, string in docstrings.docdict.items():
            cdef_name = f"DOC_{place.upper().replace('.', '_')}"
            cdef_str = normalize_doc(string)
            fid.write(f"#define {cdef_name} \"{cdef_str}\"\n")
        fid.write("#endif //NUMPY_CORE_INCLUDE__UMATH_DOC_GENERATED_H\n")

# 主函数,用于命令行参数解析和调用写入函数
def main():
    parser = argparse.ArgumentParser()  # 创建参数解析器
    parser.add_argument(
        "-o",
        "--outfile",
        type=str,
        help="Path to the output directory"
    )
    args = parser.parse_args()  # 解析命令行参数

    outfile = os.path.join(os.getcwd(), args.outfile)  # 获取输出文件路径
    write_code(outfile)  # 调用写入代码函数

# 如果当前脚本作为主程序运行,则执行 main 函数
if __name__ == '__main__':
    main()

.\numpy\numpy\_core\code_generators\numpy_api.py

"""Here we define the exported functions, types, etc... which need to be
exported through a global C pointer.

Each dictionary contains name -> index pair.

Whenever you change one index, you break the ABI (and the ABI version number
should be incremented). Whenever you add an item to one of the dict, the API
needs to be updated in both numpy/core/meson.build and by adding an appropriate
entry to cversion.txt (generate the hash via "python cversions.py").

When adding a function, make sure to use the next integer not used as an index
(in case you use an existing index or jump, the build will stop and raise an
exception, so it should hopefully not get unnoticed).

"""

import os  # 导入操作系统接口模块
import importlib.util  # 导入模块导入工具

def get_annotations():
    # Convoluted because we can't import from numpy.distutils
    # (numpy is not yet built)
    # 根据文件路径生成 genapi.py 的完整路径
    genapi_py = os.path.join(os.path.dirname(__file__), 'genapi.py')
    # 根据 genapi.py 文件创建模块规范
    spec = importlib.util.spec_from_file_location('conv_template', genapi_py)
    # 使用模块规范加载模块
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod.StealRef, mod.MinVersion  # 返回模块中的 StealRef 和 MinVersion 对象

StealRef, MinVersion = get_annotations()  # 调用获取注释函数并分配结果给全局变量

#from code_generators.genapi import StealRef

# index, type
multiarray_global_vars = {
    'NPY_NUMUSERTYPES':             (7, 'int'),           # NPY_NUMUSERTYPES 对应的索引和类型
    'NPY_DEFAULT_ASSIGN_CASTING':   (292, 'NPY_CASTING'),  # NPY_DEFAULT_ASSIGN_CASTING 对应的索引和类型
    'PyDataMem_DefaultHandler':     (306, 'PyObject*'),    # PyDataMem_DefaultHandler 对应的索引和类型
}

multiarray_scalar_bool_values = {
    '_PyArrayScalar_BoolValues':    (9,)  # _PyArrayScalar_BoolValues 对应的索引
}

# index, annotations
# please mark functions that have been checked to not need any annotations
multiarray_types_api = {
    # Slot 1 was never meaningfully used by NumPy
    'PyArray_Type':                     (2,),  # PyArray_Type 对应的索引
    # Internally, PyArrayDescr_Type is a PyArray_DTypeMeta,
    # the following also defines PyArrayDescr_TypeFull (Full appended)
    'PyArrayDescr_Type':                (3, "PyArray_DTypeMeta"),  # PyArrayDescr_Type 对应的索引和注释
    # Unused slot 4, was `PyArrayFlags_Type`
    'PyArrayIter_Type':                 (5,),  # PyArrayIter_Type 对应的索引
    'PyArrayMultiIter_Type':            (6,),  # PyArrayMultiIter_Type 对应的索引
    'PyBoolArrType_Type':               (8,),  # PyBoolArrType_Type 对应的索引
    'PyGenericArrType_Type':            (10,),  # PyGenericArrType_Type 对应的索引
    'PyNumberArrType_Type':             (11,),  # PyNumberArrType_Type 对应的索引
    'PyIntegerArrType_Type':            (12,),  # PyIntegerArrType_Type 对应的索引
    'PySignedIntegerArrType_Type':      (13,),  # PySignedIntegerArrType_Type 对应的索引
    'PyUnsignedIntegerArrType_Type':    (14,),  # PyUnsignedIntegerArrType_Type 对应的索引
    'PyInexactArrType_Type':            (15,),  # PyInexactArrType_Type 对应的索引
    'PyFloatingArrType_Type':           (16,),  # PyFloatingArrType_Type 对应的索引
    'PyComplexFloatingArrType_Type':    (17,),  # PyComplexFloatingArrType_Type 对应的索引
    'PyFlexibleArrType_Type':           (18,),  # PyFlexibleArrType_Type 对应的索引
    'PyCharacterArrType_Type':          (19,),  # PyCharacterArrType_Type 对应的索引
    'PyByteArrType_Type':               (20,),  # PyByteArrType_Type 对应的索引
    'PyShortArrType_Type':              (21,),  # PyShortArrType_Type 对应的索引
    'PyIntArrType_Type':                (22,),  # PyIntArrType_Type 对应的索引
    'PyLongArrType_Type':               (23,),  # PyLongArrType_Type 对应的索引
    'PyLongLongArrType_Type':           (24,),  # PyLongLongArrType_Type 对应的索引
    'PyUByteArrType_Type':              (25,),  # PyUByteArrType_Type 对应的索引
    'PyUShortArrType_Type':             (26,),  # PyUShortArrType_Type 对应的索引
    'PyUIntArrType_Type':               (27,),  # PyUIntArrType_Type 对应的索引
    'PyULongArrType_Type':              (28,),  # PyULongArrType_Type 对应的索引
    'PyULongLongArrType_Type':          (29,),
    'PyFloatArrType_Type':              (30,),
    'PyDoubleArrType_Type':             (31,),
    'PyLongDoubleArrType_Type':         (32,),
    'PyCFloatArrType_Type':             (33,),
    'PyCDoubleArrType_Type':            (34,),
    'PyCLongDoubleArrType_Type':        (35,),
    'PyObjectArrType_Type':             (36,),
    'PyStringArrType_Type':             (37,),
    'PyUnicodeArrType_Type':            (38,),
    'PyVoidArrType_Type':               (39,),


    # 定义一系列的Python数组类型,每个类型对应的唯一标识符用元组表示
    # 这些类型标识符是在Python C API中使用的

    # End 1.5 API
    'PyTimeIntegerArrType_Type':        (214,),
    'PyDatetimeArrType_Type':           (215,),
    'PyTimedeltaArrType_Type':          (216,),
    'PyHalfArrType_Type':               (217,),
    'NpyIter_Type':                     (218,),


    # 定义更多的Python数组类型和它们的唯一标识符
    # 这些标识符属于1.6版本的API

    # End 1.6 API
    # 注意:插槽 320-360 在 `_experimental_dtype_api.h` 中定义,
    #      并在代码生成器之外显式填充,因为元类使得它们难以公开。
    #      (这可能会被重构。)
    # 插槽 366、367、368 是抽象的数据类型
    # End 2.0 API
}
# 在这里有一个单独的右括号,似乎是代码片段的一部分,但没有上下文可以解释其含义
# 因此,这行可能是无意的代码或者漏掉了与之相关的内容

# 定义宏,用于访问 PyArray_API 数组中的索引 6 处的整数值
# 这里假设 PyArray_API 是一个数组或者结构体,存储了一些与 NumPy 多维数组相关的 API 函数或数据

# 定义宏,用于访问 PyArray_API 数组中索引 7 处的 PyTypeObject 结构
# 该结构可能与 NumPy 的布尔数组类型相关

# 定义宏,用于访问 PyArray_API 数组中索引 8 处的 PyBoolScalarObject 结构
# 这可能是一个特定的 NumPy 标量对象,用于处理布尔值

multiarray_funcs_api = {
    '__unused_indices__': (
        [1, 4, 40, 41, 66, 67, 68, 81, 82, 83,
         103, 115, 117, 122, 163, 164, 171, 173, 197,
         201, 202, 208, 219, 220, 221, 222, 223, 278,
         291, 293, 294, 295, 301]
        # range/slots reserved DType classes (see _public_dtype_api_table.h):
        + list(range(320, 361)) + [366, 367, 368]
        ),
    'PyArray_GetNDArrayCVersion':           (0,),
    # 未使用的插槽 40,之前是 `PyArray_SetNumericOps`
    # 未使用的插槽 41,之前是 `PyArray_GetNumericOps`
    'PyArray_INCREF':                       (42,),
    'PyArray_XDECREF':                      (43,),
    # `PyArray_SetStringFunction` 被存根化,未来应该移除
    'PyArray_SetStringFunction':            (44,),
    'PyArray_DescrFromType':                (45,),
    'PyArray_TypeObjectFromType':           (46,),
    'PyArray_Zero':                         (47,),
    'PyArray_One':                          (48,),
    'PyArray_CastToType':                   (49, StealRef(2)),
    'PyArray_CopyInto':                     (50,),
    'PyArray_CopyAnyInto':                  (51,),
    'PyArray_CanCastSafely':                (52,),
    'PyArray_CanCastTo':                    (53,),
    'PyArray_ObjectType':                   (54,),
    'PyArray_DescrFromObject':              (55,),
    'PyArray_ConvertToCommonType':          (56,),
    'PyArray_DescrFromScalar':              (57,),
    'PyArray_DescrFromTypeObject':          (58,),
    'PyArray_Size':                         (59,),
    'PyArray_Scalar':                       (60,),
    'PyArray_FromScalar':                   (61, StealRef(2)),
    'PyArray_ScalarAsCtype':                (62,),
    'PyArray_CastScalarToCtype':            (63,),
    'PyArray_CastScalarDirect':             (64,),
    'PyArray_Pack':                         (65, MinVersion("2.0")),
    # 未使用的插槽 66,之前是 `PyArray_GetCastFunc`
    # 未使用的插槽 67,之前是 `PyArray_FromDims`
    # 未使用的插槽 68,之前是 `PyArray_FromDimsAndDataAndDescr`
    'PyArray_FromAny':                      (69, StealRef(2)),
    'PyArray_EnsureArray':                  (70, StealRef(1)),
    'PyArray_EnsureAnyArray':               (71, StealRef(1)),
    'PyArray_FromFile':                     (72,),
    'PyArray_FromString':                   (73,),
    'PyArray_FromBuffer':                   (74,),
    'PyArray_FromIter':                     (75, StealRef(2)),
    'PyArray_Return':                       (76, StealRef(1)),
    'PyArray_GetField':                     (77, StealRef(2)),
    'PyArray_SetField':                     (78, StealRef(2)),
    'PyArray_Byteswap':                     (79,),
    'PyArray_Resize':                       (80,),
    # 未使用的插槽 81,之前是 `PyArray_MoveInto`
}
# 以上是一个 Python 字典,包含了多个 NumPy 多维数组库中的函数名和它们在 PyArray_API 中的索引
# 每个键值对表示一个函数名及其对应的 API 索引或版本信息,用于在 Python 中操作 NumPy 数组
   `
    # Unused slot 82 was `PyArray_CopyInto` (which replaces `..._CastTo`)
    # 未使用的槽位 82 是 `PyArray_CopyInto`(替代了 `..._CastTo`)

    # Unused slot 82 was `PyArray_CopyAnyInto` (which replaces `..._CastAnyTo`)
    # 未使用的槽位 82 是 `PyArray_CopyAnyInto`(替代了 `..._CastAnyTo`)

    'PyArray_CopyObject':                   (84,),
    # `PyArray_CopyObject` 对应的槽位号为 84

    'PyArray_NewCopy':                      (85,),
    # `PyArray_NewCopy` 对应的槽位号为 85

    'PyArray_ToList':                       (86,),
    # `PyArray_ToList` 对应的槽位号为 86

    'PyArray_ToString':                     (87,),
    # `PyArray_ToString` 对应的槽位号为 87

    'PyArray_ToFile':                       (88,),
    # `PyArray_ToFile` 对应的槽位号为 88

    'PyArray_Dump':                         (89,),
    # `PyArray_Dump` 对应的槽位号为 89

    'PyArray_Dumps':                        (90,),
    # `PyArray_Dumps` 对应的槽位号为 90

    'PyArray_ValidType':                    (91,),
    # `PyArray_ValidType` 对应的槽位号为 91

    'PyArray_UpdateFlags':                  (92,),
    # `PyArray_UpdateFlags` 对应的槽位号为 92

    'PyArray_New':                          (93,),
    # `PyArray_New` 对应的槽位号为 93

    'PyArray_NewFromDescr':                 (94, StealRef(2)),
    # `PyArray_NewFromDescr` 对应的槽位号为 94,并且涉及 StealRef(2) 操作

    'PyArray_DescrNew':                     (95,),
    # `PyArray_DescrNew` 对应的槽位号为 95

    'PyArray_DescrNewFromType':             (96,),
    # `PyArray_DescrNewFromType` 对应的槽位号为 96

    'PyArray_GetPriority':                  (97,),
    # `PyArray_GetPriority` 对应的槽位号为 97

    'PyArray_IterNew':                      (98,),
    # `PyArray_IterNew` 对应的槽位号为 98

    'PyArray_MultiIterNew':                 (99,),
    # `PyArray_MultiIterNew` 对应的槽位号为 99

    'PyArray_PyIntAsInt':                   (100,),
    # `PyArray_PyIntAsInt` 对应的槽位号为 100

    'PyArray_PyIntAsIntp':                  (101,),
    # `PyArray_PyIntAsIntp` 对应的槽位号为 101

    'PyArray_Broadcast':                    (102,),
    # `PyArray_Broadcast` 对应的槽位号为 102

    # Unused slot 103, was `PyArray_FillObjectArray`
    # 未使用的槽位 103 是 `PyArray_FillObjectArray`

    'PyArray_FillWithScalar':               (104,),
    # `PyArray_FillWithScalar` 对应的槽位号为 104

    'PyArray_CheckStrides':                 (105,),
    # `PyArray_CheckStrides` 对应的槽位号为 105

    'PyArray_DescrNewByteorder':            (106,),
    # `PyArray_DescrNewByteorder` 对应的槽位号为 106

    'PyArray_IterAllButAxis':               (107,),
    # `PyArray_IterAllButAxis` 对应的槽位号为 107

    'PyArray_CheckFromAny':                 (108, StealRef(2)),
    # `PyArray_CheckFromAny` 对应的槽位号为 108,并且涉及 StealRef(2) 操作

    'PyArray_FromArray':                    (109, StealRef(2)),
    # `PyArray_FromArray` 对应的槽位号为 109,并且涉及 StealRef(2) 操作

    'PyArray_FromInterface':                (110,),
    # `PyArray_FromInterface` 对应的槽位号为 110

    'PyArray_FromStructInterface':          (111,),
    # `PyArray_FromStructInterface` 对应的槽位号为 111

    'PyArray_FromArrayAttr':                (112,),
    # `PyArray_FromArrayAttr` 对应的槽位号为 112

    'PyArray_ScalarKind':                   (113,),
    # `PyArray_ScalarKind` 对应的槽位号为 113

    'PyArray_CanCoerceScalar':              (114,),
    # `PyArray_CanCoerceScalar` 对应的槽位号为 114

    # Unused slot 115, was `PyArray_NewFlagsObject`
    # 未使用的槽位 115 是 `PyArray_NewFlagsObject`

    'PyArray_CanCastScalar':                (116,),
    # `PyArray_CanCastScalar` 对应的槽位号为 116

    # Unused slot 117, was `PyArray_CompareUCS4`
    # 未使用的槽位 117 是 `PyArray_CompareUCS4`

    'PyArray_RemoveSmallest':               (118,),
    # `PyArray_RemoveSmallest` 对应的槽位号为 118

    'PyArray_ElementStrides':               (119,),
    # `PyArray_ElementStrides` 对应的槽位号为 119

    'PyArray_Item_INCREF':                  (120,),
    # `PyArray_Item_INCREF` 对应的槽位号为 120

    'PyArray_Item_XDECREF':                 (121,),
    # `PyArray_Item_XDECREF` 对应的槽位号为 121

    # Unused slot 122, was `PyArray_FieldNames`
    # 未使用的槽位 122 是 `PyArray_FieldNames`

    'PyArray_Transpose':                    (123,),
    # `PyArray_Transpose` 对应的槽位号为 123

    'PyArray_TakeFrom':                     (124,),
    # `PyArray_TakeFrom` 对应的槽位号为 124

    'PyArray_PutTo':                        (125,),
    # `PyArray_PutTo` 对应的槽位号为 125

    'PyArray_PutMask':                      (126,),
    # `PyArray_PutMask` 对应的槽位号为 126

    'PyArray_Repeat':                       (127,),
    # `PyArray_Repeat` 对应的槽位号为 127

    'PyArray_Choose':                       (128,),
    # `PyArray_Choose` 对应的槽位号为 128

    'PyArray_Sort':                         (129,),
    # `PyArray_Sort` 对应的槽位号为 129

    'PyArray_ArgSort':                      (130,),
    # `PyArray_ArgSort` 对应的槽位号为 130

    'PyArray_SearchSorted':                 (131,),
    # `PyArray_SearchSorted` 对应的槽位号为 131

    'PyArray_ArgMax':                       (132,),
    # `PyArray_ArgMax` 对应的槽位号为 132

    'PyArray_ArgMin':                       (133,),
    # `PyArray_ArgMin` 对应的槽位号为 133

    'PyArray_Reshape':                      (134,),
    # `PyArray_Reshape` 对应的槽位号为 134

    'PyArray_Newshape':                     (135,),
    # `PyArray_Newshape` 对应的槽位号为 135

    'PyArray_Squeeze':                      (136,),
    # `PyArray_Squeeze` 对应的槽位
    'PyArray_SwapAxes':                     (138,),
    'PyArray_Max':                          (139,),
    'PyArray_Min':                          (140,),
    'PyArray_Ptp':                          (141,),
    'PyArray_Mean':                         (142,),
    'PyArray_Trace':                        (143,),
    'PyArray_Diagonal':                     (144,),
    'PyArray_Clip':                         (145,),
    'PyArray_Conjugate':                    (146,),
    'PyArray_Nonzero':                      (147,),
    'PyArray_Std':                          (148,),
    'PyArray_Sum':                          (149,),
    'PyArray_CumSum':                       (150,),
    'PyArray_Prod':                         (151,),
    'PyArray_CumProd':                      (152,),
    'PyArray_All':                          (153,),
    'PyArray_Any':                          (154,),
    'PyArray_Compress':                     (155,),
    'PyArray_Flatten':                      (156,),
    'PyArray_Ravel':                        (157,),
    'PyArray_MultiplyList':                 (158,),
    'PyArray_MultiplyIntList':              (159,),
    'PyArray_GetPtr':                       (160,),
    'PyArray_CompareLists':                 (161,),
    'PyArray_AsCArray':                     (162, StealRef(5)),
    # 未使用的槽位 163, 原为 `PyArray_As1D`
    # 未使用的槽位 164, 原为 `PyArray_As2D`
    'PyArray_Free':                         (165,),
    'PyArray_Converter':                    (166,),
    'PyArray_IntpFromSequence':             (167,),
    'PyArray_Concatenate':                  (168,),
    'PyArray_InnerProduct':                 (169,),
    'PyArray_MatrixProduct':                (170,),
    # 未使用的槽位 171, 原为 `PyArray_CopyAndTranspose`
    'PyArray_Correlate':                    (172,),
    # 未使用的槽位 173, 原为 `PyArray_TypestrConvert`
    'PyArray_DescrConverter':               (174,),
    'PyArray_DescrConverter2':              (175,),
    'PyArray_IntpConverter':                (176,),
    'PyArray_BufferConverter':              (177,),
    'PyArray_AxisConverter':                (178,),
    'PyArray_BoolConverter':                (179,),
    'PyArray_ByteorderConverter':           (180,),
    'PyArray_OrderConverter':               (181,),
    'PyArray_EquivTypes':                   (182,),
    'PyArray_Zeros':                        (183, StealRef(3)),
    'PyArray_Empty':                        (184, StealRef(3)),
    'PyArray_Where':                        (185,),
    'PyArray_Arange':                       (186,),
    'PyArray_ArangeObj':                    (187,),
    'PyArray_SortkindConverter':            (188,),
    'PyArray_LexSort':                      (189,),
    'PyArray_Round':                        (190,),
    'PyArray_EquivTypenums':                (191,),
    'PyArray_RegisterDataType':             (192,),
    'PyArray_RegisterCastFunc':             (193,),
    'PyArray_RegisterCanCast':              (194,),
    'PyArray_InitArrFuncs':                 (195,),
    'PyArray_IntTupleFromIntp':             (196,),
    # 未使用的槽位 197,曾是 `PyArray_TypeNumFromName`
    'PyArray_ClipmodeConverter':            (198,),
    'PyArray_OutputConverter':              (199,),
    'PyArray_BroadcastToShape':             (200,),
    # 未使用的槽位 201,曾是 `_PyArray_SigintHandler`
    # 未使用的槽位 202,曾是 `_PyArray_GetSigintBuf`
    'PyArray_DescrAlignConverter':          (203,),
    'PyArray_DescrAlignConverter2':         (204,),
    'PyArray_SearchsideConverter':          (205,),
    'PyArray_CheckAxis':                    (206,),
    'PyArray_OverflowMultiplyList':         (207,),
    # 未使用的槽位 208,曾是 `PyArray_CompareString`
    'PyArray_MultiIterFromObjects':         (209,),
    'PyArray_GetEndianness':                (210,),
    'PyArray_GetNDArrayCFeatureVersion':    (211,),
    'PyArray_Correlate2':                   (212,),
    'PyArray_NeighborhoodIterNew':          (213,),
    # 结束 1.5 版本的 API
    # 未使用的槽位 219,曾是 `PyArray_SetDatetimeParseFunction`
    # 未使用的槽位 220,曾是 `PyArray_DatetimeToDatetimeStruct`
    # 未使用的槽位 221,曾是 `PyArray_TimedeltaToTimedeltaStruct`
    # 未使用的槽位 222,曾是 `PyArray_DatetimeStructToDatetime`
    # 未使用的槽位 223,曾是 `PyArray_TimedeltaStructToTimedelta`
    # NDIter API
    'NpyIter_New':                          (224,),
    'NpyIter_MultiNew':                     (225,),
    'NpyIter_AdvancedNew':                  (226,),
    'NpyIter_Copy':                         (227,),
    'NpyIter_Deallocate':                   (228,),
    'NpyIter_HasDelayedBufAlloc':           (229,),
    'NpyIter_HasExternalLoop':              (230,),
    'NpyIter_EnableExternalLoop':           (231,),
    'NpyIter_GetInnerStrideArray':          (232,),
    'NpyIter_GetInnerLoopSizePtr':          (233,),
    'NpyIter_Reset':                        (234,),
    'NpyIter_ResetBasePointers':            (235,),
    'NpyIter_ResetToIterIndexRange':        (236,),
    'NpyIter_GetNDim':                      (237,),
    'NpyIter_GetNOp':                       (238,),
    'NpyIter_GetIterNext':                  (239,),
    'NpyIter_GetIterSize':                  (240,),
    'NpyIter_GetIterIndexRange':            (241,),
    'NpyIter_GetIterIndex':                 (242,),
    'NpyIter_GotoIterIndex':                (243,),
    'NpyIter_HasMultiIndex':                (244,),
    'NpyIter_GetShape':                     (245,),
    'NpyIter_GetGetMultiIndex':             (246,),
    'NpyIter_GotoMultiIndex':               (247,),
    'NpyIter_RemoveMultiIndex':             (248,),
    'NpyIter_HasIndex':                     (249,),
    'NpyIter_IsBuffered':                   (250,),
    'NpyIter_IsGrowInner':                  (251,),
    'NpyIter_GetBufferSize':                (252,),
    'NpyIter_GetIndexPtr':                  (253,),
    'NpyIter_GotoIndex':                    (254,),
    'NpyIter_GetDataPtrArray':              (255,),
    'NpyIter_GetDescrArray':                (256,),
    # 返回描述符数组的指针
    'NpyIter_GetOperandArray':              (257,),
    # 返回操作数数组的指针
    'NpyIter_GetIterView':                  (258,),
    # 返回迭代器视图对象的指针
    'NpyIter_GetReadFlags':                 (259,),
    # 返回读取标志位
    'NpyIter_GetWriteFlags':                (260,),
    # 返回写入标志位
    'NpyIter_DebugPrint':                   (261,),
    # 打印调试信息
    'NpyIter_IterationNeedsAPI':            (262,),
    # 返回迭代是否需要 API 的标志位
    'NpyIter_GetInnerFixedStrideArray':     (263,),
    # 返回内部固定步长数组的指针
    'NpyIter_RemoveAxis':                   (264,),
    # 移除轴
    'NpyIter_GetAxisStrideArray':           (265,),
    # 返回轴步长数组的指针
    'NpyIter_RequiresBuffering':            (266,),
    # 返回是否需要缓冲的标志位
    'NpyIter_GetInitialDataPtrArray':       (267,),
    # 返回初始数据指针数组的指针
    'NpyIter_CreateCompatibleStrides':      (268,),
    # 创建兼容步长数组
    #
    'PyArray_CastingConverter':             (269,),
    # 数组类型转换器
    'PyArray_CountNonzero':                 (270,),
    # 计算非零元素个数
    'PyArray_PromoteTypes':                 (271,),
    # 提升数组类型
    'PyArray_MinScalarType':                (272,),
    # 获取最小标量类型
    'PyArray_ResultType':                   (273,),
    # 获取结果数组类型
    'PyArray_CanCastArrayTo':               (274,),
    # 判断数组能否转换为指定类型
    'PyArray_CanCastTypeTo':                (275,),
    # 判断类型能否转换为指定类型
    'PyArray_EinsteinSum':                  (276,),
    # 执行爱因斯坦求和
    'PyArray_NewLikeArray':                 (277, StealRef(3)),
    # 创建与给定数组类似的新数组
    # 未使用的槽位 278,曾是 `PyArray_GetArrayParamsFromObject`
    'PyArray_ConvertClipmodeSequence':      (279,),
    # 转换剪切模式序列
    'PyArray_MatrixProduct2':               (280,),
    # 计算矩阵乘积
    # 结束 1.6 版本 API
    'NpyIter_IsFirstVisit':                 (281,),
    # 检查是否第一次访问
    'PyArray_SetBaseObject':                (282, StealRef(2)),
    # 设置数组的基对象
    'PyArray_CreateSortedStridePerm':       (283,),
    # 创建排序后的步长排列
    'PyArray_RemoveAxesInPlace':            (284,),
    # 就地移除轴
    'PyArray_DebugPrint':                   (285,),
    # 打印数组调试信息
    'PyArray_FailUnlessWriteable':          (286,),
    # 如果不可写则失败
    'PyArray_SetUpdateIfCopyBase':          (287, StealRef(2)),
    # 设置如果是拷贝则更新基对象
    'PyDataMem_NEW':                        (288,),
    # 分配新的内存
    'PyDataMem_FREE':                       (289,),
    # 释放内存
    'PyDataMem_RENEW':                      (290,),
    # 重新分配内存
    # 未使用的槽位 291,曾是 `PyDataMem_SetEventHook`
    # 未使用的槽位 293,曾是 `PyArray_MapIterSwapAxes`
    # 未使用的槽位 294,曾是 `PyArray_MapIterArray`
    # 未使用的槽位 295,曾是 `PyArray_MapIterNext`
    # 结束 1.7 版本 API
    'PyArray_Partition':                    (296,),
    # 对数组执行分区
    'PyArray_ArgPartition':                 (297,),
    # 对数组执行参数分区
    'PyArray_SelectkindConverter':          (298,),
    # 选择种类转换器
    'PyDataMem_NEW_ZEROED':                 (299,),
    # 分配新的零填充内存
    # 结束 1.8 版本 API
    # 结束 1.9 版本 API
    'PyArray_CheckAnyScalarExact':          (300,),
    # 检查任意标量是否精确匹配
    # 结束 1.10 版本 API
    # 未使用的槽位 301,曾是 `PyArray_MapIterArrayCopyIfOverlap`
    # 结束 1.13 版本 API
    'PyArray_ResolveWritebackIfCopy':       (302,),
    # 解决如果是拷贝则写回的问题
    'PyArray_SetWritebackIfCopyBase':       (303,),
    # 设置如果是拷贝则写回的基对象
    # 结束 1.14 版本 API
    'PyDataMem_SetHandler':                 (304, MinVersion("1.22")),
    # 设置内存处理器
    'PyDataMem_GetHandler':                 (305, MinVersion("1.22")),
    # 获取内存处理器
    # 结束 1.22 版本 API
    'NpyDatetime_ConvertDatetime64ToDatetimeStruct': (307, MinVersion("2.0")),
    # 转换 datetime64 到 datetime 结构
    'NpyDatetime_ConvertDatetimeStructToDatetime64': (308, MinVersion("2.0")),
    # 转换 datetime 结构到 datetime64
    'NpyDatetime_ConvertPyDateTimeToDatetimeStruct': (309, MinVersion("2.0")),
    'NpyDatetime_GetDatetimeISO8601StrLen':          (310, MinVersion("2.0")),
    'NpyDatetime_MakeISO8601Datetime':               (311, MinVersion("2.0")),
    'NpyDatetime_ParseISO8601Datetime':              (312, MinVersion("2.0")),
    'NpyString_load':                                (313, MinVersion("2.0")),
    'NpyString_pack':                                (314, MinVersion("2.0")),
    'NpyString_pack_null':                           (315, MinVersion("2.0")),
    'NpyString_acquire_allocator':                   (316, MinVersion("2.0")),
    'NpyString_acquire_allocators':                  (317, MinVersion("2.0")),
    'NpyString_release_allocator':                   (318, MinVersion("2.0")),
    'NpyString_release_allocators':                  (319, MinVersion("2.0")),
    # Slots 320-360 reserved for DType classes (see comment in types)
    'PyArray_GetDefaultDescr':                       (361, MinVersion("2.0")),
    'PyArrayInitDTypeMeta_FromSpec':                 (362, MinVersion("2.0")),
    'PyArray_CommonDType':                           (363, MinVersion("2.0")),
    'PyArray_PromoteDTypeSequence':                  (364, MinVersion("2.0")),
    # The actual public API for this is the inline function
    # `PyDataType_GetArrFuncs` checks for the NumPy runtime version.
    '_PyDataType_GetArrFuncs':                       (365,),
    # End 2.0 API



    # 定义一系列的函数名及其对应的版本要求
    'NpyDatetime_ConvertPyDateTimeToDatetimeStruct': (309, MinVersion("2.0")),
    'NpyDatetime_GetDatetimeISO8601StrLen':          (310, MinVersion("2.0")),
    'NpyDatetime_MakeISO8601Datetime':               (311, MinVersion("2.0")),
    'NpyDatetime_ParseISO8601Datetime':              (312, MinVersion("2.0")),
    'NpyString_load':                                (313, MinVersion("2.0")),
    'NpyString_pack':                                (314, MinVersion("2.0")),
    'NpyString_pack_null':                           (315, MinVersion("2.0")),
    'NpyString_acquire_allocator':                   (316, MinVersion("2.0")),
    'NpyString_acquire_allocators':                  (317, MinVersion("2.0")),
    'NpyString_release_allocator':                   (318, MinVersion("2.0")),
    'NpyString_release_allocators':                  (319, MinVersion("2.0")),
    # 320-360 留作 DType 类使用(详见 types 中的注释)
    'PyArray_GetDefaultDescr':                       (361, MinVersion("2.0")),
    'PyArrayInitDTypeMeta_FromSpec':                 (362, MinVersion("2.0")),
    'PyArray_CommonDType':                           (363, MinVersion("2.0")),
    'PyArray_PromoteDTypeSequence':                  (364, MinVersion("2.0")),
    # 实际公共 API 为内联函数
    # `PyDataType_GetArrFuncs` 检查 NumPy 运行时版本。
    '_PyDataType_GetArrFuncs':                       (365,),
    # 2.0 版本 API 结束
# 该字典定义了一些名为 ufunc_types_api 的键值对,每个键都是一个字符串,对应的值是一个包含整数的元组
ufunc_types_api = {
    'PyUFunc_Type':                             (0,)
}

# 该字典定义了一些名为 ufunc_funcs_api 的键值对,每个键都是一个字符串,对应的值是一个包含整数的元组
ufunc_funcs_api = {
    '__unused_indices__': [3, 25, 26, 29, 32],
    'PyUFunc_FromFuncAndData':                  (1,),
    'PyUFunc_RegisterLoopForType':              (2,),
    # 未使用的槽 3,原先是 `PyUFunc_GenericFunction`
    'PyUFunc_f_f_As_d_d':                       (4,),
    'PyUFunc_d_d':                              (5,),
    'PyUFunc_f_f':                              (6,),
    'PyUFunc_g_g':                              (7,),
    'PyUFunc_F_F_As_D_D':                       (8,),
    'PyUFunc_F_F':                              (9,),
    'PyUFunc_D_D':                              (10,),
    'PyUFunc_G_G':                              (11,),
    'PyUFunc_O_O':                              (12,),
    'PyUFunc_ff_f_As_dd_d':                     (13,),
    'PyUFunc_ff_f':                             (14,),
    'PyUFunc_dd_d':                             (15,),
    'PyUFunc_gg_g':                             (16,),
    'PyUFunc_FF_F_As_DD_D':                     (17,),
    'PyUFunc_DD_D':                             (18,),
    'PyUFunc_FF_F':                             (19,),
    'PyUFunc_GG_G':                             (20,),
    'PyUFunc_OO_O':                             (21,),
    'PyUFunc_O_O_method':                       (22,),
    'PyUFunc_OO_O_method':                      (23,),
    'PyUFunc_On_Om':                            (24,),
    # 未使用的槽 25,原先是 `PyUFunc_GetPyValues`
    # 未使用的槽 26,原先是 `PyUFunc_checkfperr`
    'PyUFunc_clearfperr':                       (27,),
    'PyUFunc_getfperr':                         (28,),
    # 未使用的槽 29,原先是 `PyUFunc_handlefperr`
    'PyUFunc_ReplaceLoopBySignature':           (30,),
    'PyUFunc_FromFuncAndDataAndSignature':      (31,),
    # 未使用的槽 32,原先是 `PyUFunc_SetUsesArraysAsData`
    # 1.5 版本 API 结束
    'PyUFunc_e_e':                              (33,),
    'PyUFunc_e_e_As_f_f':                       (34,),
    'PyUFunc_e_e_As_d_d':                       (35,),
    'PyUFunc_ee_e':                             (36,),
    'PyUFunc_ee_e_As_ff_f':                     (37,),
    'PyUFunc_ee_e_As_dd_d':                     (38,),
    # 1.6 版本 API 结束
    'PyUFunc_DefaultTypeResolver':              (39,),
    'PyUFunc_ValidateCasting':                  (40,),
    # 1.7 版本 API 结束
    'PyUFunc_RegisterLoopForDescr':             (41,),
    # 1.8 版本 API 结束
    'PyUFunc_FromFuncAndDataAndSignatureAndIdentity': (42, MinVersion("1.16")),
    # 1.16 版本 API 结束
    'PyUFunc_AddLoopFromSpec':                       (43, MinVersion("2.0")),
    'PyUFunc_AddPromoter':                           (44, MinVersion("2.0")),
    'PyUFunc_AddWrappingLoop':                       (45, MinVersion("2.0")),
    'PyUFunc_GiveFloatingpointErrors':               (46, MinVersion("2.0")),
}

# 列出了定义 C API 的所有字典的列表
# XXX: 不要改变以下元组的顺序!
# 定义一个元组 `multiarray_api`,包含多维数组的全局变量、标量布尔值、类型 API、函数 API
multiarray_api = (
        multiarray_global_vars,   # 多维数组的全局变量
        multiarray_scalar_bool_values,  # 多维数组的标量布尔值
        multiarray_types_api,  # 多维数组的类型 API
        multiarray_funcs_api,  # 多维数组的函数 API
)

# 定义一个元组 `ufunc_api`,包含通用函数的函数 API、类型 API
ufunc_api = (
        ufunc_funcs_api,   # 通用函数的函数 API
        ufunc_types_api    # 通用函数的类型 API
)

# 将多维数组 API 和通用函数 API 合并成一个新的元组 `full_api`
full_api = multiarray_api + ufunc_api

.\numpy\numpy\_core\code_generators\ufunc_docstrings.py

"""
Docstrings for generated ufuncs

The syntax is designed to look like the function add_newdoc is being
called from numpy.lib, but in this file  add_newdoc puts the docstrings
in a dictionary. This dictionary is used in
numpy/_core/code_generators/generate_umath_doc.py to generate the docstrings
as a C #definitions for the ufuncs in numpy._core at the C level when the
ufuncs are created at compile time.

"""
import textwrap

# 创建一个空的字典,用于存储文档字符串
docdict = {}

# common parameter text to all ufuncs
# 定义参数的文本模板,供所有 ufuncs 共用
subst = {
    'PARAMS': textwrap.dedent("""
        out : ndarray, None, or tuple of ndarray and None, optional
            A location into which the result is stored. If provided, it must have
            a shape that the inputs broadcast to. If not provided or None,
            a freshly-allocated array is returned. A tuple (possible only as a
            keyword argument) must have length equal to the number of outputs.
        where : array_like, optional
            This condition is broadcast over the input. At locations where the
            condition is True, the `out` array will be set to the ufunc result.
            Elsewhere, the `out` array will retain its original value.
            Note that if an uninitialized `out` array is created via the default
            ``out=None``, locations within it where the condition is False will
            remain uninitialized.
        **kwargs
            For other keyword-only arguments, see the
            :ref:`ufunc docs <ufuncs.kwargs>`.
    """).strip(),
    'BROADCASTABLE_2': ("If ``x1.shape != x2.shape``, they must be "
                        "broadcastable to a common\n    shape (which becomes "
                        "the shape of the output)."),
    'OUT_SCALAR_1': "This is a scalar if `x` is a scalar.",
    'OUT_SCALAR_2': "This is a scalar if both `x1` and `x2` are scalars.",
}

# 定义一个函数,用于向 docdict 中添加新的文档字符串
def add_newdoc(place, name, doc):
    # 去除文档字符串的缩进并去除末尾空白
    doc = textwrap.dedent(doc).strip()

    # 定义需要跳过处理的 ufuncs 名称
    skip = (
        'matmul', 'vecdot',  # gufuncs do not use the OUT_SCALAR replacement strings
        'clip',  # clip has 3 inputs, which is not handled by this
    )
    
    # 如果名称不以下划线开头且不在跳过列表中
    if name[0] != '_' and name not in skip:
        # 检查文档字符串中是否包含特定的占位符,如果不包含则报错
        if '\nx :' in doc:
            assert '$OUT_SCALAR_1' in doc, "in {}".format(name)
        elif '\nx2 :' in doc or '\nx1, x2 :' in doc:
            assert '$OUT_SCALAR_2' in doc, "in {}".format(name)
        else:
            assert False, "Could not detect number of inputs in {}".format(name)

    # 替换文档字符串中的占位符
    for k, v in subst.items():
        doc = doc.replace('$' + k, v)

    # 将处理好的文档字符串存入 docdict 中,键为 place.name
    docdict['.'.join((place, name))] = doc


# 调用 add_newdoc 函数,向 docdict 中添加 'numpy._core.umath.absolute' 的文档字符串
add_newdoc('numpy._core.umath', 'absolute',
    """
    Calculate the absolute value element-wise.

    ``np.abs`` is a shorthand for this function.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    """
)
    absolute : ndarray
        An ndarray containing the absolute value of
        each element in `x`.  For complex input, ``a + ib``, the
        absolute value is :math:`\\sqrt{ a^2 + b^2 }`.
        $OUT_SCALAR_1

    Examples
    --------
    >>> x = np.array([-1.2, 1.2])
    >>> np.absolute(x)
    array([ 1.2,  1.2])
    >>> np.absolute(1.2 + 1j)
    1.5620499351813308

    Plot the function over ``[-10, 10]``:

    >>> import matplotlib.pyplot as plt

    >>> x = np.linspace(start=-10, stop=10, num=101)
    创建一个包含从 -1010101 个数的数组,用于 x 值
    >>> plt.plot(x, np.absolute(x))
    绘制函数在 x 范围内的绝对值图像
    >>> plt.show()

    Plot the function over the complex plane:

    >>> xx = x + 1j * x[:, np.newaxis]
    创建一个复数数组 xx,其中每个元素为 x + 1j * x 的形式
    >>> plt.imshow(np.abs(xx), extent=[-10, 10, -10, 10], cmap='gray')
    显示复平面上函数的绝对值图像
    >>> plt.show()

    The `abs` function can be used as a shorthand for ``np.absolute`` on
    ndarrays.

    >>> x = np.array([-1.2, 1.2])
    使用 `abs` 函数作为 `np.absolute` 的简写,应用于 ndarray
    >>> abs(x)
    array([1.2, 1.2])
# 向numpy._core.umath模块中添加新的文档字符串,描述函数`add`
add_newdoc('numpy._core.umath', 'add',
    """
    Add arguments element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        The arrays to be added.
        $BROADCASTABLE_2  # x1和x2可以广播
    $PARAMS  # 其它参数

    Returns
    -------
    add : ndarray or scalar
        The sum of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2  # 返回值可以是ndarray或标量

    Notes
    -----
    Equivalent to `x1` + `x2` in terms of array broadcasting.

    Examples
    --------
    >>> np.add(1.0, 4.0)
    5.0
    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = np.arange(3.0)
    >>> np.add(x1, x2)
    array([[  0.,   2.,   4.],
           [  3.,   5.,   7.],
           [  6.,   8.,  10.]])

    The ``+`` operator can be used as a shorthand for ``np.add`` on ndarrays.

    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = np.arange(3.0)
    >>> x1 + x2
    array([[ 0.,  2.,  4.],
           [ 3.,  5.,  7.],
           [ 6.,  8., 10.]])
    """)

# 向numpy._core.umath模块中添加新的文档字符串,描述函数`arccos`
add_newdoc('numpy._core.umath', 'arccos',
    """
    Trigonometric inverse cosine, element-wise.

    The inverse of `cos` so that, if ``y = cos(x)``, then ``x = arccos(y)``.

    Parameters
    ----------
    x : array_like
        `x`-coordinate on the unit circle.
        For real arguments, the domain is [-1, 1].
    $PARAMS  # 其它参数

    Returns
    -------
    angle : ndarray
        The angle of the ray intersecting the unit circle at the given
        `x`-coordinate in radians [0, pi].
        $OUT_SCALAR_1  # 返回角度,单位是弧度,范围在[0, pi]

    See Also
    --------
    cos, arctan, arcsin, emath.arccos

    Notes
    -----
    `arccos` is a multivalued function: for each `x` there are infinitely
    many numbers `z` such that ``cos(z) = x``. The convention is to return
    the angle `z` whose real part lies in `[0, pi]`.

    For real-valued input data types, `arccos` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arccos` is a complex analytic function that
    has branch cuts ``[-inf, -1]`` and `[1, inf]` and is continuous from
    above on the former and from below on the latter.

    The inverse `cos` is also known as `acos` or cos^-1.

    References
    ----------
    M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
    10th printing, 1964, pp. 79.
    https://personal.math.ubc.ca/~cbm/aands/page_79.htm

    Examples
    --------
    We expect the arccos of 1 to be 0, and of -1 to be pi:

    >>> np.arccos([1, -1])
    array([ 0.        ,  3.14159265])

    Plot arccos:

    >>> import matplotlib.pyplot as plt
    >>> x = np.linspace(-1, 1, num=100)
    >>> plt.plot(x, np.arccos(x))
    >>> plt.axis('tight')
    >>> plt.show()

    """)

# 向numpy._core.umath模块中添加新的文档字符串,描述函数`arccosh`
add_newdoc('numpy._core.umath', 'arccosh',
    """
    Inverse hyperbolic cosine, element-wise.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS  # 其它参数

    Returns
    -------
    angle : ndarray
        The inverse hyperbolic cosine of each element in `x`.

    """
)
    arccosh : ndarray
        Array of the same shape as `x`.
        $OUT_SCALAR_1

    See Also
    --------
    cosh, arcsinh, sinh, arctanh, tanh

    Notes
    -----
    `arccosh` is a multivalued function: for each `x` there are infinitely
    many numbers `z` such that `cosh(z) = x`. The convention is to return the
    `z` whose imaginary part lies in ``[-pi, pi]`` and the real part in
    ``[0, inf]``.

    For real-valued input data types, `arccosh` always returns real output.
    For each value that cannot be expressed as a real number or infinity, it
    yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arccosh` is a complex analytical function that
    has a branch cut `[-inf, 1]` and is continuous from above on it.

    References
    ----------
    .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
           10th printing, 1964, pp. 86.
           https://personal.math.ubc.ca/~cbm/aands/page_86.htm
    .. [2] Wikipedia, "Inverse hyperbolic function",
           https://en.wikipedia.org/wiki/Arccosh

    Examples
    --------
    >>> np.arccosh([np.e, 10.0])
    array([ 1.65745445,  2.99322285])
    >>> np.arccosh(1)
    0.0



    arccosh : ndarray
        返回与 `x` 相同形状的数组。
        $OUT_SCALAR_1

    See Also
    --------
    cosh, arcsinh, sinh, arctanh, tanh

    Notes
    -----
    `arccosh` 是一个多值函数:对于每个 `x` 存在无数个数 `z`,使得 `cosh(z) = x`。约定返回 `z`,其虚部位于 ``[-pi, pi]``,实部位于 ``[0, inf]``。

    对于实数输入类型,`arccosh` 总是返回实数输出。对于每个不能表达为实数或无穷大的值,它返回 ``nan`` 并设置 `invalid` 浮点错误标志。

    对于复数输入,`arccosh` 是一个复解析函数,具有分支切割 `[-inf, 1]`,在此处从上方连续。

    References
    ----------
    .. [1] M. Abramowitz 和 I.A. Stegun, "Handbook of Mathematical Functions",
           第10次印刷, 1964, pp. 86.
           https://personal.math.ubc.ca/~cbm/aands/page_86.htm
    .. [2] Wikipedia, "Inverse hyperbolic function",
           https://en.wikipedia.org/wiki/Arccosh

    Examples
    --------
    >>> np.arccosh([np.e, 10.0])
    array([ 1.65745445,  2.99322285])
    >>> np.arccosh(1)
    0.0
# 在 `numpy._core.umath` 模块中添加新的文档字符串,用于描述 `arcsin` 函数
add_newdoc('numpy._core.umath', 'arcsin',
    """
    Inverse sine, element-wise.

    Parameters
    ----------
    x : array_like
        `y`-coordinate on the unit circle.
    $PARAMS  # 参数说明,具体参数的描述将在实际文档中填充

    Returns
    -------
    angle : ndarray
        The inverse sine of each element in `x`, in radians and in the
        closed interval ``[-pi/2, pi/2]``.
        $OUT_SCALAR_1  # 返回值说明,具体返回值的描述将在实际文档中填充

    See Also
    --------
    sin, cos, arccos, tan, arctan, arctan2, emath.arcsin  # 相关函数链接,列出与本函数相关的其他函数

    Notes
    -----
    `arcsin` is a multivalued function: for each `x` there are infinitely
    many numbers `z` such that :math:`sin(z) = x`.  The convention is to
    return the angle `z` whose real part lies in [-pi/2, pi/2].

    For real-valued input data types, *arcsin* always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arcsin` is a complex analytic function that
    has, by convention, the branch cuts [-inf, -1] and [1, inf]  and is
    continuous from above on the former and from below on the latter.

    The inverse sine is also known as `asin` or sin^{-1}.

    References
    ----------
    Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*,
    10th printing, New York: Dover, 1964, pp. 79ff.
    https://personal.math.ubc.ca/~cbm/aands/page_79.htm

    Examples
    --------
    >>> np.arcsin(1)     # pi/2
    1.5707963267948966
    >>> np.arcsin(-1)    # -pi/2
    -1.5707963267948966
    >>> np.arcsin(0)
    0.0

    """)

# 在 `numpy._core.umath` 模块中添加新的文档字符串,用于描述 `arcsinh` 函数
add_newdoc('numpy._core.umath', 'arcsinh',
    """
    Inverse hyperbolic sine element-wise.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS  # 参数说明,具体参数的描述将在实际文档中填充

    Returns
    -------
    out : ndarray or scalar
        Array of the same shape as `x`.
        $OUT_SCALAR_1  # 返回值说明,具体返回值的描述将在实际文档中填充

    Notes
    -----
    `arcsinh` is a multivalued function: for each `x` there are infinitely
    many numbers `z` such that `sinh(z) = x`. The convention is to return the
    `z` whose imaginary part lies in `[-pi/2, pi/2]`.

    For real-valued input data types, `arcsinh` always returns real output.
    For each value that cannot be expressed as a real number or infinity, it
    returns ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arcsinh` is a complex analytical function that
    has branch cuts `[1j, infj]` and `[-1j, -infj]` and is continuous from
    the right on the former and from the left on the latter.

    The inverse hyperbolic sine is also known as `asinh` or ``sinh^-1``.

    References
    ----------
    .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
           10th printing, 1964, pp. 86.
           https://personal.math.ubc.ca/~cbm/aands/page_86.htm
    .. [2] Wikipedia, "Inverse hyperbolic function",
           https://en.wikipedia.org/wiki/Arcsinh

    Examples
    --------
    >>> np.arcsinh(np.array([np.e, 10.0]))

    """)
    array([ 1.72538256,  2.99822295])



# 创建一个包含两个元素的 NumPy 数组,元素分别为 1.72538256 和 2.99822295
add_newdoc('numpy._core.umath', 'arctan',
    """
    Trigonometric inverse tangent, element-wise.

    The inverse of tan, so that if ``y = tan(x)`` then ``x = arctan(y)``.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS  # Placeholder for additional parameter details

    Returns
    -------
    out : ndarray or scalar
        Array of angles in radians, in the range [-pi/2, pi/2].

    See Also
    --------
    arctan2 : Element-wise arctangent of x1/x2 with correct quadrant.
    angle : Argument of complex values.

    Notes
    -----
    `arctan` is a multi-valued function: for each `x` there are infinitely
    many numbers `z` such that tan(`z`) = `x`.  The convention is to return
    the angle `z` whose real part lies in [-pi/2, pi/2].

    For real-valued input data types, `arctan` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arctan` is a complex analytic function that
    has [``1j, infj``] and [``-1j, -infj``] as branch cuts, and is continuous
    from the left on the former and from the right on the latter.

    The inverse tangent is also known as `atan` or tan^{-1}.

    References
    ----------
    Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*,
    10th printing, New York: Dover, 1964, pp. 79.
    https://personal.math.ubc.ca/~cbm/aands/page_79.htm

    Examples
    --------
    We expect the arctan of 0 to be 0, and of 1 to be pi/4:

    >>> np.arctan([0, 1])
    array([ 0.        ,  0.78539816])

    >>> np.pi/4
    0.78539816339744828

    Plot arctan:

    >>> import matplotlib.pyplot as plt
    >>> x = np.linspace(-10, 10)
    >>> plt.plot(x, np.arctan(x))
    >>> plt.axis('tight')
    >>> plt.show()

    """
)

add_newdoc('numpy._core.umath', 'arctan2',
    """
    Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly.

    The quadrant (i.e., branch) is chosen so that ``arctan2(x1, x2)`` is
    the signed angle in radians between the ray ending at the origin and
    passing through the point (1,0), and the ray ending at the origin and
    passing through the point (`x2`, `x1`).  (Note the role reversal: the
    "`y`-coordinate" is the first function parameter, the "`x`-coordinate"
    is the second.)  By IEEE convention, this function is defined for
    `x2` = +/-0 and for either or both of `x1` and `x2` = +/-inf (see
    Notes for specific values).

    This function is not defined for complex-valued arguments; for the
    so-called argument of complex values, use `angle`.

    Parameters
    ----------
    x1 : array_like, real-valued
        `y`-coordinates.
    x2 : array_like, real-valued
        `x`-coordinates.
        $BROADCASTABLE_2  # Placeholder for broadcasting rules
    $PARAMS  # Placeholder for additional parameter details

    Returns
    -------
    out : ndarray
        Array of angles in radians, in the range [-pi, pi].

    """
)
    angle : ndarray
        Array of angles in radians, in the range ``[-pi, pi]``.
        $OUT_SCALAR_2

    See Also
    --------
    arctan, tan, angle

    Notes
    -----
    *arctan2* is identical to the `atan2` function of the underlying
    C library.  The following special values are defined in the C
    standard: [1]_

    ====== ====== ================
    `x1`   `x2`   `arctan2(x1,x2)`
    ====== ====== ================
    +/- 0  +0     +/- 0
    +/- 0  -0     +/- pi
     > 0   +/-inf +0 / +pi
     < 0   +/-inf -0 / -pi
    +/-inf +inf   +/- (pi/4)
    +/-inf -inf   +/- (3*pi/4)
    ====== ====== ================

    Note that +0 and -0 are distinct floating point numbers, as are +inf
    and -inf.

    References
    ----------
    .. [1] ISO/IEC standard 9899:1999, "Programming language C."

    Examples
    --------
    Consider four points in different quadrants:

    >>> x = np.array([-1, +1, +1, -1])
    >>> y = np.array([-1, -1, +1, +1])
    >>> np.arctan2(y, x) * 180 / np.pi
    array([-135.,  -45.,   45.,  135.])

    Note the order of the parameters. `arctan2` is defined also when `x2` = 0
    and at several other special points, obtaining values in
    the range ``[-pi, pi]``:

    >>> np.arctan2([1., -1.], [0., 0.])
    array([ 1.57079633, -1.57079633])
    >>> np.arctan2([0., 0., np.inf], [+0., -0., np.inf])
    array([0.        , 3.14159265, 0.78539816])

    """
# 向 numpy._core.umath 模块添加新的文档字符串
add_newdoc('numpy._core.umath', '_arg',
    """
    DO NOT USE, ONLY FOR TESTING
    """)

# 向 numpy._core.umath 模块添加 'arctanh' 函数的文档字符串
add_newdoc('numpy._core.umath', 'arctanh',
    """
    Inverse hyperbolic tangent element-wise.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Array of the same shape as `x`.
        $OUT_SCALAR_1

    See Also
    --------
    emath.arctanh

    Notes
    -----
    `arctanh` is a multivalued function: for each `x` there are infinitely
    many numbers `z` such that ``tanh(z) = x``. The convention is to return
    the `z` whose imaginary part lies in `[-pi/2, pi/2]`.

    For real-valued input data types, `arctanh` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `arctanh` is a complex analytical function
    that has branch cuts `[-1, -inf]` and `[1, inf]` and is continuous from
    above on the former and from below on the latter.

    The inverse hyperbolic tangent is also known as `atanh` or ``tanh^-1``.

    References
    ----------
    .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
           10th printing, 1964, pp. 86.
           https://personal.math.ubc.ca/~cbm/aands/page_86.htm
    .. [2] Wikipedia, "Inverse hyperbolic function",
           https://en.wikipedia.org/wiki/Arctanh

    Examples
    --------
    >>> np.arctanh([0, -0.5])
    array([ 0.        , -0.54930614])

    """)

# 向 numpy._core.umath 模块添加 'bitwise_and' 函数的文档字符串
add_newdoc('numpy._core.umath', 'bitwise_and',
    """
    Compute the bit-wise AND of two arrays element-wise.

    Computes the bit-wise AND of the underlying binary representation of
    the integers in the input arrays. This ufunc implements the C/Python
    operator ``&``.

    Parameters
    ----------
    x1, x2 : array_like
        Only integer and boolean types are handled.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Result.
        $OUT_SCALAR_2

    See Also
    --------
    logical_and
    bitwise_or
    bitwise_xor
    binary_repr :
        Return the binary representation of the input number as a string.

    Examples
    --------
    The number 13 is represented by ``00001101``.  Likewise, 17 is
    represented by ``00010001``.  The bit-wise AND of 13 and 17 is
    therefore ``000000001``, or 1:

    >>> np.bitwise_and(13, 17)
    1

    >>> np.bitwise_and(14, 13)
    12
    >>> np.binary_repr(12)
    '1100'
    >>> np.bitwise_and([14,3], 13)
    array([12,  1])

    >>> np.bitwise_and([11,7], [4,25])
    array([0, 1])
    >>> np.bitwise_and(np.array([2,5,255]), np.array([3,14,16]))
    array([ 2,  4, 16])
    >>> np.bitwise_and([True, True], [False, True])
    array([False,  True])

    The ``&`` operator can be used as a shorthand for ``np.bitwise_and`` on
    ndarrays.

    >>> x1 = np.array([2, 5, 255])
    # 创建一个 NumPy 数组 x2,包含元素 [3, 14, 16]
    x2 = np.array([3, 14, 16])
    # 对数组 x1 和 x2 进行按位与操作,返回一个新的 NumPy 数组
    # 按位与操作会对数组中对应位置的元素进行按位与运算
    # 结果数组中的每个元素都是 x1 和 x2 对应位置元素按位与的结果
    x1 & x2
    # 返回结果为一个 NumPy 数组 [2, 4, 16]
    array([ 2,  4, 16])
# 添加新的文档字符串到指定模块和函数名的文档中
add_newdoc('numpy._core.umath', 'bitwise_or',
    """
    Compute the bit-wise OR of two arrays element-wise.

    Computes the bit-wise OR of the underlying binary representation of
    the integers in the input arrays. This ufunc implements the C/Python
    operator ``|``.

    Parameters
    ----------
    x1, x2 : array_like
        Only integer and boolean types are handled.
        $BROADCASTABLE_2  # 指代两个数组可以进行广播操作
    $PARAMS  # 其他参数文档中定义的未指定参数

    Returns
    -------
    out : ndarray or scalar
        Result.
        $OUT_SCALAR_2  # 指代返回值可以是数组或标量

    See Also
    --------
    logical_or  # 相关函数:逻辑或
    bitwise_and  # 相关函数:按位与
    bitwise_xor  # 相关函数:按位异或
    binary_repr :  # 相关函数:返回输入数字的二进制表示作为字符串

    Examples
    --------
    The number 13 has the binary representation ``00001101``. Likewise,
    16 is represented by ``00010000``.  The bit-wise OR of 13 and 16 is
    then ``00011101``, or 29:

    >>> np.bitwise_or(13, 16)
    29
    >>> np.binary_repr(29)
    '11101'

    >>> np.bitwise_or(32, 2)
    34
    >>> np.bitwise_or([33, 4], 1)
    array([33,  5])
    >>> np.bitwise_or([33, 4], [1, 2])
    array([33,  6])

    >>> np.bitwise_or(np.array([2, 5, 255]), np.array([4, 4, 4]))
    array([  6,   5, 255])
    >>> np.array([2, 5, 255]) | np.array([4, 4, 4])
    array([  6,   5, 255])
    >>> np.bitwise_or(np.array([2, 5, 255, 2147483647], dtype=np.int32),
    ...               np.array([4, 4, 4, 2147483647], dtype=np.int32))
    array([         6,          5,        255, 2147483647])
    >>> np.bitwise_or([True, True], [False, True])
    array([ True,  True])

    The ``|`` operator can be used as a shorthand for ``np.bitwise_or`` on
    ndarrays.

    >>> x1 = np.array([2, 5, 255])
    >>> x2 = np.array([4, 4, 4])
    >>> x1 | x2
    array([  6,   5, 255])

    """)

# 添加新的文档字符串到指定模块和函数名的文档中
add_newdoc('numpy._core.umath', 'bitwise_xor',
    """
    Compute the bit-wise XOR of two arrays element-wise.

    Computes the bit-wise XOR of the underlying binary representation of
    the integers in the input arrays. This ufunc implements the C/Python
    operator ``^``.

    Parameters
    ----------
    x1, x2 : array_like
        Only integer and boolean types are handled.
        $BROADCASTABLE_2  # 指代两个数组可以进行广播操作
    $PARAMS  # 其他参数文档中定义的未指定参数

    Returns
    -------
    out : ndarray or scalar
        Result.
        $OUT_SCALAR_2  # 指代返回值可以是数组或标量

    See Also
    --------
    logical_xor  # 相关函数:逻辑异或
    bitwise_and  # 相关函数:按位与
    bitwise_or  # 相关函数:按位或
    binary_repr :  # 相关函数:返回输入数字的二进制表示作为字符串

    Examples
    --------
    The number 13 is represented by ``00001101``. Likewise, 17 is
    represented by ``00010001``.  The bit-wise XOR of 13 and 17 is
    therefore ``00011100``, or 28:

    >>> np.bitwise_xor(13, 17)
    28
    >>> np.binary_repr(28)
    '11100'

    >>> np.bitwise_xor(31, 5)
    26
    >>> np.bitwise_xor([31,3], 5)
    array([26,  6])

    >>> np.bitwise_xor([31,3], [5,6])
    array([26,  5])
    >>> np.bitwise_xor([True, True], [False, True])
    array([ True, False])

    """
    The ``^`` operator can be used as a shorthand for ``np.bitwise_xor`` on
    ndarrays.

    >>> x1 = np.array([True, True])   # 创建一个包含布尔值的 NumPy 数组 x1
    >>> x2 = np.array([False, True])  # 创建另一个包含布尔值的 NumPy 数组 x2
    >>> x1 ^ x2                       # 对数组 x1 和 x2 执行按位异或操作
    array([ True, False])            # 返回按位异或操作后的结果数组,[True, False]
# 添加新的文档字符串到 'numpy._core.umath' 的 'ceil' 函数,描述其功能和用法
add_newdoc('numpy._core.umath', 'ceil',
    """
    Return the ceiling of the input, element-wise.

    The ceil of the scalar `x` is the smallest integer `i`, such that
    ``i >= x``.  It is often denoted as :math:`\\lceil x \\rceil`.

    Parameters
    ----------
    x : array_like
        Input data.
    $PARAMS

    Returns
    -------
    y : ndarray or scalar
        The ceiling of each element in `x`, with `float` dtype.
        $OUT_SCALAR_1

    See Also
    --------
    floor, trunc, rint, fix

    Examples
    --------
    >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
    >>> np.ceil(a)
    array([-1., -1., -0.,  1.,  2.,  2.,  2.])

    """)

# 添加新的文档字符串到 'numpy._core.umath' 的 'trunc' 函数,描述其功能和用法
add_newdoc('numpy._core.umath', 'trunc',
    """
    Return the truncated value of the input, element-wise.

    The truncated value of the scalar `x` is the nearest integer `i` which
    is closer to zero than `x` is. In short, the fractional part of the
    signed number `x` is discarded.

    Parameters
    ----------
    x : array_like
        Input data.
    $PARAMS

    Returns
    -------
    y : ndarray or scalar
        The truncated value of each element in `x`.
        $OUT_SCALAR_1

    See Also
    --------
    ceil, floor, rint, fix

    Notes
    -----
    .. versionadded:: 1.3.0

    Examples
    --------
    >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
    >>> np.trunc(a)
    array([-1., -1., -0.,  0.,  1.,  1.,  2.])

    """)

# 添加新的文档字符串到 'numpy._core.umath' 的 'conjugate' 函数,描述其功能和用法
add_newdoc('numpy._core.umath', 'conjugate',
    """
    Return the complex conjugate, element-wise.

    The complex conjugate of a complex number is obtained by changing the
    sign of its imaginary part.

    Parameters
    ----------
    x : array_like
        Input value.
    $PARAMS

    Returns
    -------
    y : ndarray
        The complex conjugate of `x`, with same dtype as `y`.
        $OUT_SCALAR_1

    Notes
    -----
    `conj` is an alias for `conjugate`:

    >>> np.conj is np.conjugate
    True

    Examples
    --------
    >>> np.conjugate(1+2j)
    (1-2j)

    >>> x = np.eye(2) + 1j * np.eye(2)
    >>> np.conjugate(x)
    array([[ 1.-1.j,  0.-0.j],
           [ 0.-0.j,  1.-1.j]])

    """)

# 添加新的文档字符串到 'numpy._core.umath' 的 'cos' 函数,描述其功能和用法
add_newdoc('numpy._core.umath', 'cos',
    """
    Cosine element-wise.

    Parameters
    ----------
    x : array_like
        Input array in radians.
    $PARAMS

    Returns
    -------
    y : ndarray
        The corresponding cosine values.
        $OUT_SCALAR_1

    Notes
    -----
    If `out` is provided, the function writes the result into it,
    and returns a reference to `out`.  (See Examples)

    References
    ----------
    M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions.
    New York, NY: Dover, 1972.

    Examples
    --------
    >>> np.cos(np.array([0, np.pi/2, np.pi]))
    array([  1.00000000e+00,   6.12303177e-17,  -1.00000000e+00])
    >>>
    >>> # Example of providing the optional output parameter
    >>> out1 = np.array([0], dtype='d')
    >>> out2 = np.cos([0.1], out1)

    """)
    >>> out2 is out1
    True
    >>>
    >>> # 检查 out2 是否与 out1 是同一个对象的示例
    >>> # 这里返回 True 表示 out2 和 out1 是同一个对象

    >>> # Example of ValueError due to provision of shape mis-matched `out`
    >>> # 由于提供形状不匹配的 `out` 参数,导致 ValueError 的示例
    >>> # 在这个例子中,np.cos 函数尝试使用两个不同形状的数组进行计算,引发异常
    >>> np.cos(np.zeros((3,3)),np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: operands could not be broadcast together with shapes (3,3) (2,2)
# 向 numpy._core.umath 模块添加新的文档字符串和函数定义
add_newdoc('numpy._core.umath', 'cosh',
    """
    Hyperbolic cosine, element-wise.

    Equivalent to ``1/2 * (np.exp(x) + np.exp(-x))`` and ``np.cos(1j*x)``.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Output array of same shape as `x`.
        $OUT_SCALAR_1

    Examples
    --------
    >>> np.cosh(0)
    1.0

    The hyperbolic cosine describes the shape of a hanging cable:

    >>> import matplotlib.pyplot as plt
    >>> x = np.linspace(-4, 4, 1000)
    >>> plt.plot(x, np.cosh(x))
    >>> plt.show()

    """)

# 向 numpy._core.umath 模块添加新的文档字符串和函数定义
add_newdoc('numpy._core.umath', 'degrees',
    """
    Convert angles from radians to degrees.

    Parameters
    ----------
    x : array_like
        Input array in radians.
    $PARAMS

    Returns
    -------
    y : ndarray of floats
        The corresponding degree values; if `out` was supplied this is a
        reference to it.
        $OUT_SCALAR_1

    See Also
    --------
    rad2deg : equivalent function

    Examples
    --------
    Convert a radian array to degrees

    >>> rad = np.arange(12.)*np.pi/6
    >>> np.degrees(rad)
    array([   0.,   30.,   60.,   90.,  120.,  150.,  180.,  210.,  240.,
            270.,  300.,  330.])

    >>> out = np.zeros((rad.shape))
    >>> r = np.degrees(rad, out)
    >>> np.all(r == out)
    True

    """)

# 向 numpy._core.umath 模块添加新的文档字符串和函数定义
add_newdoc('numpy._core.umath', 'rad2deg',
    """
    Convert angles from radians to degrees.

    Parameters
    ----------
    x : array_like
        Angle in radians.
    $PARAMS

    Returns
    -------
    y : ndarray
        The corresponding angle in degrees.
        $OUT_SCALAR_1

    See Also
    --------
    deg2rad : Convert angles from degrees to radians.
    unwrap : Remove large jumps in angle by wrapping.

    Notes
    -----
    .. versionadded:: 1.3.0

    rad2deg(x) is ``180 * x / pi``.

    Examples
    --------
    >>> np.rad2deg(np.pi/2)
    90.0

    """)

# 向 numpy._core.umath 模块添加新的文档字符串和函数定义
add_newdoc('numpy._core.umath', 'heaviside',
    """
    Compute the Heaviside step function.

    The Heaviside step function [1]_ is defined as::

                              0   if x1 < 0
        heaviside(x1, x2) =  x2   if x1 == 0
                              1   if x1 > 0

    where `x2` is often taken to be 0.5, but 0 and 1 are also sometimes used.

    Parameters
    ----------
    x1 : array_like
        Input values.
    x2 : array_like
        The value of the function when x1 is 0.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        The output array, element-wise Heaviside step function of `x1`.
        $OUT_SCALAR_2

    Notes
    -----
    .. versionadded:: 1.13.0

    References
    ----------
    .. [1] Wikipedia, "Heaviside step function",
           https://en.wikipedia.org/wiki/Heaviside_step_function

    Examples
    --------
    >>> np.heaviside([-1.5, 0, 2.0], 0.5)
    array([ 0. ,  0.5,  1. ])
    >>> np.heaviside([-1.5, 0, 2.0], 1)

    """)
    array([ 0.,  1.,  1.])
    """



    # 创建一个包含三个浮点数的NumPy数组,并没有对其进行赋值或命名
    array([ 0.,  1.,  1.])
    # 这是一个多行字符串的结束标记,用三个双引号包围
    """
# 添加新的文档字符串到numpy._core.umath模块,定义了divide函数的文档信息
add_newdoc('numpy._core.umath', 'divide',
    """
    Divide arguments element-wise.

    Parameters
    ----------
    x1 : array_like
        Dividend array.
    x2 : array_like
        Divisor array.
        $BROADCASTABLE_2  # 标记此处支持数组广播
    $PARAMS  # 描述参数信息

    Returns
    -------
    y : ndarray or scalar
        The quotient ``x1/x2``, element-wise.
        $OUT_SCALAR_2  # 标记输出标量类型

    See Also
    --------
    seterr : Set whether to raise or warn on overflow, underflow and
             division by zero.

    Notes
    -----
    Equivalent to ``x1`` / ``x2`` in terms of array-broadcasting.

    The ``true_divide(x1, x2)`` function is an alias for
    ``divide(x1, x2)``.

    Examples
    --------
    >>> np.divide(2.0, 4.0)
    0.5
    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = np.arange(3.0)
    >>> np.divide(x1, x2)
    array([[nan, 1. , 1. ],
           [inf, 4. , 2.5],
           [inf, 7. , 4. ]])

    The ``/`` operator can be used as a shorthand for ``np.divide`` on
    ndarrays.

    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = 2 * np.ones(3)
    >>> x1 / x2
    array([[0. , 0.5, 1. ],
           [1.5, 2. , 2.5],
           [3. , 3.5, 4. ]])

    """)

# 添加新的文档字符串到numpy._core.umath模块,定义了equal函数的文档信息
add_newdoc('numpy._core.umath', 'equal',
    """
    Return (x1 == x2) element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays.
        $BROADCASTABLE_2  # 标记此处支持数组广播
    $PARAMS  # 描述参数信息

    Returns
    -------
    out : ndarray or scalar
        Output array, element-wise comparison of `x1` and `x2`.
        Typically of type bool, unless ``dtype=object`` is passed.
        $OUT_SCALAR_2  # 标记输出标量类型

    See Also
    --------
    not_equal, greater_equal, less_equal, greater, less

    Examples
    --------
    >>> np.equal([0, 1, 3], np.arange(3))
    array([ True,  True, False])

    What is compared are values, not types. So an int (1) and an array of
    length one can evaluate as True:

    >>> np.equal(1, np.ones(1))
    array([ True])

    The ``==`` operator can be used as a shorthand for ``np.equal`` on
    ndarrays.

    >>> a = np.array([2, 4, 6])
    >>> b = np.array([2, 4, 2])
    >>> a == b
    array([ True,  True, False])

    """)

# 添加新的文档字符串到numpy._core.umath模块,定义了exp函数的文档信息
add_newdoc('numpy._core.umath', 'exp',
    """
    Calculate the exponential of all elements in the input array.

    Parameters
    ----------
    x : array_like
        Input values.
    $PARAMS  # 描述参数信息

    Returns
    -------
    out : ndarray or scalar
        Output array, element-wise exponential of `x`.
        $OUT_SCALAR_1  # 标记输出标量类型

    See Also
    --------
    expm1 : Calculate ``exp(x) - 1`` for all elements in the array.
    exp2  : Calculate ``2**x`` for all elements in the array.

    Notes
    -----
    The irrational number ``e`` is also known as Euler's number.  It is
    approximately 2.718281, and is the base of the natural logarithm,
    ``ln`` (this means that, if :math:`x = \\ln y = \\log_e y`,
    then :math:`e^x = y`. For real input, ``exp(x)`` is always positive.

    For complex arguments, ``x = a + ib``, we can write

    """)
    # Plot the magnitude and phase of ``exp(x)`` in the complex plane:
    >>> import matplotlib.pyplot as plt
    
    # Create a linearly spaced array of values from -2π to 2π with 100 points
    >>> x = np.linspace(-2*np.pi, 2*np.pi, 100)
    # Create a complex grid xx where each point is represented as a + ib
    >>> xx = x + 1j * x[:, np.newaxis]
    
    # Compute the exponential of each complex value in xx
    >>> out = np.exp(xx)
    
    # Create a subplot with 1 row and 2 columns, first subplot
    >>> plt.subplot(121)
    # Display the magnitude (absolute value) of out as an image plot
    >>> plt.imshow(np.abs(out),
    ...            extent=[-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi], cmap='gray')
    # Set the title of the subplot
    >>> plt.title('Magnitude of exp(x)')
    
    # Create a subplot with 1 row and 2 columns, second subplot
    >>> plt.subplot(122)
    # Display the phase (angle) of out as an image plot
    >>> plt.imshow(np.angle(out),
    ...            extent=[-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi], cmap='hsv')
    # Set the title of the subplot
    >>> plt.title('Phase (angle) of exp(x)')
    # Display the plot
    >>> plt.show()
# 将函数 `add_newdoc` 用于模块 `numpy._core.umath`,添加新的文档字符串定义
add_newdoc('numpy._core.umath', 'exp2',
    """
    计算输入数组中所有元素 `p` 的 `2**p`。

    Parameters
    ----------
    x : array_like
        输入值数组.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        每个元素对应的 2 的幂 `x`.
        $OUT_SCALAR_1

    See Also
    --------
    power

    Notes
    -----
    .. versionadded:: 1.3.0

    Examples
    --------
    >>> np.exp2([2, 3])
    array([ 4.,  8.])

    """)

# 将函数 `add_newdoc` 用于模块 `numpy._core.umath`,添加新的文档字符串定义
add_newdoc('numpy._core.umath', 'expm1',
    """
    计算数组中所有元素的 `exp(x) - 1`。

    Parameters
    ----------
    x : array_like
        输入值数组.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        每个元素对应的指数减一: ``out = exp(x) - 1``.
        $OUT_SCALAR_1

    See Also
    --------
    log1p : ``log(1 + x)``, expm1 的逆操作.

    Notes
    -----
    对于小的 `x` 值,此函数提供比 ``exp(x) - 1`` 更高的精度。

    Examples
    --------
    对于 ``exp(1e-10) - 1`` 的真实值是 ``1.00000000005e-10``,有约 32 位有效数字。此示例展示了 expm1 在这种情况下的优越性。

    >>> np.expm1(1e-10)
    1.00000000005e-10
    >>> np.exp(1e-10) - 1
    1.000000082740371e-10

    """)

# 将函数 `add_newdoc` 用于模块 `numpy._core.umath`,添加新的文档字符串定义
add_newdoc('numpy._core.umath', 'fabs',
    """
    计算数组元素的绝对值。

    此函数返回 `x` 中数据的绝对值(正数)。复数值不受支持,使用 `absolute` 来获取复数数据的绝对值。

    Parameters
    ----------
    x : array_like
        需要计算绝对值的数值数组。如果 `x` 是标量,则返回的 `y` 也是标量.
    $PARAMS

    Returns
    -------
    y : ndarray or scalar
        `x` 的绝对值,返回值始终是浮点数.
        $OUT_SCALAR_1

    See Also
    --------
    absolute : 包括 `complex` 类型在内的绝对值计算.

    Examples
    --------
    >>> np.fabs(-1)
    1.0
    >>> np.fabs([-1.2, 1.2])
    array([ 1.2,  1.2])

    """)

# 将函数 `add_newdoc` 用于模块 `numpy._core.umath`,添加新的文档字符串定义
add_newdoc('numpy._core.umath', 'floor',
    """
    返回输入数据的向下取整结果,逐元素操作。

    标量 `x` 的向下取整是最大整数 `i`,使得 `i <= x`。通常表示为 :math:`\\lfloor x \\rfloor`。

    Parameters
    ----------
    x : array_like
        输入数据.
    $PARAMS

    Returns
    -------
    y : ndarray or scalar
        `x` 中每个元素的向下取整结果.
        $OUT_SCALAR_1

    See Also
    --------
    ceil, trunc, rint, fix

    Notes
    -----
    一些电子表格程序计算的是 "向零取整",即 ``floor(-2.5) == -2``。而 NumPy 使用的是 `floor` 的定义,其中 ``floor(-2.5) == -3``。向零取整函数在 NumPy 中称为 ``fix``。

    Examples
    --------
    >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
    >>> np.floor(a)

    """)
    array([-2., -2., -1.,  0.,  1.,  1.,  2.])



# 创建一个包含浮点数的 NumPy 数组,数组元素依次为 -2.0, -2.0, -1.0, 0.0, 1.0, 1.0, 2.0
# 添加新的文档字符串给 numpy._core.umath 模块的 floor_divide 函数
add_newdoc('numpy._core.umath', 'floor_divide',
    """
    返回输入的除法结果向下取整的最大整数。
    它等同于 Python 中的 ``//`` 运算符,配对使用 Python 的 ``%`` (`remainder`) 函数,
    使得 ``a = a % b + b * (a // b)`` 直至舍入误差。

    Parameters
    ----------
    x1 : array_like
        分子。
    x2 : array_like
        分母。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray
        y = floor(`x1`/`x2`)
        $OUT_SCALAR_2

    See Also
    --------
    remainder : floor_divide 的余数补充。
    divmod : 同时执行整除和取余数。
    divide : 标准除法。
    floor : 向负无穷大取最近的整数。
    ceil : 向正无穷大取最近的整数。

    Examples
    --------
    >>> np.floor_divide(7,3)
    2
    >>> np.floor_divide([1., 2., 3., 4.], 2.5)
    array([ 0.,  0.,  1.,  1.])

    在 ndarrays 上,``//`` 运算符可以作为 ``np.floor_divide`` 的简写。

    >>> x1 = np.array([1., 2., 3., 4.])
    >>> x1 // 2.5
    array([0., 0., 1., 1.])

    """)

# 添加新的文档字符串给 numpy._core.umath 模块的 fmod 函数
add_newdoc('numpy._core.umath', 'fmod',
    """
    返回元素级别的除法余数。

    这是 C 库函数 fmod 在 NumPy 中的实现,余数与被除数 `x1` 的符号相同。
    它等同于 Matlab(TM) 中的 ``rem`` 函数,不应与 Python 模数运算符 ``x1 % x2`` 混淆。

    Parameters
    ----------
    x1 : array_like
        被除数。
    x2 : array_like
        除数。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : array_like
        `x1` 除以 `x2` 的余数。
        $OUT_SCALAR_2

    See Also
    --------
    remainder : 等同于 Python ``%`` 运算符。
    divide

    Notes
    -----
    负被除数和除数的模数运算结果受约定约束。对于 `fmod`,结果的符号与被除数相同,
    而对于 `remainder`,结果的符号与除数相同。`fmod` 函数等同于 Matlab(TM) 的 ``rem`` 函数。

    Examples
    --------
    >>> np.fmod([-3, -2, -1, 1, 2, 3], 2)
    array([-1,  0, -1,  1,  0,  1])
    >>> np.remainder([-3, -2, -1, 1, 2, 3], 2)
    array([1, 0, 1, 1, 0, 1])

    >>> np.fmod([5, 3], [2, 2.])
    array([ 1.,  1.])
    >>> a = np.arange(-3, 3).reshape(3, 2)
    >>> a
    array([[-3, -2],
           [-1,  0],
           [ 1,  2]])
    >>> np.fmod(a, [2,2])
    array([[-1,  0],
           [-1,  0],
           [ 1,  0]])

    """)

# 添加新的文档字符串给 numpy._core.umath 模块的 greater 函数
add_newdoc('numpy._core.umath', 'greater',
    """
    返回元素级别的 (x1 > x2) 的真值。

    Parameters
    ----------
    x1, x2 : array_like
        输入数组。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        # 定义函数输出,可以是一个数组或标量
        Output array, element-wise comparison of `x1` and `x2`.
        # 输出数组,对 `x1` 和 `x2` 进行逐元素比较
        Typically of type bool, unless ``dtype=object`` is passed.
        # 通常为布尔类型,除非传入 ``dtype=object`` 参数
        $OUT_SCALAR_2
        # 这里的 $OUT_SCALAR_2 是一个占位符,通常用于在文档中引用相关变量或标量


    See Also
    --------
    greater_equal, less, less_equal, equal, not_equal
    # 参见的其他函数,用于比较操作:greater_equal, less, less_equal, equal, not_equal

    Examples
    --------
    >>> np.greater([4,2],[2,2])
    array([ True, False])
    # 示例:使用 np.greater 对数组 [4, 2] 和 [2, 2] 进行比较,得到数组 [ True, False]

    The ``>`` operator can be used as a shorthand for ``np.greater`` on
    ndarrays.
    # ``>`` 运算符可以作为 np.greater 在 ndarray 上的简写形式使用
    >>> a = np.array([4, 2])
    >>> b = np.array([2, 2])
    >>> a > b
    array([ True, False])
    # 示例:使用 ``>`` 运算符对数组 a 和 b 进行比较,得到数组 [ True, False]

    """
    # 文档字符串结束
# 添加新的文档字符串到 numpy._core.umath 模块下的 greater_equal 函数
add_newdoc('numpy._core.umath', 'greater_equal',
    """
    Return the truth value of (x1 >= x2) element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : bool or ndarray of bool
        Output array, element-wise comparison of `x1` and `x2`.
        Typically of type bool, unless ``dtype=object`` is passed.
        $OUT_SCALAR_2

    See Also
    --------
    greater, less, less_equal, equal, not_equal

    Examples
    --------
    >>> np.greater_equal([4, 2, 1], [2, 2, 2])
    array([ True, True, False])

    The ``>=`` operator can be used as a shorthand for ``np.greater_equal``
    on ndarrays.

    >>> a = np.array([4, 2, 1])
    >>> b = np.array([2, 2, 2])
    >>> a >= b
    array([ True,  True, False])

    """)

# 添加新的文档字符串到 numpy._core.umath 模块下的 hypot 函数
add_newdoc('numpy._core.umath', 'hypot',
    """
    Given the "legs" of a right triangle, return its hypotenuse.

    Equivalent to ``sqrt(x1**2 + x2**2)``, element-wise.  If `x1` or
    `x2` is scalar_like (i.e., unambiguously cast-able to a scalar type),
    it is broadcast for use with each element of the other argument.
    (See Examples)

    Parameters
    ----------
    x1, x2 : array_like
        Leg of the triangle(s).
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    z : ndarray
        The hypotenuse of the triangle(s).
        $OUT_SCALAR_2

    Examples
    --------
    >>> np.hypot(3*np.ones((3, 3)), 4*np.ones((3, 3)))
    array([[ 5.,  5.,  5.],
           [ 5.,  5.,  5.],
           [ 5.,  5.,  5.]])

    Example showing broadcast of scalar_like argument:

    >>> np.hypot(3*np.ones((3, 3)), [4])
    array([[ 5.,  5.,  5.],
           [ 5.,  5.,  5.],
           [ 5.,  5.,  5.]])

    """)

# 添加新的文档字符串到 numpy._core.umath 模块下的 invert 函数
add_newdoc('numpy._core.umath', 'invert',
    """
    Compute bit-wise inversion, or bit-wise NOT, element-wise.

    Computes the bit-wise NOT of the underlying binary representation of
    the integers in the input arrays. This ufunc implements the C/Python
    operator ``~``.

    For signed integer inputs, the bit-wise NOT of the absolute value is
    returned. In a two's-complement system, this operation effectively flips
    all the bits, resulting in a representation that corresponds to the
    negative of the input plus one. This is the most common method of
    representing signed integers on computers [1]_. A N-bit two's-complement
    system can represent every integer in the range :math:`-2^{N-1}` to
    :math:`+2^{N-1}-1`.

    Parameters
    ----------
    x : array_like
        Only integer and boolean types are handled.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Result.
        $OUT_SCALAR_1

    See Also
    --------
    bitwise_and, bitwise_or, bitwise_xor
    logical_not
    binary_repr :
        Return the binary representation of the input number as a string.

    Notes
    -----
    ``numpy.bitwise_not`` is an alias for `invert`:
    """)
    # np.bitwise_not 是 np.invert 的别名,它们在功能上是等价的
    True
    
    References
    ----------
    .. [1] Wikipedia, "Two's complement",
        https://en.wikipedia.org/wiki/Two's_complement
    
    Examples
    --------
    We've seen that 13 is represented by ``00001101``.
    The invert or bit-wise NOT of 13 is then:
    
    # 使用 np.invert 函数对一个无符号 8 位整数(uint8)的数值 13 进行位取反操作
    >>> x = np.invert(np.array(13, dtype=np.uint8))
    # 输出取反后的结果
    >>> x
    242
    # 将结果以 8 位二进制形式显示
    >>> np.binary_repr(x, width=8)
    '11110010'
    
    The result depends on the bit-width:
    
    # 使用 np.invert 函数对一个无符号 16 位整数(uint16)的数值 13 进行位取反操作
    >>> x = np.invert(np.array(13, dtype=np.uint16))
    # 输出取反后的结果
    >>> x
    65522
    # 将结果以 16 位二进制形式显示
    >>> np.binary_repr(x, width=16)
    '1111111111110010'
    
    When using signed integer types, the result is the bit-wise NOT of
    the unsigned type, interpreted as a signed integer:
    
    # 使用有符号 8 位整数(int8)类型进行位取反操作
    >>> np.invert(np.array([13], dtype=np.int8))
    array([-14], dtype=int8)
    # 将结果 -14 以 8 位二进制形式显示
    >>> np.binary_repr(-14, width=8)
    
    Booleans are accepted as well:
    
    # 对布尔数组进行位取反操作
    >>> np.invert(np.array([True, False]))
    array([False,  True])
    
    The ``~`` operator can be used as a shorthand for ``np.invert`` on
    ndarrays.
    
    # ``~`` 操作符可以用作 ``np.invert`` 在 ndarray 上的简写
    >>> x1 = np.array([True, False])
    >>> ~x1
    array([False,  True])
# 添加新文档到 numpy._core.umath 模块,函数名为 'isfinite'
# 检测逐元素是否有限(既不是正无穷大也不是 NaN)
"""
Test element-wise for finiteness (not infinity and not Not a Number).

The result is returned as a boolean array.

Parameters
----------
x : array_like
    Input values.
$PARAMS

Returns
-------
y : ndarray, bool
    True where ``x`` is not positive infinity, negative infinity,
    or NaN; false otherwise.
    $OUT_SCALAR_1

See Also
--------
isinf, isneginf, isposinf, isnan

Notes
-----
Not a Number, positive infinity, and negative infinity are considered
to be non-finite.

NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
(IEEE 754). This means that Not a Number is not equivalent to infinity.
Also that positive infinity is not equivalent to negative infinity. But
infinity is equivalent to positive infinity.  Errors result if the
second argument is also supplied when `x` is a scalar input, or if
first and second arguments have different shapes.

Examples
--------
>>> np.isfinite(1)
True
>>> np.isfinite(0)
True
>>> np.isfinite(np.nan)
False
>>> np.isfinite(np.inf)
False
>>> np.isfinite(-np.inf)
False
>>> np.isfinite([np.log(-1.),1.,np.log(0)])
array([False,  True, False])

>>> x = np.array([-np.inf, 0., np.inf])
>>> y = np.array([2, 2, 2])
>>> np.isfinite(x, y)
array([0, 1, 0])
>>> y
array([0, 1, 0])
"""

# 添加新文档到 numpy._core.umath 模块,函数名为 'isinf'
# 检测逐元素是否为正无穷大或负无穷大
"""
Test element-wise for positive or negative infinity.

Returns a boolean array of the same shape as `x`, True where ``x ==
+/-inf``, otherwise False.

Parameters
----------
x : array_like
    Input values
$PARAMS

Returns
-------
y : bool (scalar) or boolean ndarray
    True where ``x`` is positive or negative infinity, false otherwise.
    $OUT_SCALAR_1

See Also
--------
isneginf, isposinf, isnan, isfinite

Notes
-----
NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
(IEEE 754).

Errors result if the second argument is supplied when the first
argument is a scalar, or if the first and second arguments have
different shapes.

Examples
--------
>>> np.isinf(np.inf)
True
>>> np.isinf(np.nan)
False
>>> np.isinf(-np.inf)
True
>>> np.isinf([np.inf, -np.inf, 1.0, np.nan])
array([ True,  True, False, False])

>>> x = np.array([-np.inf, 0., np.inf])
>>> y = np.array([2, 2, 2])
>>> np.isinf(x, y)
array([1, 0, 1])
>>> y
array([1, 0, 1])
"""

# 添加新文档到 numpy._core.umath 模块,函数名为 'isnan'
# 检测逐元素是否为 NaN,返回结果为布尔数组
"""
Test element-wise for NaN and return result as a boolean array.

Parameters
----------
x : array_like
    Input array.
$PARAMS

Returns
-------
y : ndarray or bool
    True where ``x`` is NaN, false otherwise.
    $OUT_SCALAR_1

See Also
    --------
    isinf, isneginf, isposinf, isfinite, isnat

    Notes
    -----
    NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
    (IEEE 754). This means that Not a Number is not equivalent to infinity.

    Examples
    --------
    >>> np.isnan(np.nan)
    True                        # 检查 np.nan 是否为 NaN (Not a Number),返回 True
    >>> np.isnan(np.inf)
    False                       # 检查 np.inf 是否为 NaN,返回 False
    >>> np.isnan([np.log(-1.),1.,np.log(0)])
    array([ True, False, False])  # 检查数组中每个元素是否为 NaN,返回布尔数组

    """
# 将新文档添加到numpy._core.umath模块,函数名为'isnat'
add_newdoc('numpy._core.umath', 'isnat',
    """
    Test element-wise for NaT (not a time) and return result as a boolean array.

    .. versionadded:: 1.13.0

    Parameters
    ----------
    x : array_like
        Input array with datetime or timedelta data type.
    $PARAMS  # 参数的详细说明将在实际文档中替换

    Returns
    -------
    y : ndarray or bool
        True where ``x`` is NaT, false otherwise.
        $OUT_SCALAR_1  # 返回值的详细说明将在实际文档中替换

    See Also
    --------
    isnan, isinf, isneginf, isposinf, isfinite

    Examples
    --------
    >>> np.isnat(np.datetime64("NaT"))
    True
    >>> np.isnat(np.datetime64("2016-01-01"))
    False
    >>> np.isnat(np.array(["NaT", "2016-01-01"], dtype="datetime64[ns]"))
    array([ True, False])

    """)

# 将新文档添加到numpy._core.umath模块,函数名为'left_shift'
add_newdoc('numpy._core.umath', 'left_shift',
    """
    Shift the bits of an integer to the left.

    Bits are shifted to the left by appending `x2` 0s at the right of `x1`.
    Since the internal representation of numbers is in binary format, this
    operation is equivalent to multiplying `x1` by ``2**x2``.

    Parameters
    ----------
    x1 : array_like of integer type
        Input values.
    x2 : array_like of integer type
        Number of zeros to append to `x1`. Has to be non-negative.
        $BROADCASTABLE_2  # 参数的详细说明将在实际文档中替换
    $PARAMS  # 参数的详细说明将在实际文档中替换

    Returns
    -------
    out : array of integer type
        Return `x1` with bits shifted `x2` times to the left.
        $OUT_SCALAR_2  # 返回值的详细说明将在实际文档中替换

    See Also
    --------
    right_shift : Shift the bits of an integer to the right.
    binary_repr : Return the binary representation of the input number
        as a string.

    Examples
    --------
    >>> np.binary_repr(5)
    '101'
    >>> np.left_shift(5, 2)
    20
    >>> np.binary_repr(20)
    '10100'

    >>> np.left_shift(5, [1,2,3])
    array([10, 20, 40])

    Note that the dtype of the second argument may change the dtype of the
    result and can lead to unexpected results in some cases (see
    :ref:`Casting Rules <ufuncs.casting>`):

    >>> a = np.left_shift(np.uint8(255), np.int64(1))  # Expect 254
    >>> print(a, type(a)) # Unexpected result due to upcasting
    510 <class 'numpy.int64'>
    >>> b = np.left_shift(np.uint8(255), np.uint8(1))
    >>> print(b, type(b))
    254 <class 'numpy.uint8'>

    The ``<<`` operator can be used as a shorthand for ``np.left_shift`` on
    ndarrays.

    >>> x1 = 5
    >>> x2 = np.array([1, 2, 3])
    >>> x1 << x2
    array([10, 20, 40])

    """)

# 将新文档添加到numpy._core.umath模块,函数名为'less'
add_newdoc('numpy._core.umath', 'less',
    """
    Return the truth value of (x1 < x2) element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays.
        $BROADCASTABLE_2  # 参数的详细说明将在实际文档中替换
    $PARAMS  # 参数的详细说明将在实际文档中替换

    Returns
    -------
    out : ndarray or scalar
        Output array, element-wise comparison of `x1` and `x2`.
        Typically of type bool, unless ``dtype=object`` is passed.
        $OUT_SCALAR_2  # 返回值的详细说明将在实际文档中替换

    See Also
    --------
    greater, less_equal, greater_equal, equal, not_equal

    Examples
    --------
    >>> np.less([1, 2], [2, 2])

    """)
    array([ True, False])

    # 创建一个NumPy数组,包含布尔值True和False
    # 这个数组展示了在ndarray上使用“<”运算符作为np.less的缩写的效果

    >>> a = np.array([1, 2])
    >>> b = np.array([2, 2])
    >>> a < b
    # 比较数组a和数组b中的元素,返回一个布尔类型的数组,显示每个元素是否满足小于的条件
    array([ True, False])

    """
# 添加新的文档字符串给指定的numpy._core.umath函数'less_equal'
add_newdoc('numpy._core.umath', 'less_equal',
    """
    返回元素级别上的(x1 <= x2)的真值。

    参数
    ----------
    x1, x2 : array_like
        输入数组。
        $BROADCASTABLE_2
    $PARAMS

    返回
    -------
    out : ndarray 或者标量
        输出数组,元素级别上的 `x1` 和 `x2` 的比较结果。
        通常为布尔类型,除非传入 ``dtype=object``。
        $OUT_SCALAR_2

    另请参阅
    --------
    greater, less, greater_equal, equal, not_equal

    示例
    --------
    >>> np.less_equal([4, 2, 1], [2, 2, 2])
    array([False,  True,  True])

    运算符 ``<=`` 可以用作 ``np.less_equal`` 在 ndarray 上的简写。

    >>> a = np.array([4, 2, 1])
    >>> b = np.array([2, 2, 2])
    >>> a <= b
    array([False,  True,  True])

    """)

# 添加新的文档字符串给指定的numpy._core.umath函数'log'
add_newdoc('numpy._core.umath', 'log',
    """
    自然对数,元素级别。

    自然对数 `log` 是指数函数的反函数,因此 `log(exp(x)) = x`。自然对数的底数为 `e`。

    参数
    ----------
    x : array_like
        输入值。
    $PARAMS

    返回
    -------
    y : ndarray
        `x` 的自然对数,元素级别。
        $OUT_SCALAR_1

    另请参阅
    --------
    log10, log2, log1p, emath.log

    注意
    -----
    对数是多值函数:对于每个 `x`,都有无穷多个 `z` 满足 `exp(z) = x`。惯例上返回其虚部在 `(-pi, pi]` 之间的 `z`。

    对于实数输入数据类型,`log` 总是返回实数输出。对于每个不能表示为实数或无穷大的值,返回 `nan` 并设置 `invalid` 浮点错误标志。

    对于复数输入,`log` 是一个复解析函数,在其上具有一个分支割线 `[-inf, 0]`,在上方连续。`log` 处理浮点数的负零作为一个无穷小的负数,符合 C99 标准。

    在输入具有负实部和非常小的负复部(接近0)的情况下,结果接近 `-pi`,且确切地评估为 `-pi`。

    引用
    ----------
    .. [1] M. Abramowitz 和 I.A. Stegun, "Handbook of Mathematical Functions",
           第10版印刷, 1964, pp. 67.
           https://personal.math.ubc.ca/~cbm/aands/page_67.htm
    .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm

    示例
    --------
    >>> np.log([1, np.e, np.e**2, 0])
    array([  0.,   1.,   2., -inf])

    """)

# 添加新的文档字符串给指定的numpy._core.umath函数'log10'
add_newdoc('numpy._core.umath', 'log10',
    """
    返回输入数组的以10为底的对数,元素级别。

    参数
    ----------
    x : array_like
        输入值。
    $PARAMS

    返回
    -------
    y : ndarray
        `x` 的以10为底的对数,元素级别。当 x 为负时返回 NaN。
        $OUT_SCALAR_1


    """)
    # 查看 emath.log10 函数的相关文档和用法
    See Also
    --------
    emath.log10
    
    # 注意事项部分提供了对于对数函数 log10 的解释,尤其是对于复数输入和实数输入的处理规则
    Notes
    -----
    Logarithm is a multivalued function: for each `x` there is an infinite
    number of `z` such that `10**z = x`. The convention is to return the
    `z` whose imaginary part lies in `(-pi, pi]`.
    
    For real-valued input data types, `log10` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.
    
    For complex-valued input, `log10` is a complex analytical function that
    has a branch cut `[-inf, 0]` and is continuous from above on it.
    `log10` handles the floating-point negative zero as an infinitesimal
    negative number, conforming to the C99 standard.
    
    In the cases where the input has a negative real part and a very small
    negative complex part (approaching 0), the result is so close to `-pi`
    that it evaluates to exactly `-pi`.
    
    # 参考文献部分引用了两个对数函数的标准参考资料
    References
    ----------
    .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
           10th printing, 1964, pp. 67.
           https://personal.math.ubc.ca/~cbm/aands/page_67.htm
    .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm
    
    # 示例部分展示了不同输入情况下的 `log10` 函数的输出结果
    Examples
    --------
    >>> np.log10([1e-15, -3.])
    array([-15.,  nan])
# 在 numpy._core.umath 模块中添加新的文档字符串,用于描述 log2 函数
add_newdoc('numpy._core.umath', 'log2',
    """
    Base-2 logarithm of `x`.

    Parameters
    ----------
    x : array_like
        Input values.
        $PARAMS

    Returns
    -------
    y : ndarray
        Base-2 logarithm of `x`.
        $OUT_SCALAR_1

    See Also
    --------
    log, log10, log1p, emath.log2

    Notes
    -----
    .. versionadded:: 1.3.0

    Logarithm is a multivalued function: for each `x` there is an infinite
    number of `z` such that `2**z = x`. The convention is to return the `z`
    whose imaginary part lies in `(-pi, pi]`.

    For real-valued input data types, `log2` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `log2` is a complex analytical function that
    has a branch cut `[-inf, 0]` and is continuous from above on it. `log2`
    handles the floating-point negative zero as an infinitesimal negative
    number, conforming to the C99 standard.

    In the cases where the input has a negative real part and a very small
    negative complex part (approaching 0), the result is so close to `-pi`
    that it evaluates to exactly `-pi`.

    Examples
    --------
    >>> x = np.array([0, 1, 2, 2**4])
    >>> np.log2(x)
    array([-inf,   0.,   1.,   4.])

    >>> xi = np.array([0+1.j, 1, 2+0.j, 4.j])
    >>> np.log2(xi)
    array([ 0.+2.26618007j,  0.+0.j        ,  1.+0.j        ,  2.+2.26618007j])

    """)

# 在 numpy._core.umath 模块中添加新的文档字符串,用于描述 logaddexp 函数
add_newdoc('numpy._core.umath', 'logaddexp',
    """
    Logarithm of the sum of exponentiations of the inputs.

    Calculates ``log(exp(x1) + exp(x2))``. This function is useful in
    statistics where the calculated probabilities of events may be so small
    as to exceed the range of normal floating point numbers.  In such cases
    the logarithm of the calculated probability is stored. This function
    allows adding probabilities stored in such a fashion.

    Parameters
    ----------
    x1, x2 : array_like
        Input values.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    result : ndarray
        Logarithm of ``exp(x1) + exp(x2)``.
        $OUT_SCALAR_2

    See Also
    --------
    logaddexp2: Logarithm of the sum of exponentiations of inputs in base 2.

    Notes
    -----
    .. versionadded:: 1.3.0

    Examples
    --------
    >>> prob1 = np.log(1e-50)
    >>> prob2 = np.log(2.5e-50)
    >>> prob12 = np.logaddexp(prob1, prob2)
    >>> prob12
    -113.87649168120691
    >>> np.exp(prob12)
    3.5000000000000057e-50

    """)

# 在 numpy._core.umath 模块中添加新的文档字符串,用于描述 logaddexp2 函数
add_newdoc('numpy._core.umath', 'logaddexp2',
    """
    Logarithm of the sum of exponentiations of the inputs in base-2.

    Calculates ``log2(2**x1 + 2**x2)``. This function is useful in machine
    learning when the calculated probabilities of events may be so small as
    to exceed the range of normal floating point numbers.  In such cases
    the logarithm of the calculated probability is stored. This function
    allows adding probabilities stored in such a fashion.
    
    Parameters
    ----------
    x1, x2 : array_like
        Input values.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    result : ndarray
        Logarithm of ``2**x1 + 2**x2``.
        $OUT_SCALAR_3

    See Also
    --------
    logaddexp: Logarithm of the sum of exponentiations of the inputs.

    Notes
    -----
    .. versionadded:: 1.3.0

    Examples
    --------
    >>> prob1 = np.log2(1e-50)
    >>> prob2 = np.log2(2.5e-50)
    >>> prob12 = np.logaddexp2(prob1, prob2)
    >>> prob12
    -113.87649168120691
    >>> 2**prob12
    3.5000000000000057e-50

    """
    # 计算输入的两个值的指数和的对数,以2为底
    the base-2 logarithm of the calculated probability can be used instead.
    # 此函数允许添加以这种方式存储的概率。
    This function allows adding probabilities stored in such a fashion.

    Parameters
    ----------
    x1, x2 : array_like
        # 输入的值。
        Input values.
        # 可广播到二维的情况。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    result : ndarray
        # ``2**x1 + 2**x2`` 的以2为底的对数。
        Base-2 logarithm of ``2**x1 + 2**x2``.
        # 输出是标量的情况。
        $OUT_SCALAR_2

    See Also
    --------
    logaddexp: Logarithm of the sum of exponentiations of the inputs.

    Notes
    -----
    # 版本新增功能:1.3.0
    .. versionadded:: 1.3.0

    Examples
    --------
    >>> prob1 = np.log2(1e-50)
    >>> prob2 = np.log2(2.5e-50)
    >>> prob12 = np.logaddexp2(prob1, prob2)
    >>> prob1, prob2, prob12
    (-166.09640474436813, -164.77447664948076, -164.28904982231052)
    >>> 2**prob12
    3.4999999999999914e-50

    """
# 添加新的文档字符串到指定的NumPy函数
add_newdoc('numpy._core.umath', 'log1p',
    """
    Return the natural logarithm of one plus the input array, element-wise.

    Calculates ``log(1 + x)``.

    Parameters
    ----------
    x : array_like
        Input values.
        $PARAMS

    Returns
    -------
    y : ndarray
        Natural logarithm of `1 + x`, element-wise.
        $OUT_SCALAR_1

    See Also
    --------
    expm1 : ``exp(x) - 1``, the inverse of `log1p`.

    Notes
    -----
    For real-valued input, `log1p` is accurate also for `x` so small
    that `1 + x == 1` in floating-point accuracy.

    Logarithm is a multivalued function: for each `x` there is an infinite
    number of `z` such that `exp(z) = 1 + x`. The convention is to return
    the `z` whose imaginary part lies in `[-pi, pi]`.

    For real-valued input data types, `log1p` always returns real output.
    For each value that cannot be expressed as a real number or infinity,
    it yields ``nan`` and sets the `invalid` floating point error flag.

    For complex-valued input, `log1p` is a complex analytical function that
    has a branch cut `[-inf, -1]` and is continuous from above on it.
    `log1p` handles the floating-point negative zero as an infinitesimal
    negative number, conforming to the C99 standard.

    References
    ----------
    .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions",
           10th printing, 1964, pp. 67.
           https://personal.math.ubc.ca/~cbm/aands/page_67.htm
    .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm

    Examples
    --------
    >>> np.log1p(1e-99)
    1e-99
    >>> np.log(1 + 1e-99)
    0.0

    """)

# 添加新的文档字符串到指定的NumPy函数
add_newdoc('numpy._core.umath', 'logical_and',
    """
    Compute the truth value of x1 AND x2 element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray or bool
        Boolean result of the logical AND operation applied to the elements
        of `x1` and `x2`; the shape is determined by broadcasting.
        $OUT_SCALAR_2

    See Also
    --------
    logical_or, logical_not, logical_xor
    bitwise_and

    Examples
    --------
    >>> np.logical_and(True, False)
    False
    >>> np.logical_and([True, False], [False, False])
    array([False, False])

    >>> x = np.arange(5)
    >>> np.logical_and(x>1, x<4)
    array([False, False,  True,  True, False])


    The ``&`` operator can be used as a shorthand for ``np.logical_and`` on
    boolean ndarrays.

    >>> a = np.array([True, False])
    >>> b = np.array([False, False])
    >>> a & b
    array([False, False])

    """)

# 添加新的文档字符串到指定的NumPy函数
add_newdoc('numpy._core.umath', 'logical_not',
    """
    Compute the truth value of NOT x element-wise.

    Parameters
    ----------
    x : array_like
        Logical NOT is applied to the elements of `x`.
    $PARAMS

    Returns
    -------
    y : ndarray or bool
        Boolean result of the logical NOT operation applied to the elements
        of `x`.
        $OUT_SCALAR_3

    Examples
    --------
    >>> np.logical_not(True)
    False
    >>> np.logical_not([True, False, 0, 1])
    array([False,  True,  True, False])

    """)
    # y : bool or ndarray of bool
    # 表示结果变量 y,可以是单个布尔值或布尔值数组,与输入 x 具有相同的形状,表示对 x 中元素进行逻辑非操作的结果。
    # $OUT_SCALAR_1
    # 此处可能存在文档生成工具的占位符或注释标记,用于文档自动生成,实际使用时可能会被替换成相应内容。

    # See Also
    # --------
    # logical_and, logical_or, logical_xor
    # 与本函数相关的其他逻辑运算函数,包括逻辑与、逻辑或、逻辑异或。

    # Examples
    # --------
    # >>> np.logical_not(3)
    # False
    # 对标量 3 进行逻辑非运算,结果为 False。
    # >>> np.logical_not([True, False, 0, 1])
    # array([False,  True,  True, False])
    # 对布尔数组 [True, False, 0, 1] 中的每个元素进行逻辑非运算,返回对应的布尔值数组。

    # >>> x = np.arange(5)
    # >>> np.logical_not(x<3)
    # array([False, False, False,  True,  True])
    # 创建一个长度为 5 的数组 x,对 x<3 的结果进行逻辑非运算,返回结果数组。
# 向 numpy._core.umath 模块添加新的文档字符串,定义了 logical_or 函数
add_newdoc('numpy._core.umath', 'logical_or',
    """
    Compute the truth value of x1 OR x2 element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Logical OR is applied to the elements of `x1` and `x2`.
        $BROADCASTABLE_2  # 描述参数可以广播到的形状
    $PARAMS  # 描述未列出的参数信息

    Returns
    -------
    y : ndarray or bool
        Boolean result of the logical OR operation applied to the elements
        of `x1` and `x2`; the shape is determined by broadcasting.
        $OUT_SCALAR_2  # 描述返回值的形状和类型

    See Also
    --------
    logical_and, logical_not, logical_xor  # 相关的逻辑运算函数
    bitwise_or  # 位运算的 OR 操作

    Examples
    --------
    >>> np.logical_or(True, False)
    True
    >>> np.logical_or([True, False], [False, False])
    array([ True, False])

    >>> x = np.arange(5)
    >>> np.logical_or(x < 1, x > 3)
    array([ True, False, False, False,  True])

    The ``|`` operator can be used as a shorthand for ``np.logical_or`` on
    boolean ndarrays.

    >>> a = np.array([True, False])
    >>> b = np.array([False, False])
    >>> a | b
    array([ True, False])

    """)

# 向 numpy._core.umath 模块添加新的文档字符串,定义了 logical_xor 函数
add_newdoc('numpy._core.umath', 'logical_xor',
    """
    Compute the truth value of x1 XOR x2, element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Logical XOR is applied to the elements of `x1` and `x2`.
        $BROADCASTABLE_2  # 描述参数可以广播到的形状
    $PARAMS  # 描述未列出的参数信息

    Returns
    -------
    y : bool or ndarray of bool
        Boolean result of the logical XOR operation applied to the elements
        of `x1` and `x2`; the shape is determined by broadcasting.
        $OUT_SCALAR_2  # 描述返回值的形状和类型

    See Also
    --------
    logical_and, logical_or, logical_not, bitwise_xor  # 相关的逻辑运算函数和位运算的 XOR 操作

    Examples
    --------
    >>> np.logical_xor(True, False)
    True
    >>> np.logical_xor([True, True, False, False], [True, False, True, False])
    array([False,  True,  True, False])

    >>> x = np.arange(5)
    >>> np.logical_xor(x < 1, x > 3)
    array([ True, False, False, False,  True])

    Simple example showing support of broadcasting

    >>> np.logical_xor(0, np.eye(2))
    array([[ True, False],
           [False,  True]])

    """)

# 向 numpy._core.umath 模块添加新的文档字符串,定义了 maximum 函数
add_newdoc('numpy._core.umath', 'maximum',
    """
    Element-wise maximum of array elements.

    Compare two arrays and return a new array containing the element-wise
    maxima. If one of the elements being compared is a NaN, then that
    element is returned. If both elements are NaNs then the first is
    returned. The latter distinction is important for complex NaNs, which
    are defined as at least one of the real or imaginary parts being a NaN.
    The net effect is that NaNs are propagated.

    Parameters
    ----------
    x1, x2 : array_like
        The arrays holding the elements to be compared.
        $BROADCASTABLE_2  # 描述参数可以广播到的形状
    $PARAMS  # 描述未列出的参数信息

    Returns
    -------
    y : ndarray or scalar
        The maximum of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2  # 描述返回值的形状和类型

    See Also
    --------
    minimum :  # 最小值函数的参考链接
        Element-wise minimum of two arrays, propagates NaNs.

    """)
    fmax :
        Element-wise maximum of two arrays, ignores NaNs.
    amax :
        The maximum value of an array along a given axis, propagates NaNs.
    nanmax :
        The maximum value of an array along a given axis, ignores NaNs.

    fmin, amin, nanmin

    Notes
    -----
    The maximum is equivalent to ``np.where(x1 >= x2, x1, x2)`` when
    neither x1 nor x2 are nans, but it is faster and does proper
    broadcasting.

    Examples
    --------
    >>> np.maximum([2, 3, 4], [1, 5, 2])
    array([2, 5, 4])

    >>> np.maximum(np.eye(2), [0.5, 2]) # broadcasting
    array([[ 1. ,  2. ],
           [ 0.5,  2. ]])

    >>> np.maximum([np.nan, 0, np.nan], [0, np.nan, np.nan])
    array([nan, nan, nan])
    >>> np.maximum(np.inf, 1)
    inf

    """


注释:

    fmax :
        两个数组的逐元素最大值,忽略 NaN 值。
    amax :
        沿指定轴的数组最大值,传播 NaN 值。
    nanmax :
        沿指定轴的数组最大值,忽略 NaN 值。

    fmin, amin, nanmin :
        与上述相似,分别表示逐元素最小值、沿指定轴的最小值,以及忽略 NaN 的最小值。

    Notes
    -----
    maximum 函数的作用类似于 ``np.where(x1 >= x2, x1, x2)``,在 x1 和 x2 都不是 NaN 时,
    但它执行速度更快且进行适当的广播。

    Examples
    --------
    几个使用 maximum 函数的示例:
    - 比较两个数组的逐元素最大值,返回结果数组。
    - 使用广播功能,将单位矩阵与数组进行比较。
    - 处理包含 NaN 值的情况,返回 NaN 值的数组。
    - 处理与无穷大的比较,返回无穷大值。

    """
# 添加新文档(docstring)到numpy._core.umath中的'minimum'函数
add_newdoc('numpy._core.umath', 'minimum',
    """
    Element-wise minimum of array elements.

    Compare two arrays and return a new array containing the element-wise
    minima. If one of the elements being compared is a NaN, then that
    element is returned. If both elements are NaNs then the first is
    returned. The latter distinction is important for complex NaNs, which
    are defined as at least one of the real or imaginary parts being a NaN.
    The net effect is that NaNs are propagated.

    Parameters
    ----------
    x1, x2 : array_like
        The arrays holding the elements to be compared.
        $BROADCASTABLE_2  # 标记参数x1和x2可以广播
    $PARAMS  # 标记包含其他参数说明的部分

    Returns
    -------
    y : ndarray or scalar
        The minimum of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2  # 标记返回值是数组或标量

    See Also
    --------
    maximum :
        Element-wise maximum of two arrays, propagates NaNs.
    fmin :
        Element-wise minimum of two arrays, ignores NaNs.
    amin :
        The minimum value of an array along a given axis, propagates NaNs.
    nanmin :
        The minimum value of an array along a given axis, ignores NaNs.

    fmax, amax, nanmax

    Notes
    -----
    The minimum is equivalent to ``np.where(x1 <= x2, x1, x2)`` when
    neither x1 nor x2 are NaNs, but it is faster and does proper
    broadcasting.

    Examples
    --------
    >>> np.minimum([2, 3, 4], [1, 5, 2])
    array([1, 3, 2])

    >>> np.minimum(np.eye(2), [0.5, 2]) # broadcasting
    array([[ 0.5,  0. ],
           [ 0. ,  1. ]])

    >>> np.minimum([np.nan, 0, np.nan],[0, np.nan, np.nan])
    array([nan, nan, nan])
    >>> np.minimum(-np.inf, 1)
    -inf

    """)

# 添加新文档(docstring)到numpy._core.umath中的'fmax'函数
add_newdoc('numpy._core.umath', 'fmax',
    """
    Element-wise maximum of array elements.

    Compare two arrays and return a new array containing the element-wise
    maxima. If one of the elements being compared is a NaN, then the
    non-nan element is returned. If both elements are NaNs then the first
    is returned.  The latter distinction is important for complex NaNs,
    which are defined as at least one of the real or imaginary parts being
    a NaN. The net effect is that NaNs are ignored when possible.

    Parameters
    ----------
    x1, x2 : array_like
        The arrays holding the elements to be compared.
        $BROADCASTABLE_2  # 标记参数x1和x2可以广播
    $PARAMS  # 标记包含其他参数说明的部分

    Returns
    -------
    y : ndarray or scalar
        The maximum of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2  # 标记返回值是数组或标量

    See Also
    --------
    fmin :
        Element-wise minimum of two arrays, ignores NaNs.
    maximum :
        Element-wise maximum of two arrays, propagates NaNs.
    amax :
        The maximum value of an array along a given axis, propagates NaNs.
    nanmax :
        The maximum value of an array along a given axis, ignores NaNs.

    minimum, amin, nanmin

    Notes
    -----
    .. versionadded:: 1.3.0

    The fmax is equivalent to ``np.where(x1 >= x2, x1, x2)`` when neither
    """
    x1 nor x2 are NaNs, but it is faster and does proper broadcasting.
    # x1 和 x2 都不是 NaN 时,函数表现更快且执行正确的广播操作。

    Examples
    --------
    >>> np.fmax([2, 3, 4], [1, 5, 2])
    array([ 2.,  5.,  4.])
    # 对两个数组进行元素级比较,返回每个位置上的较大值组成的数组。

    >>> np.fmax(np.eye(2), [0.5, 2])
    array([[ 1. ,  2. ],
           [ 0.5,  2. ]])
    # 将单位矩阵与数组进行元素级比较,返回每个位置上的较大值组成的数组。

    >>> np.fmax([np.nan, 0, np.nan],[0, np.nan, np.nan])
    array([ 0.,  0., nan])
    # 对包含 NaN 的数组进行元素级比较,返回每个位置上的较大值组成的数组。
    
    """
# 添加新的文档字符串到指定的NumPy模块和函数名
add_newdoc('numpy._core.umath', 'fmin',
    """
    Element-wise minimum of array elements.
    
    Compare two arrays element-wise and return a new array containing the element-wise
    minima. If one of the elements being compared is NaN, then the non-NaN element is returned.
    If both elements are NaNs, then the first NaN element is returned, which is crucial for
    handling complex NaNs where either the real or imaginary parts are NaN. NaNs are effectively
    ignored whenever possible.
    
    Parameters
    ----------
    x1, x2 : array_like
        Arrays holding the elements to be compared.
        $BROADCASTABLE_2
    $PARAMS
    
    Returns
    -------
    y : ndarray or scalar
        Element-wise minimum of `x1` and `x2`.
        $OUT_SCALAR_2
    
    See Also
    --------
    fmax :
        Element-wise maximum of two arrays, ignoring NaNs.
    minimum :
        Element-wise minimum of two arrays, propagating NaNs.
    amin :
        Minimum value of an array along a given axis, propagating NaNs.
    nanmin :
        Minimum value of an array along a given axis, ignoring NaNs.
    
    maximum, amax, nanmax
    
    Notes
    -----
    .. versionadded:: 1.3.0
    
    fmin is equivalent to ``np.where(x1 <= x2, x1, x2)`` when neither x1 nor x2 are NaNs,
    but it performs faster and handles broadcasting correctly.
    
    Examples
    --------
    >>> np.fmin([2, 3, 4], [1, 5, 2])
    array([1, 3, 2])
    
    >>> np.fmin(np.eye(2), [0.5, 2])
    array([[ 0.5,  0. ],
           [ 0. ,  1. ]])
    
    >>> np.fmin([np.nan, 0, np.nan],[0, np.nan, np.nan])
    array([ 0.,  0., nan])
    
    """)

# 添加新的文档字符串到指定的NumPy模块和函数名
add_newdoc('numpy._core.umath', 'clip',
    """
    Clip (limit) the values in an array.
    
    Given an interval, values outside the interval are clipped to the interval edges.
    For example, if an interval of ``[0, 1]`` is specified, values smaller than 0 become 0,
    and values larger than 1 become 1.
    
    This function is equivalent to, but faster than ``np.minimum(np.maximum(a, a_min), a_max)``.
    
    Parameters
    ----------
    a : array_like
        Array containing elements to clip.
    a_min : array_like
        Minimum value.
    a_max : array_like
        Maximum value.
    out : ndarray, optional
        Array where clipped values are placed. It can be the input array for in-place clipping.
        `out` must be of the right shape to hold the output, and its type is preserved.
    $PARAMS
    
    See Also
    --------
    numpy.clip :
        Wrapper that makes the `a_min` and `a_max` arguments optional, dispatching to one of
        `~numpy._core.umath.clip`, `~numpy._core.umath.minimum`, and `~numpy._core.umath.maximum`.
    
    Returns
    -------
    clipped_array : ndarray
        Array with elements of `a`, but values < `a_min` are replaced with `a_min`,
        and values > `a_max` are replaced with `a_max`.
    """)

# 添加新的文档字符串到指定的NumPy模块和函数名
add_newdoc('numpy._core.umath', 'matmul',
    """
    Matrix product of two arrays.
    
    Parameters
    # 定义 matmul 函数,用于执行矩阵乘法操作
    ----------
    # x1, x2 : array_like
    #     输入的数组,不允许是标量。
    # out : ndarray, optional
    #     存储结果的位置。如果提供,则必须具有与签名 `(n,k),(k,m)->(n,m)` 相匹配的形状。
    #     如果未提供或为 None,则返回一个新分配的数组。
    # **kwargs
    #     其他关键字参数,参见 :ref:`ufunc docs <ufuncs.kwargs>`。
    #
    #     .. versionadded:: 1.16
    #        现在支持处理 ufunc 的 kwargs
    #
    # Returns
    # -------
    # y : ndarray
    #     输入的矩阵的乘积。
    #     当 x1 和 x2 都是 1-D 向量时,这是一个标量。
    #
    # Raises
    # ------
    # ValueError
    #     如果 `x1` 的最后一个维度与 `x2` 倒数第二个维度的大小不同。
    #
    #     如果传入的是标量值。
    #
    # See Also
    # --------
    # vdot : 复共轭点积。
    # tensordot : 在任意轴上进行求和。
    # einsum : Einstein 求和约定。
    # dot : 具有不同广播规则的备用矩阵乘积。
    #
    # Notes
    # -----
    #
    # 行为取决于以下方式的参数。
    #
    # - 如果两个参数都是 2-D,则它们像传统矩阵一样相乘。
    # - 如果任一参数是 N-D,N > 2,则将其视为驻留在最后两个索引中的矩阵堆栈,并相应广播。
    # - 如果第一个参数是 1-D,则通过在其维度之前加一个 1 来提升为矩阵。矩阵乘法后,去除前加的 1。
    # - 如果第二个参数是 1-D,则通过在其维度之后添加一个 1 来提升为矩阵。矩阵乘法后,去除后加的 1。
    #
    # ``matmul`` 与 ``dot`` 有两个重要的不同之处:
    #
    # - 不允许标量乘法,请使用 ``*`` 替代。
    # - 矩阵堆栈按照元素的方式一起广播,遵循签名 ``(n,k),(k,m)->(n,m)``:
    #
    #   >>> a = np.ones([9, 5, 7, 4])
    #   >>> c = np.ones([9, 5, 4, 3])
    #   >>> np.dot(a, c).shape
    #   (9, 5, 7, 9, 5, 3)
    #   >>> np.matmul(a, c).shape
    #   (9, 5, 7, 3)
    #   >>> # n 是 7, k 是 4, m 是 3
    #
    # ``matmul`` 函数实现了在 Python 3.5 引入的 ``@`` 操作符的语义,参见 :pep:`465`。
    #
    # 在可能的情况下,它使用了优化的 BLAS 库(参见 `numpy.linalg`)。
    #
    # Examples
    # --------
    #
    # 对于 2-D 数组,它是矩阵乘积:
    #
    # >>> a = np.array([[1, 0],
    # ...               [0, 1]])
    # >>> b = np.array([[4, 1],
    # ...               [2, 2]])
    # >>> np.matmul(a, b)
    # array([[4, 1],
    #        [2, 2]])
    #
    # 对于 2-D 与 1-D 混合,结果是通常的。
    #
    # >>> a = np.array([[1, 0],
    # ...               [0, 1]])
    # >>> b = np.array([1, 2])
    # >>> np.matmul(a, b)
    # array([1, 2])
    # >>> np.matmul(b, a)
    # array([1, 2])
    #
    # 对于数组堆栈,广播是常规的。
    #
    # >>> a = np.arange(2 * 2 * 4).reshape((2, 2, 4))
    # 创建一个 3 维的 numpy 数组 a,形状为 (2, 2, 2 * 4),并填充从 0 到 15 的数值
    a = np.arange(2 * 2 * 4).reshape((2, 4, 2))
    
    # 使用 np.matmul 计算 a 和 b 的矩阵乘积,返回结果的形状
    np.matmul(a,b).shape
    
    # 使用 np.matmul 计算 a 和 b 的矩阵乘积,并返回结果中第 (0, 1, 1) 位置的元素值
    np.matmul(a, b)[0, 1, 1]
    
    # 计算 a[0, 1, :] 和 b[0, :, 1] 的内积和
    sum(a[0, 1, :] * b[0 , :, 1])
    
    # 当两个复数向量作为参数时,使用 np.matmul 计算它们的矩阵乘积,返回复数形式的结果
    np.matmul([2j, 3j], [2j, 3j])
    
    # 当一个向量和一个标量作为参数时,抛出 ValueError 异常,因为标量不具备足够的维度
    np.matmul([1,2], 3)
    
    # 使用 @ 运算符作为 np.matmul 的简写,计算两个复数向量的矩阵乘积
    x1 = np.array([2j, 3j])
    x2 = np.array([2j, 3j])
    x1 @ x2
    
    # 此功能从 NumPy 1.10.0 版本开始添加支持
# 将新文档添加到 `numpy._core.umath` 模块,定义函数 `vecdot`
add_newdoc('numpy._core.umath', 'vecdot',
    """
    Vector dot product of two arrays.

    Let :math:`\\mathbf{a}` be a vector in `x1` and :math:`\\mathbf{b}` be
    a corresponding vector in `x2`. The dot product is defined as:

    .. math::
       \\mathbf{a} \\cdot \\mathbf{b} = \\sum_{i=0}^{n-1} \\overline{a_i}b_i

    where the sum is over the last dimension (unless `axis` is specified) and
    where :math:`\\overline{a_i}` denotes the complex conjugate if :math:`a_i`
    is complex and the identity otherwise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays, scalars not allowed.
    out : ndarray, optional
        A location into which the result is stored. If provided, it must have
        a shape that the broadcasted shape of `x1` and `x2` with the last axis
        removed. If not provided or None, a freshly-allocated array is used.
    **kwargs
        For other keyword-only arguments, see the
        :ref:`ufunc docs <ufuncs.kwargs>`.

    Returns
    -------
    y : ndarray
        The vector dot product of the inputs.
        This is a scalar only when both x1, x2 are 1-d vectors.

    Raises
    ------
    ValueError
        If the last dimension of `x1` is not the same size as
        the last dimension of `x2`.

        If a scalar value is passed in.

    See Also
    --------
    vdot : same but flattens arguments first
    einsum : Einstein summation convention.

    Examples
    --------
    Get the projected size along a given normal for an array of vectors.

    >>> v = np.array([[0., 5., 0.], [0., 0., 10.], [0., 6., 8.]])
    >>> n = np.array([0., 0.6, 0.8])
    >>> np.vecdot(v, n)
    array([ 3.,  8., 10.])

    .. versionadded:: 2.0.0
    """)

# 将新文档添加到 `numpy._core.umath` 模块,定义函数 `modf`
add_newdoc('numpy._core.umath', 'modf',
    """
    Return the fractional and integral parts of an array, element-wise.

    The fractional and integral parts are negative if the given number is
    negative.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    y1 : ndarray
        Fractional part of `x`.
        $OUT_SCALAR_1
    y2 : ndarray
        Integral part of `x`.
        $OUT_SCALAR_1

    Notes
    -----
    For integer input the return values are floats.

    See Also
    --------
    divmod : ``divmod(x, 1)`` is equivalent to ``modf`` with the return values
             switched, except it always has a positive remainder.

    Examples
    --------
    >>> np.modf([0, 3.5])
    (array([ 0. ,  0.5]), array([ 0.,  3.]))
    >>> np.modf(-0.5)
    (-0.5, -0)

    """)

# 将新文档添加到 `numpy._core.umath` 模块,定义函数 `multiply`
add_newdoc('numpy._core.umath', 'multiply',
    """
    Multiply arguments element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays to be multiplied.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray
        The product of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2

    Notes
    -----
    Equivalent to `x1` * `x2` in terms of array broadcasting.
    """)
    Examples
    --------
    >>> np.multiply(2.0, 4.0)
    8.0
    # 对两个数进行乘法运算,返回结果 8.0
    
    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = np.arange(3.0)
    >>> np.multiply(x1, x2)
    array([[  0.,   1.,   4.],
           [  0.,   4.,  10.],
           [  0.,   7.,  16.]])
    # 创建一个 3x3 的二维数组 x1 和一个长度为 3 的一维数组 x2,
    # 对它们进行对应位置的乘法运算,返回一个新的二维数组
    
    The ``*`` operator can be used as a shorthand for ``np.multiply`` on
    ndarrays.
    
    >>> x1 = np.arange(9.0).reshape((3, 3))
    >>> x2 = np.arange(3.0)
    >>> x1 * x2
    array([[  0.,   1.,   4.],
           [  0.,   4.,  10.],
           [  0.,   7.,  16.]])
    # 使用 ``*`` 操作符可以作为 np.multiply 的简写形式,适用于 ndarray
# 添加新的文档字符串到指定的 numpy 模块中的函数 'negative'
add_newdoc('numpy._core.umath', 'negative',
    """
    Numerical negative, element-wise.

    Parameters
    ----------
    x : array_like or scalar
        Input array.
    $PARAMS

    Returns
    -------
    y : ndarray or scalar
        Returned array or scalar: `y = -x`.
        $OUT_SCALAR_1

    Examples
    --------
    >>> np.negative([1.,-1.])
    array([-1.,  1.])

    The unary ``-`` operator can be used as a shorthand for ``np.negative`` on
    ndarrays.

    >>> x1 = np.array(([1., -1.]))
    >>> -x1
    array([-1.,  1.])

    """)

# 添加新的文档字符串到指定的 numpy 模块中的函数 'positive'
add_newdoc('numpy._core.umath', 'positive',
    """
    Numerical positive, element-wise.

    .. versionadded:: 1.13.0

    Parameters
    ----------
    x : array_like or scalar
        Input array.

    Returns
    -------
    y : ndarray or scalar
        Returned array or scalar: `y = +x`.
        $OUT_SCALAR_1

    Notes
    -----
    Equivalent to `x.copy()`, but only defined for types that support
    arithmetic.

    Examples
    --------

    >>> x1 = np.array(([1., -1.]))
    >>> np.positive(x1)
    array([ 1., -1.])

    The unary ``+`` operator can be used as a shorthand for ``np.positive`` on
    ndarrays.

    >>> x1 = np.array(([1., -1.]))
    >>> +x1
    array([ 1., -1.])

    """)

# 添加新的文档字符串到指定的 numpy 模块中的函数 'not_equal'
add_newdoc('numpy._core.umath', 'not_equal',
    """
    Return (x1 != x2) element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        Input arrays.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Output array, element-wise comparison of `x1` and `x2`.
        Typically of type bool, unless ``dtype=object`` is passed.
        $OUT_SCALAR_2

    See Also
    --------
    equal, greater, greater_equal, less, less_equal

    Examples
    --------
    >>> np.not_equal([1.,2.], [1., 3.])
    array([False,  True])
    >>> np.not_equal([1, 2], [[1, 3],[1, 4]])
    array([[False,  True],
           [False,  True]])

    The ``!=`` operator can be used as a shorthand for ``np.not_equal`` on
    ndarrays.

    >>> a = np.array([1., 2.])
    >>> b = np.array([1., 3.])
    >>> a != b
    array([False,  True])


    """)

# 添加新的文档字符串到指定的 numpy 模块中的函数 '_ones_like'
add_newdoc('numpy._core.umath', '_ones_like',
    """
    This function used to be the numpy.ones_like, but now a specific
    function for that has been written for consistency with the other
    *_like functions. It is only used internally in a limited fashion now.

    See Also
    --------
    ones_like

    """)

# 添加新的文档字符串到指定的 numpy 模块中的函数 'power'
add_newdoc('numpy._core.umath', 'power',
    """
    First array elements raised to powers from second array, element-wise.

    Raise each base in `x1` to the positionally-corresponding power in
    `x2`.  `x1` and `x2` must be broadcastable to the same shape.

    An integer type raised to a negative integer power will raise a
    ``ValueError``.

    Negative values raised to a non-integral value will return ``nan``.
    To get complex results, cast the input to complex, or specify the
    """)
    # 返回 `x1` 中每个元素以 `x2` 中对应元素为指数的幂运算结果,支持广播
    # 如果 `dtype` 设置为 `complex`,则返回复数结果(参见下面的示例)

    Parameters
    ----------
    x1 : array_like
        底数数组。
    x2 : array_like
        指数数组。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray
        数组 `x1` 中每个元素的指数为 `x2` 中对应元素的幂运算结果。
        $OUT_SCALAR_2

    See Also
    --------
    float_power : 将整数提升为浮点数的幂函数

    Examples
    --------
    对数组中的每个元素进行立方运算。

    >>> x1 = np.arange(6)
    >>> x1
    [0, 1, 2, 3, 4, 5]
    >>> np.power(x1, 3)
    array([  0,   1,   8,  27,  64, 125])

    将不同指数应用于不同的底数。

    >>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
    >>> np.power(x1, x2)
    array([  0.,   1.,   8.,  27.,  16.,   5.])

    广播效果示例。

    >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
    >>> x2
    array([[1, 2, 3, 3, 2, 1],
           [1, 2, 3, 3, 2, 1]])
    >>> np.power(x1, x2)
    array([[ 0,  1,  8, 27, 16,  5],
           [ 0,  1,  8, 27, 16,  5]])

    在 ndarray 上,可以使用 `**` 操作符作为 `np.power` 的简写。

    >>> x2 = np.array([1, 2, 3, 3, 2, 1])
    >>> x1 = np.arange(6)
    >>> x1 ** x2
    array([ 0,  1,  8, 27, 16,  5])

    将负数提升至非整数指数将导致结果为 `nan`(并生成警告)。

    >>> x3 = np.array([-1.0, -4.0])
    >>> with np.errstate(invalid='ignore'):
    ...     p = np.power(x3, 1.5)
    ...
    >>> p
    array([nan, nan])

    要获取复数结果,需要设置参数 `dtype=complex`。

    >>> np.power(x3, 1.5, dtype=complex)
    array([-1.83697020e-16-1.j, -1.46957616e-15-8.j])
# 在 numpy._core.umath 模块中添加新文档或修改现有文档,函数名为 float_power
add_newdoc('numpy._core.umath', 'float_power',
    """
    First array elements raised to powers from second array, element-wise.

    Raise each base in `x1` to the positionally-corresponding power in `x2`.
    `x1` and `x2` must be broadcastable to the same shape. This differs from
    the power function in that integers, float16, and float32  are promoted to
    floats with a minimum precision of float64 so that the result is always
    inexact.  The intent is that the function will return a usable result for
    negative powers and seldom overflow for positive powers.

    Negative values raised to a non-integral value will return ``nan``.
    To get complex results, cast the input to complex, or specify the
    ``dtype`` to be ``complex`` (see the example below).

    .. versionadded:: 1.12.0

    Parameters
    ----------
    x1 : array_like
        The bases.
    x2 : array_like
        The exponents.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray
        The bases in `x1` raised to the exponents in `x2`.
        $OUT_SCALAR_2

    See Also
    --------
    power : power function that preserves type

    Examples
    --------
    Cube each element in a list.

    >>> x1 = range(6)
    >>> x1
    [0, 1, 2, 3, 4, 5]
    >>> np.float_power(x1, 3)
    array([   0.,    1.,    8.,   27.,   64.,  125.])

    Raise the bases to different exponents.

    >>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
    >>> np.float_power(x1, x2)
    array([  0.,   1.,   8.,  27.,  16.,   5.])

    The effect of broadcasting.

    >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
    >>> x2
    array([[1, 2, 3, 3, 2, 1],
           [1, 2, 3, 3, 2, 1]])
    >>> np.float_power(x1, x2)
    array([[  0.,   1.,   8.,  27.,  16.,   5.],
           [  0.,   1.,   8.,  27.,  16.,   5.]])

    Negative values raised to a non-integral value will result in ``nan``
    (and a warning will be generated).

    >>> x3 = np.array([-1, -4])
    >>> with np.errstate(invalid='ignore'):
    ...     p = np.float_power(x3, 1.5)
    ...
    >>> p
    array([nan, nan])

    To get complex results, give the argument ``dtype=complex``.

    >>> np.float_power(x3, 1.5, dtype=complex)
    array([-1.83697020e-16-1.j, -1.46957616e-15-8.j])

    """)

# 在 numpy._core.umath 模块中添加新文档或修改现有文档,函数名为 radians
add_newdoc('numpy._core.umath', 'radians',
    """
    Convert angles from degrees to radians.

    Parameters
    ----------
    x : array_like
        Input array in degrees.
    $PARAMS

    Returns
    -------
    y : ndarray
        The corresponding radian values.
        $OUT_SCALAR_1

    See Also
    --------
    deg2rad : equivalent function

    Examples
    --------
    Convert a degree array to radians

    >>> deg = np.arange(12.) * 30.
    >>> np.radians(deg)
    array([ 0.        ,  0.52359878,  1.04719755,  1.57079633,  2.0943951 ,
            2.61799388,  3.14159265,  3.66519143,  4.1887902 ,  4.71238898,
            5.23598776,  5.75958653])

    >>> out = np.zeros((deg.shape))

    """)
    # 使用 NumPy 的 radians 函数将角度数组 deg 转换为弧度,并将结果存储到数组 out 中
    ret = np.radians(deg, out)
    # 检查返回的数组 ret 是否与数组 out 是同一个对象(即它们在内存中的地址是否相同)
    ret is out
    # 返回 True,表明 ret 和 out 是同一个数组对象
    True
# 添加新的文档字符串到指定的 NumPy 函数
add_newdoc('numpy._core.umath', 'deg2rad',
    """
    将角度从度转换为弧度。

    Parameters
    ----------
    x : array_like
        角度值(以度为单位)。
    $PARAMS

    Returns
    -------
    y : ndarray
        对应的弧度值。
        $OUT_SCALAR_1

    See Also
    --------
    rad2deg : 将弧度转换为角度。
    unwrap : 通过包装方式去除角度中的大跳变。

    Notes
    -----
    .. versionadded:: 1.3.0

    ``deg2rad(x)`` 的计算结果为 ``x * pi / 180``。

    Examples
    --------
    >>> np.deg2rad(180)
    3.1415926535897931

    """)

# 添加新的文档字符串到指定的 NumPy 函数
add_newdoc('numpy._core.umath', 'reciprocal',
    """
    返回参数的倒数,逐元素计算。

    计算 ``1/x``。

    Parameters
    ----------
    x : array_like
        输入数组。
    $PARAMS

    Returns
    -------
    y : ndarray
        返回的数组。
        $OUT_SCALAR_1

    Notes
    -----
    .. note::
        此函数不适用于整数。

    对于绝对值大于1的整数参数,结果总是0,这是由于 Python 处理整数除法的方式。对于整数0,结果是溢出。

    Examples
    --------
    >>> np.reciprocal(2.)
    0.5
    >>> np.reciprocal([1, 2., 3.33])
    array([ 1.       ,  0.5      ,  0.3003003])

    """)

# 添加新的文档字符串到指定的 NumPy 函数
add_newdoc('numpy._core.umath', 'remainder',
    """
    返回元素级别的除法余数。

    计算与 `floor_divide` 函数互补的余数。等效于 Python 的模运算符 ``x1 % x2``,并且具有与除数 `x2` 相同的符号。
    MATLAB 中等效于 ``np.remainder`` 的函数是 ``mod``。

    .. warning::

        这与以下内容不应混淆:

        * Python 3.7 的 `math.remainder` 和 C 的 ``remainder``,计算 IEEE 余数,是 ``round(x1 / x2)`` 的补数。
        * MATLAB 的 ``rem`` 函数或 C 的 ``%`` 运算符,是 ``int(x1 / x2)`` 的补数。

    Parameters
    ----------
    x1 : array_like
        被除数数组。
    x2 : array_like
        除数数组。
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    y : ndarray
        除法商 ``floor_divide(x1, x2)`` 的元素级别余数。
        $OUT_SCALAR_2

    See Also
    --------
    floor_divide : Python 中的 ``//`` 运算符的等效。
    divmod : 同时执行 floor 除法和余数计算。
    fmod : MATLAB 中的 ``rem`` 函数的等效。
    divide, floor

    Notes
    -----
    当 `x2` 为0且 `x1` 和 `x2` 均为(数组的)整数时,返回0。
    ``mod`` 是 ``remainder`` 的别名。

    Examples
    --------
    >>> np.remainder([4, 7], [2, 3])
    array([0, 1])
    >>> np.remainder(np.arange(7), 5)
    array([0, 1, 2, 3, 4, 0, 1])

    ``%`` 运算符可用作 ndarray 上 ``np.remainder`` 的简写。

    >>> x1 = np.arange(7)
    >>> x1 % 5

    """)
    array([0, 1, 2, 3, 4, 0, 1])
    """
    创建一个名为 `array` 的 NumPy 数组,包含整数元素 0, 1, 2, 3, 4, 0, 1。
    """
# 添加新的文档字符串到 numpy._core.umath 模块下的 divmod 函数
add_newdoc('numpy._core.umath', 'divmod',
    """
    Return element-wise quotient and remainder simultaneously.

    .. versionadded:: 1.13.0

    ``np.divmod(x, y)`` is equivalent to ``(x // y, x % y)``, but faster
    because it avoids redundant work. It is used to implement the Python
    built-in function ``divmod`` on NumPy arrays.

    Parameters
    ----------
    x1 : array_like
        Dividend array.
    x2 : array_like
        Divisor array.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out1 : ndarray
        Element-wise quotient resulting from floor division.
        $OUT_SCALAR_2
    out2 : ndarray
        Element-wise remainder from floor division.
        $OUT_SCALAR_2

    See Also
    --------
    floor_divide : Equivalent to Python's ``//`` operator.
    remainder : Equivalent to Python's ``%`` operator.
    modf : Equivalent to ``divmod(x, 1)`` for positive ``x`` with the return
           values switched.

    Examples
    --------
    >>> np.divmod(np.arange(5), 3)
    (array([0, 0, 0, 1, 1]), array([0, 1, 2, 0, 1]))

    The `divmod` function can be used as a shorthand for ``np.divmod`` on
    ndarrays.

    >>> x = np.arange(5)
    >>> divmod(x, 3)
    (array([0, 0, 0, 1, 1]), array([0, 1, 2, 0, 1]))

    """)

# 添加新的文档字符串到 numpy._core.umath 模块下的 right_shift 函数
add_newdoc('numpy._core.umath', 'right_shift',
    """
    Shift the bits of an integer to the right.

    Bits are shifted to the right `x2`.  Because the internal
    representation of numbers is in binary format, this operation is
    equivalent to dividing `x1` by ``2**x2``.

    Parameters
    ----------
    x1 : array_like, int
        Input values.
    x2 : array_like, int
        Number of bits to remove at the right of `x1`.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray, int
        Return `x1` with bits shifted `x2` times to the right.
        $OUT_SCALAR_2

    See Also
    --------
    left_shift : Shift the bits of an integer to the left.
    binary_repr : Return the binary representation of the input number
        as a string.

    Examples
    --------
    >>> np.binary_repr(10)
    '1010'
    >>> np.right_shift(10, 1)
    5
    >>> np.binary_repr(5)
    '101'

    >>> np.right_shift(10, [1,2,3])
    array([5, 2, 1])

    The ``>>`` operator can be used as a shorthand for ``np.right_shift`` on
    ndarrays.

    >>> x1 = 10
    >>> x2 = np.array([1,2,3])
    >>> x1 >> x2
    array([5, 2, 1])

    """)

# 添加新的文档字符串到 numpy._core.umath 模块下的 rint 函数
add_newdoc('numpy._core.umath', 'rint',
    """
    Round elements of the array to the nearest integer.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        Output array is same shape and type as `x`.
        $OUT_SCALAR_1

    See Also
    --------
    fix, ceil, floor, trunc

    Notes
    -----
    For values exactly halfway between rounded decimal values, NumPy
    rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,

    """)
    -0.5 and 0.5 round to 0.0, etc.
    # 在 numpy 中,-0.5 和 0.5 等数字会被四舍五入到最接近的整数,此外还有类似的情况。

    Examples
    --------
    >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
    # 创建一个 numpy 数组 a,包含了一组浮点数
    >>> np.rint(a)
    # 使用 numpy 的 rint 函数对数组 a 中的每个元素进行四舍五入
    array([-2., -2., -0.,  0.,  2.,  2.,  2.])
    # 返回结果是一个新的 numpy 数组,包含了每个元素四舍五入后的值

    """
# 将新的文档条目添加到numpy._core.umath模块中,名称为'sign'
add_newdoc('numpy._core.umath', 'sign',
    """
    Returns an element-wise indication of the sign of a number.

    The `sign` function returns ``-1 if x < 0, 0 if x==0, 1 if x > 0``.  nan
    is returned for nan inputs.

    For complex inputs, the `sign` function returns ``x / abs(x)``, the
    generalization of the above (and ``0 if x==0``).

    .. versionchanged:: 2.0.0
        Definition of complex sign changed to follow the Array API standard.

    Parameters
    ----------
    x : array_like
        Input values.
    $PARAMS

    Returns
    -------
    y : ndarray
        The sign of `x`.
        $OUT_SCALAR_1

    Notes
    -----
    There is more than one definition of sign in common use for complex
    numbers.  The definition used here is equivalent to :math:`x/\\sqrt{x*x}`
    which is different from a common alternative, :math:`x/|x|`.

    Examples
    --------
    >>> np.sign([-5., 4.5])
    array([-1.,  1.])
    >>> np.sign(0)
    0
    >>> np.sign([3-4j, 8j])
    array([0.6-0.8j, 0. +1.j ])

    """)

# 将新的文档条目添加到numpy._core.umath模块中,名称为'signbit'
add_newdoc('numpy._core.umath', 'signbit',
    """
    Returns element-wise True where signbit is set (less than zero).

    Parameters
    ----------
    x : array_like
        The input value(s).
    $PARAMS

    Returns
    -------
    result : ndarray of bool
        Output array, or reference to `out` if that was supplied.
        $OUT_SCALAR_1

    Examples
    --------
    >>> np.signbit(-1.2)
    True
    >>> np.signbit(np.array([1, -2.3, 2.1]))
    array([False,  True, False])

    """)

# 将新的文档条目添加到numpy._core.umath模块中,名称为'copysign'
add_newdoc('numpy._core.umath', 'copysign',
    """
    Change the sign of x1 to that of x2, element-wise.

    If `x2` is a scalar, its sign will be copied to all elements of `x1`.

    Parameters
    ----------
    x1 : array_like
        Values to change the sign of.
    x2 : array_like
        The sign of `x2` is copied to `x1`.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        The values of `x1` with the sign of `x2`.
        $OUT_SCALAR_2

    Examples
    --------
    >>> np.copysign(1.3, -1)
    -1.3
    >>> 1/np.copysign(0, 1)
    inf
    >>> 1/np.copysign(0, -1)
    -inf

    >>> np.copysign([-1, 0, 1], -1.1)
    array([-1., -0., -1.])
    >>> np.copysign([-1, 0, 1], np.arange(3)-1)
    array([-1.,  0.,  1.])

    """)

# 将新的文档条目添加到numpy._core.umath模块中,名称为'nextafter'
add_newdoc('numpy._core.umath', 'nextafter',
    """
    Return the next floating-point value after x1 towards x2, element-wise.

    Parameters
    ----------
    x1 : array_like
        Values to find the next representable value of.
    x2 : array_like
        The direction where to look for the next representable value of `x1`.
        $BROADCASTABLE_2
    $PARAMS

    Returns
    -------
    out : ndarray or scalar
        The next representable values of `x1` in the direction of `x2`.
        $OUT_SCALAR_2

    Examples
    --------
    >>> eps = np.finfo(np.float64).eps
    >>> np.nextafter(1, 2) == eps + 1
    True

    """)
    # 调用 NumPy 中的 nextafter 函数,用于获取接近指定数字的下一个浮点数
    np.nextafter([1, 2], [2, 1])
    # 比较 nextafter 返回的结果是否等于指定的值数组 [eps + 1, 2 - eps]
    np.nextafter([1, 2], [2, 1]) == [eps + 1, 2 - eps]
    # 返回一个布尔数组,指示每个对应位置的元素是否相等
    array([ True,  True])
# 添加新的文档字符串到numpy._core.umath模块中,定义spacing函数
add_newdoc('numpy._core.umath', 'spacing',
    """
    Return the distance between x and the nearest adjacent number.

    Parameters
    ----------
    x : array_like
        Values to find the spacing of.
    $PARAMS  # 参数详细信息将在实际使用时被替换

    Returns
    -------
    out : ndarray or scalar
        The spacing of values of `x`.
        $OUT_SCALAR_1  # 返回值的具体描述将在实际使用时被替换

    Notes
    -----
    It can be considered as a generalization of EPS:
    ``spacing(np.float64(1)) == np.finfo(np.float64).eps``, and there
    should not be any representable number between ``x + spacing(x)`` and
    x for any finite x.

    Spacing of +- inf and NaN is NaN.

    Examples
    --------
    >>> np.spacing(1) == np.finfo(np.float64).eps
    True

    """)

# 添加新的文档字符串到numpy._core.umath模块中,定义sin函数
add_newdoc('numpy._core.umath', 'sin',
    """
    Trigonometric sine, element-wise.

    Parameters
    ----------
    x : array_like
        Angle, in radians (:math:`2 \\pi` rad equals 360 degrees).
    $PARAMS  # 参数详细信息将在实际使用时被替换

    Returns
    -------
    y : array_like
        The sine of each element of x.
        $OUT_SCALAR_1  # 返回值的具体描述将在实际使用时被替换

    See Also
    --------
    arcsin, sinh, cos

    Notes
    -----
    The sine is one of the fundamental functions of trigonometry (the
    mathematical study of triangles).  Consider a circle of radius 1
    centered on the origin.  A ray comes in from the :math:`+x` axis, makes
    an angle at the origin (measured counter-clockwise from that axis), and
    departs from the origin.  The :math:`y` coordinate of the outgoing
    ray's intersection with the unit circle is the sine of that angle.  It
    ranges from -1 for :math:`x=3\\pi / 2` to +1 for :math:`\\pi / 2.`  The
    function has zeroes where the angle is a multiple of :math:`\\pi`.
    Sines of angles between :math:`\\pi` and :math:`2\\pi` are negative.
    The numerous properties of the sine and related functions are included
    in any standard trigonometry text.

    Examples
    --------
    Print sine of one angle:

    >>> np.sin(np.pi/2.)
    1.0

    Print sines of an array of angles given in degrees:

    >>> np.sin(np.array((0., 30., 45., 60., 90.)) * np.pi / 180. )
    array([ 0.        ,  0.5       ,  0.70710678,  0.8660254 ,  1.        ])

    Plot the sine function:

    >>> import matplotlib.pylab as plt
    >>> x = np.linspace(-np.pi, np.pi, 201)
    >>> plt.plot(x, np.sin(x))
    >>> plt.xlabel('Angle [rad]')
    >>> plt.ylabel('sin(x)')
    >>> plt.axis('tight')
    >>> plt.show()

    """)

# 添加新的文档字符串到numpy._core.umath模块中,定义sinh函数
add_newdoc('numpy._core.umath', 'sinh',
    """
    Hyperbolic sine, element-wise.

    Equivalent to ``1/2 * (np.exp(x) - np.exp(-x))`` or
    ``-1j * np.sin(1j*x)``.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS  # 参数详细信息将在实际使用时被替换

    Returns
    -------
    y : ndarray
        The corresponding hyperbolic sine values.
        $OUT_SCALAR_1  # 返回值的具体描述将在实际使用时被替换

    Notes
    -----
    If `out` is provided, the function writes the result into it,
    and returns a reference to `out`.  (See Examples)

    References
    ----------

    """)
    M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions.
    New York, NY: Dover, 1972, pg. 83.

    Examples
    --------
    >>> np.sinh(0)
    0.0
    >>> np.sinh(np.pi*1j/2)
    1j
    >>> np.sinh(np.pi*1j) # (exact value is 0)
    1.2246063538223773e-016j
    >>> # Discrepancy due to vagaries of floating point arithmetic.

    >>> # Example of providing the optional output parameter
    >>> out1 = np.array([0], dtype='d')
    >>> out2 = np.sinh([0.1], out1)
    >>> out2 is out1
    True

    >>> # Example of ValueError due to provision of shape mis-matched `out`
    >>> np.sinh(np.zeros((3,3)),np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: operands could not be broadcast together with shapes (3,3) (2,2)
# 在 numpy._core.umath 中添加新的文档字符串和函数 'sqrt'
add_newdoc('numpy._core.umath', 'sqrt',
    """
    Return the non-negative square-root of an array, element-wise.

    Parameters
    ----------
    x : array_like
        The values whose square-roots are required.
    $PARAMS  # 描述参数的占位符

    Returns
    -------
    y : ndarray
        An array of the same shape as `x`, containing the positive
        square-root of each element in `x`.  If any element in `x` is
        complex, a complex array is returned (and the square-roots of
        negative reals are calculated).  If all of the elements in `x`
        are real, so is `y`, with negative elements returning ``nan``.
        If `out` was provided, `y` is a reference to it.
        $OUT_SCALAR_1  # 描述返回值的占位符

    See Also
    --------
    emath.sqrt
        A version which returns complex numbers when given negative reals.
        Note that 0.0 and -0.0 are handled differently for complex inputs.

    Notes
    -----
    *sqrt* has--consistent with common convention--as its branch cut the
    real "interval" [`-inf`, 0), and is continuous from above on it.
    A branch cut is a curve in the complex plane across which a given
    complex function fails to be continuous.

    Examples
    --------
    >>> np.sqrt([1,4,9])
    array([ 1.,  2.,  3.])

    >>> np.sqrt([4, -1, -3+4J])
    array([ 2.+0.j,  0.+1.j,  1.+2.j])

    >>> np.sqrt([4, -1, np.inf])
    array([ 2., nan, inf])

    """)

# 在 numpy._core.umath 中添加新的文档字符串和函数 'cbrt'
add_newdoc('numpy._core.umath', 'cbrt',
    """
    Return the cube-root of an array, element-wise.

    .. versionadded:: 1.10.0  # 描述函数的版本增加信息

    Parameters
    ----------
    x : array_like
        The values whose cube-roots are required.
    $PARAMS  # 描述参数的占位符

    Returns
    -------
    y : ndarray
        An array of the same shape as `x`, containing the
        cube root of each element in `x`.
        If `out` was provided, `y` is a reference to it.
        $OUT_SCALAR_1  # 描述返回值的占位符

    Examples
    --------
    >>> np.cbrt([1,8,27])
    array([ 1.,  2.,  3.])

    """)

# 在 numpy._core.umath 中添加新的文档字符串和函数 'square'
add_newdoc('numpy._core.umath', 'square',
    """
    Return the element-wise square of the input.

    Parameters
    ----------
    x : array_like
        Input data.
    $PARAMS  # 描述参数的占位符

    Returns
    -------
    out : ndarray or scalar
        Element-wise `x*x`, of the same shape and dtype as `x`.
        $OUT_SCALAR_1  # 描述返回值的占位符

    See Also
    --------
    numpy.linalg.matrix_power
    sqrt
    power

    Examples
    --------
    >>> np.square([-1j, 1])
    array([-1.-0.j,  1.+0.j])

    """)

# 在 numpy._core.umath 中添加新的文档字符串和函数 'subtract'
add_newdoc('numpy._core.umath', 'subtract',
    """
    Subtract arguments, element-wise.

    Parameters
    ----------
    x1, x2 : array_like
        The arrays to be subtracted from each other.
        $BROADCASTABLE_2  # 描述参数的占位符
    $PARAMS  # 描述参数的占位符

    Returns
    -------
    y : ndarray
        The difference of `x1` and `x2`, element-wise.
        $OUT_SCALAR_2  # 描述返回值的占位符

    Notes
    -----
    Equivalent to ``x1 - x2`` in terms of array broadcasting.

    Examples
    --------
    >>> np.subtract(1.0, 4.0)
    -3.0

    >>> x1 = np.arange(9.0).reshape((3, 3))

    """)
    # 创建一个包含三个元素的 NumPy 数组,元素值为 [0.0, 1.0, 2.0]
    >>> x2 = np.arange(3.0)
    
    # 使用 NumPy 的 subtract 函数计算两个数组的差,结果是一个二维数组
    # 第一个数组 x1 是一个 3x3 的矩阵,包含 0 到 8 的整数,reshape 后为 (3, 3)
    # 第二个数组 x2 是一个包含三个元素的一维数组 [0.0, 1.0, 2.0]
    >>> np.subtract(x1, x2)
    array([[ 0.,  0.,  0.],
           [ 3.,  3.,  3.],
           [ 6.,  6.,  6.]])
    
    # 在 NumPy 中,操作符 '-' 可以作为 np.subtract 的缩写,用于对数组进行减法运算
    # 这里展示了使用操作符 '-' 计算数组之间的减法,结果与上面使用 np.subtract 的结果相同
    
    >>> x1 = np.arange(9.0).reshape((3, 3))
    # 创建一个 3x3 的数组 x1,包含 0 到 8 的浮点数,reshape 后形状为 (3, 3)
    >>> x2 = np.arange(3.0)
    # 创建一个包含三个元素的一维数组 x2,元素值为 [0.0, 1.0, 2.0]
    
    >>> x1 - x2
    # 对数组 x1 和 x2 进行减法操作,得到一个二维数组
    array([[0., 0., 0.],
           [3., 3., 3.],
           [6., 6., 6.]])
    
    # 这里再次展示了使用操作符 '-' 进行数组减法,得到的结果与上面使用 np.subtract 的结果一致
# 添加新的文档字符串给 'numpy._core.umath' 中的 'tan' 函数
add_newdoc('numpy._core.umath', 'tan',
    """
    Compute tangent element-wise.

    Equivalent to ``np.sin(x)/np.cos(x)`` element-wise.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    y : ndarray
        The corresponding tangent values.
        $OUT_SCALAR_1

    Notes
    -----
    If `out` is provided, the function writes the result into it,
    and returns a reference to `out`.  (See Examples)

    References
    ----------
    M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions.
    New York, NY: Dover, 1972.

    Examples
    --------
    >>> from math import pi
    >>> np.tan(np.array([-pi,pi/2,pi]))
    array([  1.22460635e-16,   1.63317787e+16,  -1.22460635e-16])
    >>>
    >>> # Example of providing the optional output parameter illustrating
    >>> # that what is returned is a reference to said parameter
    >>> out1 = np.array([0], dtype='d')
    >>> out2 = np.cos([0.1], out1)
    >>> out2 is out1
    True
    >>>
    >>> # Example of ValueError due to provision of shape mis-matched `out`
    >>> np.cos(np.zeros((3,3)),np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: operands could not be broadcast together with shapes (3,3) (2,2)

    """)

# 添加新的文档字符串给 'numpy._core.umath' 中的 'tanh' 函数
add_newdoc('numpy._core.umath', 'tanh',
    """
    Compute hyperbolic tangent element-wise.

    Equivalent to ``np.sinh(x)/np.cosh(x)`` or ``-1j * np.tan(1j*x)``.

    Parameters
    ----------
    x : array_like
        Input array.
    $PARAMS

    Returns
    -------
    y : ndarray
        The corresponding hyperbolic tangent values.
        $OUT_SCALAR_1

    Notes
    -----
    If `out` is provided, the function writes the result into it,
    and returns a reference to `out`.  (See Examples)

    References
    ----------
    .. [1] M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions.
           New York, NY: Dover, 1972, pg. 83.
           https://personal.math.ubc.ca/~cbm/aands/page_83.htm

    .. [2] Wikipedia, "Hyperbolic function",
           https://en.wikipedia.org/wiki/Hyperbolic_function

    Examples
    --------
    >>> np.tanh((0, np.pi*1j, np.pi*1j/2))
    array([ 0. +0.00000000e+00j,  0. -1.22460635e-16j,  0. +1.63317787e+16j])

    >>> # Example of providing the optional output parameter illustrating
    >>> # that what is returned is a reference to said parameter
    >>> out1 = np.array([0], dtype='d')
    >>> out2 = np.tanh([0.1], out1)
    >>> out2 is out1
    True

    >>> # Example of ValueError due to provision of shape mis-matched `out`
    >>> np.tanh(np.zeros((3,3)),np.zeros((2,2)))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: operands could not be broadcast together with shapes (3,3) (2,2)

    """)

# 添加新的文档字符串给 'numpy._core.umath' 中的 'frexp' 函数
add_newdoc('numpy._core.umath', 'frexp',
    """
    Decompose the elements of x into mantissa and twos exponent.
    
    """)
    Returns (`mantissa`, `exponent`), where ``x = mantissa * 2**exponent``.
    The mantissa lies in the open interval(-1, 1), while the twos
    exponent is a signed integer.

    Parameters
    ----------
    x : array_like
        Array of numbers to be decomposed.
    out1 : ndarray, optional
        Output array for the mantissa. Must have the same shape as `x`.
    out2 : ndarray, optional
        Output array for the exponent. Must have the same shape as `x`.
    $PARAMS

    Returns
    -------
    mantissa : ndarray
        Floating values between -1 and 1.
        $OUT_SCALAR_1
    exponent : ndarray
        Integer exponents of 2.
        $OUT_SCALAR_1

    See Also
    --------
    ldexp : Compute ``y = x1 * 2**x2``, the inverse of `frexp`.

    Notes
    -----
    Complex dtypes are not supported, they will raise a TypeError.

    Examples
    --------
    >>> x = np.arange(9)
    >>> y1, y2 = np.frexp(x)
    >>> y1
    array([ 0.   ,  0.5  ,  0.5  ,  0.75 ,  0.5  ,  0.625,  0.75 ,  0.875,
            0.5  ])
    >>> y2
    array([0, 1, 2, 2, 3, 3, 3, 3, 4])
    >>> y1 * 2**y2
    array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.])

    """
# 添加新的文档字符串给 'numpy._core.umath' 模块的 'ldexp' 函数
add_newdoc('numpy._core.umath', 'ldexp',
    """
    返回 x1 * 2**x2,逐元素计算。

    使用尾数 `x1` 和指数 `x2` 构造浮点数 ``x1 * 2**x2``。

    参数
    ----------
    x1 : array_like
        乘数数组。
    x2 : array_like, int
        指数数组。
        $BROADCASTABLE_2
    $PARAMS

    返回
    -------
    y : ndarray 或标量
        ``x1 * 2**x2`` 的结果。
        $OUT_SCALAR_2

    参见
    --------
    frexp : 从 ``x = y1 * 2**y2`` 返回 (y1, y2),是 `ldexp` 的逆操作。

    注意
    -----
    不支持复杂数数据类型,否则会引发 TypeError。

    `ldexp` 可以作为 `frexp` 的逆操作,如果单独使用,使用表达式 ``x1 * 2**x2`` 更加清晰。

    示例
    --------
    >>> np.ldexp(5, np.arange(4))
    array([ 5., 10., 20., 40.], dtype=float16)

    >>> x = np.arange(6)
    >>> np.ldexp(*np.frexp(x))
    array([ 0.,  1.,  2.,  3.,  4.,  5.])

    """)

# 添加新的文档字符串给 'numpy._core.umath' 模块的 'gcd' 函数
add_newdoc('numpy._core.umath', 'gcd',
    """
    返回 ``|x1|`` 和 ``|x2|`` 的最大公约数。

    参数
    ----------
    x1, x2 : array_like, int
        值的数组。
        $BROADCASTABLE_2

    返回
    -------
    y : ndarray 或标量
        输入绝对值的最大公约数。
        $OUT_SCALAR_2

    参见
    --------
    lcm : 最小公倍数

    示例
    --------
    >>> np.gcd(12, 20)
    4
    >>> np.gcd.reduce([15, 25, 35])
    5
    >>> np.gcd(np.arange(6), 20)
    array([20,  1,  2,  1,  4,  5])

    """)

# 添加新的文档字符串给 'numpy._core.umath' 模块的 'lcm' 函数
add_newdoc('numpy._core.umath', 'lcm',
    """
    返回 ``|x1|`` 和 ``|x2|`` 的最小公倍数。

    参数
    ----------
    x1, x2 : array_like, int
        值的数组。
        $BROADCASTABLE_2

    返回
    -------
    y : ndarray 或标量
        输入绝对值的最小公倍数。
        $OUT_SCALAR_2

    参见
    --------
    gcd : 最大公约数

    示例
    --------
    >>> np.lcm(12, 20)
    60
    >>> np.lcm.reduce([3, 12, 20])
    60
    >>> np.lcm.reduce([40, 12, 20])
    120
    >>> np.lcm(np.arange(6), 20)
    array([ 0, 20, 20, 60, 20, 20])

    """)

# 添加新的文档字符串给 'numpy._core.umath' 模块的 'bitwise_count' 函数
add_newdoc('numpy._core.umath', 'bitwise_count',
    """
    计算输入数组 ``x`` 绝对值中 1 的位数。
    类似于内置的 `int.bit_count` 或 C++ 中的 ``popcount``。

    参数
    ----------
    x : array_like, unsigned int
        输入数组。
    $PARAMS

    返回
    -------
    y : ndarray
        输入中 1 的位数。
        对所有整数类型返回 uint8
        $OUT_SCALAR_1

    参考
    ----------
    .. [1] https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel

    .. [2] Wikipedia, "Hamming weight",
           https://en.wikipedia.org/wiki/Hamming_weight


    """)
    .. [3] http://aggregate.ee.engr.uky.edu/MAGIC/#Population%20Count%20(Ones%20Count)

    Examples
    --------
    >>> np.bitwise_count(1023)
    # 对给定的整数 1023 进行位计数,返回其中包含的二进制位为 1 的个数,结果为 10
    10
    >>> a = np.array([2**i - 1 for i in range(16)])
    # 创建一个包含 16 个元素的 NumPy 数组 a,其中每个元素都是 2 的幂次减 1 的值
    >>> np.bitwise_count(a)
    # 对数组 a 中的每个元素进行位计数,返回包含每个元素二进制位为 1 的个数的数组,数据类型为 uint8
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
          dtype=uint8)

    """
# 给指定模块和函数添加新的文档字符串
add_newdoc('numpy._core.umath', 'str_len',
    """
    返回每个元素的长度。对于字节串,长度是以字节计算;对于Unicode串,是以Unicode代码点计算。

    Parameters
    ----------
    x : array_like
        输入数组,其元素类型为``StringDType``、``bytes_``或``str_``
        $PARAMS

    Returns
    -------
    y : ndarray
        整数类型的输出数组
        $OUT_SCALAR_1

    See Also
    --------
    len

    Examples
    --------
    >>> a = np.array(['Grace Hopper Conference', 'Open Source Day'])
    >>> np.strings.str_len(a)
    array([23, 15])
    >>> a = np.array(['\u0420', '\u043e'])
    >>> np.strings.str_len(a)
    array([1, 1])
    >>> a = np.array([['hello', 'world'], ['\u0420', '\u043e']])
    >>> np.strings.str_len(a)
    array([[5, 5], [1, 1]])

    """)

# 给指定模块和函数添加新的文档字符串
add_newdoc('numpy._core.umath', 'isalpha',
    """
    如果解释为字符串的数据中所有字符都是字母并且至少有一个字符,则为每个元素返回True,否则返回False。

    对于字节串(即``bytes``),字母字符是序列
    b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'中的字节值。
    对于Unicode串,字母字符是Unicode字符数据库中定义的“Letter”。

    Parameters
    ----------
    x : array_like
        输入数组,其元素类型为``StringDType``、``bytes_``或``str_``
        $PARAMS

    Returns
    -------
    y : ndarray
        布尔类型的输出数组
        $OUT_SCALAR_1

    See Also
    --------
    str.isalpha

    """)

# 给指定模块和函数添加新的文档字符串
add_newdoc('numpy._core.umath', 'isdigit',
    """
    如果字符串中所有字符都是数字并且至少有一个字符,则为每个元素返回True,否则返回False。

    对于字节串,数字是序列
    b'0123456789'中的字节值。
    对于Unicode串,数字包括十进制字符和需要特殊处理的数字,如兼容上标数字。
    这也包括不能用于十进制数的数字,如Kharosthi数字。

    Parameters
    ----------
    x : array_like
        输入数组,其元素类型为``StringDType``、``bytes_``或``str_``
        $PARAMS

    Returns
    -------
    y : ndarray
        布尔类型的输出数组
        $OUT_SCALAR_1

    See Also
    --------
    str.isdigit

    Examples
    --------
    >>> a = np.array(['a', 'b', '0'])
    >>> np.strings.isdigit(a)
    array([False, False,  True])
    >>> a = np.array([['a', 'b', '0'], ['c', '1', '2']])
    >>> np.strings.isdigit(a)
    array([[False, False,  True], [False,  True,  True]])

    """)

# 给指定模块和函数添加新的文档字符串
add_newdoc('numpy._core.umath', 'isspace',
    r"""
    如果字符串中只有空白字符并且至少有一个字符,则为每个元素返回True,否则返回False。

    对于字节串,空白字符是序列
    b' \t\n\r\x0b\f'中的字符。
    对于Unicode串,字符是
    whitespace, if, in the Unicode character database, its general
    category is Zs (“Separator, space”), or its bidirectional class
    is one of WS, B, or S.


# 检查字符是否是空白字符,根据 Unicode 字符数据库的定义,如果其一般类别为 Zs(“分隔符,空格”),或其双向类别为 WS、B 或 S 中的一种。



    Parameters
    ----------
    x : array_like, with ``StringDType``, ``bytes_``, or ``str_`` dtype


# 参数
# ------
# x : array_like
#     输入数组,元素类型可以是 ``StringDType``、``bytes_`` 或 ``str_``。



    $PARAMS


# $PARAMS
# (未提供足够的上下文,可能是占位符或参数的具体描述)



    Returns
    -------
    y : ndarray
        Output array of bools
        $OUT_SCALAR_1


# 返回
# ------
# y : ndarray
#     布尔类型的输出数组。
#     $OUT_SCALAR_1
# (未提供足够的上下文,可能是占位符或返回值的具体描述)



    See Also
    --------
    str.isspace


# 参见
# ------
# str.isspace
# (指向相关的字符串方法,用于检查字符串是否只包含空白字符)



    """)




# """
# (多余的字符串结尾标记,可能是输入文档中的错误)
# 向 numpy._core.umath 模块添加新文档,定义 isalnum 函数
add_newdoc('numpy._core.umath', 'isalnum',
    """
    Returns true for each element if all characters in the string are
    alphanumeric and there is at least one character, false otherwise.

    Parameters
    ----------
    x : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings.
        $PARAMS

    Returns
    -------
    out : ndarray
        Output array of bools
        $OUT_SCALAR_1

    See Also
    --------
    str.isalnum

    Examples
    --------
    >>> a = np.array(['a', '1', 'a1', '(', ''])
    >>> np.strings.isalnum(a)
    array([ True,  True,  True, False, False])
    
    """)

# 向 numpy._core.umath 模块添加新文档,定义 islower 函数
add_newdoc('numpy._core.umath', 'islower',
    """
    Returns true for each element if all cased characters in the
    string are lowercase and there is at least one cased character,
    false otherwise.

    Parameters
    ----------
    x : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings.
        $PARAMS

    Returns
    -------
    out : ndarray
        Output array of bools
        $OUT_SCALAR_1

    See Also
    --------
    str.islower

    Examples
    --------
    >>> np.strings.islower("GHC")
    array(False)
    >>> np.strings.islower("ghc")
    array(True)

    """)

# 向 numpy._core.umath 模块添加新文档,定义 isupper 函数
add_newdoc('numpy._core.umath', 'isupper',
    """
    Return true for each element if all cased characters in the
    string are uppercase and there is at least one character, false
    otherwise.

    Parameters
    ----------
    x : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings.
        $PARAMS

    Returns
    -------
    out : ndarray
        Output array of bools
        $OUT_SCALAR_1

    See Also
    --------
    str.isupper

    Examples
    --------
    >>> np.strings.isupper("GHC")
    array(True)     
    >>> a = np.array(["hello", "HELLO", "Hello"])
    >>> np.strings.isupper(a)
    array([False,  True, False]) 

    """)

# 向 numpy._core.umath 模块添加新文档,定义 istitle 函数
add_newdoc('numpy._core.umath', 'istitle',
    """
    Returns true for each element if the element is a titlecased
    string and there is at least one character, false otherwise.

    Parameters
    ----------
    x : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings.
        $PARAMS

    Returns
    -------
    out : ndarray
        Output array of bools
        $OUT_SCALAR_1

    See Also
    --------
    str.istitle

    Examples
    --------
    >>> np.strings.istitle("Numpy Is Great")
    array(True)

    >>> np.strings.istitle("Numpy is great")
    array(False)
    
    """)

# 向 numpy._core.umath 模块添加新文档,定义 isdecimal 函数
add_newdoc('numpy._core.umath', 'isdecimal',
    """
    For each element, return True if there are only decimal
    characters in the element.

    Decimal characters include digit characters, and all characters
    that can be used to form decimal-radix numbers,
    e.g. ``U+0660, ARABIC-INDIC DIGIT ZERO``.

    Parameters
    ----------
    x : array_like, with ``StringDType`` or ``str_`` dtype
        Input array of strings.
        $PARAMS

    Returns
    -------
    y : ndarray
        Output array of bools
        $OUT_SCALAR_1

    See Also
    --------

    """)
    str.isdecimal



    # 返回一个布尔值,指示字符串是否只包含十进制字符
    str.isdecimal



    Examples
    --------
    >>> np.strings.isdecimal(['12345', '4.99', '123ABC', ''])
    array([ True, False, False, False])

    """



    # 示例用法:使用 np.strings.isdecimal() 函数检查字符串数组中每个字符串是否只包含十进制字符
    Examples
    --------
    >>> np.strings.isdecimal(['12345', '4.99', '123ABC', ''])
    array([ True, False, False, False])

    """
# 添加新的文档字符串到 numpy._core.umath 模块中的 isnumeric 函数
add_newdoc('numpy._core.umath', 'isnumeric',
    """
    对于每个元素,如果元素中仅包含数字字符,则返回 True。

    数字字符包括数字字符本身,以及具有 Unicode 数字值属性的所有字符,
    例如 ``U+2155, VULGAR FRACTION ONE FIFTH``。

    Parameters
    ----------
    x : array_like,具有 ``StringDType`` 或 ``str_`` dtype
    $PARAMS

    Returns
    -------
    y : ndarray
        布尔类型的输出数组
        $OUT_SCALAR_1

    See Also
    --------
    str.isnumeric

    Examples
    --------
    >>> np.strings.isnumeric(['123', '123abc', '9.0', '1/4', 'VIII'])
    array([ True, False, False, False, False])

    """)

# 添加新的文档字符串到 numpy._core.umath 模块中的 find 函数
add_newdoc('numpy._core.umath', 'find',
    """
    对于每个元素,在字符串中返回子字符串 `x2` 第一次出现的最低索引,
    使得 `x2` 包含在范围 [`x3`, `x4`] 中。

    Parameters
    ----------
    x1 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype

    x2 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype

    x3 : array_like,具有 ``int_`` dtype

    x4 : array_like,具有 ``int_`` dtype
        $PARAMS

    `x3` 和 `x4` 被解释为切片表示法。

    Returns
    -------
    y : ndarray
        整数类型的输出数组
        $OUT_SCALAR_2

    See Also
    --------
    str.find

    Examples
    --------
    >>> a = np.array(["NumPy is a Python library"])
    >>> np.strings.find(a, "Python", 0, None)
    array([11])

    """)

# 添加新的文档字符串到 numpy._core.umath 模块中的 rfind 函数
add_newdoc('numpy._core.umath', 'rfind',
    """
    对于每个元素,在字符串中返回子字符串 `x2` 最后一次出现的最高索引,
    使得 `x2` 包含在范围 [`x3`, `x4`] 中。

    Parameters
    ----------
    x1 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype

    x2 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype

    x3 : array_like,具有 ``int_`` dtype

    x4 : array_like,具有 ``int_`` dtype
        $PARAMS

    `x3` 和 `x4` 被解释为切片表示法。

    Returns
    -------
    y : ndarray
        整数类型的输出数组
        $OUT_SCALAR_2

    See Also
    --------
    str.rfind

    """)

# 添加新的文档字符串到 numpy._core.umath 模块中的 count 函数
add_newdoc('numpy._core.umath', 'count',
    """
    返回数组中子字符串 `x2` 在范围 [`x3`, `x4`] 中的非重叠出现次数。

    Parameters
    ----------
    x1 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype

    x2 : array-like,具有 ``StringDType``,``bytes_`` 或 ``str_`` dtype
       要搜索的子字符串。

    x3 : array_like,具有 ``int_`` dtype

    x4 : array_like,具有 ``int_`` dtype
        $PARAMS

    `x3` 和 `x4` 被解释为切片表示法。

    Returns
    -------
    y : ndarray
        整数类型的输出数组
        $OUT_SCALAR_2

    See Also
    --------
    str.count

    Examples
    --------
    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
    >>> c
    """)
    # 创建一个包含字符串数组的 NumPy 数组,每个字符串最长为 7 个字符
    array(['aAaAaA', '  aA  ', 'abBABba'], dtype='<U7')
    # 使用 np.strings.count 函数统计每个字符串中出现 'A' 的次数
    >>> np.strings.count(c, 'A')
    # 返回一个包含每个字符串中 'A' 的出现次数的 NumPy 数组
    array([3, 1, 1])
    # 使用 np.strings.count 函数统计每个字符串中出现 'aA' 的次数(大小写敏感)
    >>> np.strings.count(c, 'aA')
    # 返回一个包含每个字符串中 'aA' 的出现次数的 NumPy 数组
    array([3, 1, 0])
    # 使用 np.strings.count 函数统计每个字符串中在指定范围内(从 start 到 end-1)出现 'A' 的次数
    >>> np.strings.count(c, 'A', start=1, end=4)
    # 返回一个包含每个字符串在指定范围内出现 'A' 的次数的 NumPy 数组
    array([2, 1, 1])
    # 使用 np.strings.count 函数统计每个字符串中在指定范围内(从 start 到 end-1)出现 'A' 的次数
    >>> np.strings.count(c, 'A', start=1, end=3)
    # 返回一个包含每个字符串在指定范围内出现 'A' 的次数的 NumPy 数组
    array([1, 0, 0])
# 将新文档添加到numpy._core.umath模块中的index函数
add_newdoc('numpy._core.umath', 'index',
    """
    类似于`find`,但在子字符串未找到时引发ValueError异常。

    Parameters
    ----------
    x1 : array_like,具有`StringDType`,`bytes_`或`unicode_` dtype

    x2 : array_like,具有`StringDType`,`bytes_`或`unicode_` dtype

    x3, x4 : array_like,具有任何整数dtype
        要查找的范围,按切片表示法解释。
        $PARAMS

    Returns
    -------
    out : ndarray
        输出整数数组。如果未找到`x2`,则引发ValueError异常。
        $OUT_SCALAR_2

    See Also
    --------
    find, str.find

    Examples
    --------
    >>> a = np.array(["Computer Science"])
    >>> np.strings.index(a, "Science")
    array([9])

    """)

# 将新文档添加到numpy._core.umath模块中的rindex函数
add_newdoc('numpy._core.umath', 'rindex',
    """
    类似于`rfind`,但在子字符串未找到时引发ValueError异常。

    Parameters
    ----------
    x1 : array_like,具有`StringDType`,`bytes_`或`unicode_` dtype

    x2 : array_like,具有`StringDType`,`bytes_`或`unicode_` dtype

    x3, x4 : array_like,具有任何整数dtype
        要查找的范围,按切片表示法解释。
        $PARAMS

    Returns
    -------
    out : ndarray
        输出整数数组。如果未找到`x2`,则引发ValueError异常。
        $OUT_SCALAR_2

    See Also
    --------
    rfind, str.rfind

    Examples
    --------
    >>> a = np.array(["Computer Science"])
    >>> np.strings.rindex(a, "Science")
    array([9])

    """)

# 将新文档添加到numpy._core.umath模块中的_replace函数
add_newdoc('numpy._core.umath', '_replace',
    """
    `replace`的ufunc实现。此内部函数由带有设置`out`的`replace`调用,
    以便知道结果字符串缓冲区的大小。
    """)

# 将新文档添加到numpy._core.umath模块中的startswith函数
add_newdoc('numpy._core.umath', 'startswith',
    """
    返回布尔数组,其中在`x1`中的字符串元素以`x2`开头时为`True`,否则为`False`。

    Parameters
    ----------
    x1 : array-like,具有`StringDType`,`bytes_`或`str_` dtype

    x2 : array-like,具有`StringDType`,`bytes_`或`str_` dtype

    x3 : array_like,具有`int_` dtype

    x4 : array_like,具有`int_` dtype
        $PARAMS
        使用`x3`,从该位置开始比较。使用`x4`,在该位置停止比较。

    Returns
    -------
    out : ndarray
        输出布尔数组
        $OUT_SCALAR_2

    See Also
    --------
    str.startswith

    """)

# 将新文档添加到numpy._core.umath模块中的endswith函数
add_newdoc('numpy._core.umath', 'endswith',
    """
    返回布尔数组,其中在`x1`中的字符串元素以`x2`结尾时为`True`,否则为`False`。

    Parameters
    ----------
    x1 : array-like,具有`StringDType`,`bytes_`或`str_` dtype

    x2 : array-like,具有`StringDType`,`bytes_`或`str_` dtype

    x3 : array_like,具有`int_` dtype
    x4 : array_like, with ``int_`` dtype
        # 参数 x4:数组类型,要求为整数类型
        # $PARAMS
        # 与 x3 一起使用时,从该位置开始测试。与 x4 一起使用时,
        # 在该位置停止比较。

    Returns
    -------
    out : ndarray
        # 返回值:布尔数组
        # $OUT_SCALAR_2

    See Also
    --------
    str.endswith
        # 参见:str.endswith 函数

    Examples
    --------
    >>> s = np.array(['foo', 'bar'])
    >>> s
    array(['foo', 'bar'], dtype='<U3')
    >>> np.strings.endswith(s, 'ar')
    array([False,  True])
    >>> np.strings.endswith(s, 'a', start=1, end=2)
    array([False,  True])

    """
# 添加新文档到 'numpy._core.umath' 模块中的 '_strip_chars' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_strip_chars', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_lstrip_chars' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_lstrip_chars', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_rstrip_chars' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_rstrip_chars', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_strip_whitespace' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_strip_whitespace', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_lstrip_whitespace' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_lstrip_whitespace', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_rstrip_whitespace' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_rstrip_whitespace', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_expandtabs_length' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_expandtabs_length', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_expandtabs' 函数,文档内容为空字符串
add_newdoc('numpy._core.umath', '_expandtabs', '')

# 添加新文档到 'numpy._core.umath' 模块中的 '_center' 函数,提供详细的文档说明
add_newdoc('numpy._core.umath', '_center',
    """
    Return a copy of `x1` with its elements centered in a string of
    length `x2`.

    Parameters
    ----------
    x1 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings to be centered.
    x2 : array_like, with any integer dtype
        The length of the resulting strings, unless `width < str_len(a)`.
    x3 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        The padding character to use.

    Returns
    -------
    out : ndarray
        Output array of ``StringDType``, ``bytes_`` or ``str_`` dtype,
        depending on input types.

    See Also
    --------
    str.center : Equivalent Python built-in method.

    Examples
    --------
    >>> c = np.array(['a1b2','1b2a','b2a1','2a1b'])
    >>> np.strings.center(c, width=9)
    array(['   a1b2  ', '   1b2a  ', '   b2a1  ', '   2a1b  '], dtype='<U9')
    >>> np.strings.center(c, width=9, fillchar='*')
    array(['***a1b2**', '***1b2a**', '***b2a1**', '***2a1b**'], dtype='<U9')
    >>> np.strings.center(c, width=1)
    array(['a1b2', '1b2a', 'b2a1', '2a1b'], dtype='<U4')
    """
)

# 添加新文档到 'numpy._core.umath' 模块中的 '_ljust' 函数,提供详细的文档说明
add_newdoc('numpy._core.umath', '_ljust',
    """
    Return an array with the elements of `x1` left-justified in a
    string of length `x2`.

    Parameters
    ----------
    x1 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings to be left-justified.
    x2 : array_like, with any integer dtype
        The length of the resulting strings, unless `width < str_len(a)`.
    x3 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        The padding character to use.

    Returns
    -------
    out : ndarray
        Output array of ``StringDType``, ``bytes_`` or ``str_`` dtype,
        depending on input type.

    See Also
    --------
    str.ljust : Equivalent Python built-in method.

    Examples
    --------
    >>> c = np.array(['aAaAaA', '  aA  ', 'abBABba'])
    >>> np.strings.ljust(c, width=3)
    array(['aAaAaA', '  aA  ', 'abBABba'], dtype='<U7')
    >>> np.strings.ljust(c, width=9)
    array(['aAaAaA   ', '  aA     ', 'abBABba  '], dtype='<U9')
    """
)

# 添加新文档到 'numpy._core.umath' 模块中的 '_rjust' 函数,提供详细的文档说明
add_newdoc('numpy._core.umath', '_rjust',
    """
    Return an array with the elements of `x1` right-justified in a
    string of length `x2`.

    Parameters
    ----------
    x1 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        Input array of strings to be right-justified.
    x2 : array_like, with any integer dtype
        The length of the resulting strings, unless `width < str_len(a)`.

    Returns
    -------
    out : ndarray
        Output array of ``StringDType``, ``bytes_`` or ``str_`` dtype,
        depending on input type.
    """
)
    x3 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        The padding character to use.
        $PARAMS

    Returns
    -------
    out : ndarray
        Output array of ``StringDType``, ``bytes_`` or ``str_`` dtype,
        depending on input type
        $OUT_SCALAR_2

    See Also
    --------
    str.rjust

    Examples
    --------
    >>> a = np.array(['aAaAaA', '  aA  ', 'abBABba'])
    >>> np.strings.rjust(a, width=3)
    array(['aAaAaA', '  aA  ', 'abBABba'], dtype='<U7')
    >>> np.strings.rjust(a, width=9)
    array(['   aAaAaA', '     aA  ', '  abBABba'], dtype='<U9')


注释:


# x3参数:array_like,其元素可以是StringDType、bytes_或str_类型的数组
# 使用的填充字符
# $PARAMS

# 返回值
# -------
# out : ndarray
#     输出的ndarray数组,其元素类型为StringDType、bytes_或str_,取决于输入类型
# $OUT_SCALAR_2

# 参见
# --------
# str.rjust

# 示例
# --------
# 创建一个包含字符串的numpy数组a
# >>> a = np.array(['aAaAaA', '  aA  ', 'abBABba'])
# 对数组a中的每个字符串右对齐,宽度为3
# >>> np.strings.rjust(a, width=3)
# 返回一个数组,包含右对齐后的结果,元素类型为'<U7'
# array(['aAaAaA', '  aA  ', 'abBABba'], dtype='<U7')
# 对数组a中的每个字符串右对齐,宽度为9
# >>> np.strings.rjust(a, width=9)
# 返回一个数组,包含右对齐后的结果,元素类型为'<U9'
# array(['   aAaAaA', '     aA  ', '  abBABba'], dtype='<U9')
# 将新文档添加到numpy._core.umath模块中,函数名为'_zfill'
add_newdoc('numpy._core.umath', '_zfill',
    """
    Return the numeric string left-filled with zeros. A leading
    sign prefix (``+``/``-``) is handled by inserting the padding
    after the sign character rather than before.

    Parameters
    ----------
    x1 : array_like, with ``StringDType``, ``bytes_`` or ``str_`` dtype
        输入数组,可以是``StringDType``、``bytes_``或``str_``类型

    x2 : array_like, with any integer dtype
        要在`x1`中的元素左侧填充的字符串宽度
        $PARAMS

    Returns
    -------
    out : ndarray
        输出数组,类型为``StringDType``、``bytes_``或``str_``,取决于输入类型
        $OUT_SCALAR_2

    See Also
    --------
    str.zfill

    Examples
    --------
    >>> np.strings.zfill(['1', '-1', '+1'], 3)
    array(['001', '-01', '+01'], dtype='<U3')

    """)

# 将新文档添加到numpy._core.umath模块中,函数名为'_partition_index'
add_newdoc('numpy._core.umath', '_partition_index',
    """
    Partition each element in ``x1`` around ``x2``, at precomputed
    index ``x3``.

    For each element in ``x1``, split the element at the first
    occurrence of ``x2`` at location ``x3``, and return a 3-tuple
    containing the part before the separator, the separator itself,
    and the part after the separator. If the separator is not found,
    the first item of the tuple will contain the whole string, and
    the second and third ones will be the empty string.

    Parameters
    ----------
    x1 : array-like, with ``bytes_``, or ``str_`` dtype
        输入数组

    x2 : array-like, with ``bytes_``, or ``str_`` dtype
        用于在``x1``中的每个字符串元素周围分割的分隔符

    x3 : array-like, with any integer dtype
        分隔符的预先计算索引(<0表示分隔符不存在)

    Returns
    -------
    out : 3-tuple:
        - 包含分隔符之前部分的``bytes_``或``str_`` dtype数组
        - 包含分隔符的``bytes_``或``str_`` dtype数组
        - 包含分隔符之后部分的``bytes_``或``str_`` dtype数组

    See Also
    --------
    str.partition

    Examples
    --------
    此ufunc最容易通过``np.strings.partition``使用,在计算索引后调用它:

    >>> x = np.array(["Numpy is nice!"])
    >>> np.strings.partition(x, " ")
    (array(['Numpy'], dtype='<U5'),
     array([' '], dtype='<U1'),
     array(['is nice!'], dtype='<U8'))

    """)

# 将新文档添加到numpy._core.umath模块中,函数名为'_rpartition_index'
add_newdoc('numpy._core.umath', '_rpartition_index',
    """
    Partition each element in ``x1`` around the right-most separator,
    ``x2``, at precomputed index ``x3``.

    For each element in ``x1``, split the element at the last
    occurrence of ``x2`` at location ``x3``, and return a 3-tuple
    containing the part before the separator, the separator itself,
    and the part after the separator. If the separator is not found,
    the third item of the tuple will contain the whole string, and
    the first and second ones will be the empty string.

    Parameters
    ----------
    x1 : array-like, with ``bytes_``, or ``str_`` dtype
        输入数组

    x2 : array-like, with ``bytes_``, or ``str_`` dtype
        最右边分隔符,用于在``x1``中的每个元素周围分割

    x3 : array-like, with any integer dtype
        分隔符的预先计算索引(<0表示分隔符不存在)

    Returns
    -------
    out : 3-tuple:
        - 包含分隔符之前部分的``bytes_``或``str_`` dtype数组
        - 包含分隔符的``bytes_``或``str_`` dtype数组
        - 包含分隔符之后部分的``bytes_``或``str_`` dtype数组

    """)
    x1 : array-like, with ``bytes_``, or ``str_`` dtype
        输入数组,可以是具有 ``bytes_`` 或 ``str_`` 数据类型的数组
    x2 : array-like, with ``bytes_``, or ``str_`` dtype
        用于分割 ``x1`` 中每个字符串元素的分隔符数组
    x3 : array-like, with any integer dtype
        分隔符的索引数组(<0 表示分隔符不存在)

    Returns
    -------
    out : 3-tuple:
        返回一个包含三个元素的元组:
        - 具有 ``bytes_`` 或 ``str_`` 数据类型的数组,包含分隔符之前的部分
        - 具有 ``bytes_`` 或 ``str_`` 数据类型的数组,包含分隔符本身
        - 具有 ``bytes_`` 或 ``str_`` 数据类型的数组,包含分隔符之后的部分

    See Also
    --------
    str.rpartition
        参考 Python 字符串方法 rpartition 的用法

    Examples
    --------
    通过 ``np.strings.rpartition`` 最方便地使用这个函数,它在计算索引后会调用这个函数:

    >>> a = np.array(['aAaAaA', '  aA  ', 'abBABba'])
    >>> np.strings.rpartition(a, 'A')
    (array(['aAaAa', '  a', 'abB'], dtype='<U5'),
     array(['A', 'A', 'A'], dtype='<U1'),
     array(['', '  ', 'Bba'], dtype='<U3'))

    """
# 将新的文档添加到指定的 NumPy 模块和函数
add_newdoc('numpy._core.umath', '_partition',
    """
    Partition each element in ``x1`` around ``x2``.
    
    For each element in ``x1``, split the element at the first
    occurrence of ``x2`` and return a 3-tuple containing the part before
    the separator, the separator itself, and the part after the
    separator. If the separator is not found, the first item of the
    tuple will contain the whole string, and the second and third ones
    will be the empty string.
    
    Parameters
    ----------
    x1 : array-like, with ``StringDType`` dtype
        Input array
    x2 : array-like, with ``StringDType`` dtype
        Separator to split each string element in ``x1``.
    
    Returns
    -------
    out : 3-tuple:
        - ``StringDType`` array with the part before the separator
        - ``StringDType`` array with the separator
        - ``StringDType`` array with the part after the separator
    
    See Also
    --------
    str.partition
    
    Examples
    --------
    The ufunc is used most easily via ``np.strings.partition``,
    which calls it under the hood::
    
    >>> x = np.array(["Numpy is nice!"], dtype="T")
    >>> np.strings.partition(x, " ")
    (array(['Numpy'], dtype=StringDType()),
     array([' '], dtype=StringDType()),
     array(['is nice!'], dtype=StringDType()))
    
    """)

# 将新的文档添加到指定的 NumPy 模块和函数
add_newdoc('numpy._core.umath', '_rpartition',
    """
    Partition each element in ``x1`` around the right-most separator,
    ``x2``.
    
    For each element in ``x1``, split the element at the last
    occurrence of ``x2`` at location ``x3``, and return a 3-tuple
    containing the part before the separator, the separator itself,
    and the part after the separator. If the separator is not found,
    the third item of the tuple will contain the whole string, and
    the first and second ones will be the empty string.
    
    Parameters
    ----------
    x1 : array-like, with ``StringDType`` dtype
        Input array
    x2 : array-like, with ``StringDType`` dtype
        Separator to split each string element in ``x1``.
    
    Returns
    -------
    out : 3-tuple:
        - ``StringDType`` array with the part before the separator
        - ``StringDType`` array with the separator
        - ``StringDType`` array with the part after the separator
    
    See Also
    --------
    str.rpartition
    
    Examples
    --------
    The ufunc is used most easily via ``np.strings.rpartition``,
    which calls it after calculating the indices::
    
    >>> a = np.array(['aAaAaA', '  aA  ', 'abBABba'], dtype="T")
    >>> np.strings.rpartition(a, 'A')
    (array(['aAaAa', '  a', 'abB'], dtype=StringDType()),
     array(['A', 'A', 'A'], dtype=StringDType()),
     array(['', '  ', 'Bba'], dtype=StringDType()))
    
    """)