scipy API Reference

Full documentation for scipy (1.14.0)

scipy.LowLevelCallable
Python Library Documentation: class LowLevelCallable in module scipy._lib._ccallback

class LowLevelCallable(builtins.tuple)
 |  LowLevelCallable(function, user_data=None, signature=None)
 |
 |  Low-level callback function.
 |
 |  Some functions in SciPy take as arguments callback functions, which
 |  can either be python callables or low-level compiled functions. Using
 |  compiled callback functions can improve performance somewhat by
 |  avoiding wrapping data in Python objects.
 |
 |  Such low-level functions in SciPy are wrapped in `LowLevelCallable`
 |  objects, which can be constructed from function pointers obtained from
 |  ctypes, cffi, Cython, or contained in Python `PyCapsule` objects.
 |
 |  .. seealso::
 |
 |     Functions accepting low-level callables:
 |
 |     `scipy.integrate.quad`, `scipy.ndimage.generic_filter`,
 |     `scipy.ndimage.generic_filter1d`, `scipy.ndimage.geometric_transform`
 |
 |     Usage examples:
 |
 |     :ref:`ndimage-ccallbacks`, :ref:`quad-callbacks`
 |
 |  Parameters
 |  ----------
 |  function : {PyCapsule, ctypes function pointer, cffi function pointer}
 |      Low-level callback function.
 |  user_data : {PyCapsule, ctypes void pointer, cffi void pointer}
 |      User data to pass on to the callback function.
 |  signature : str, optional
 |      Signature of the function. If omitted, determined from *function*,
 |      if possible.
 |
 |  Attributes
 |  ----------
 |  function
 |      Callback function given.
 |  user_data
 |      User data given.
 |  signature
 |      Signature of the function.
 |
 |  Methods
 |  -------
 |  from_cython
 |      Class method for constructing callables from Cython C-exported
 |      functions.
 |
 |  Notes
 |  -----
 |  The argument ``function`` can be one of:
 |
 |  - PyCapsule, whose name contains the C function signature
 |  - ctypes function pointer
 |  - cffi function pointer
 |
 |  The signature of the low-level callback must match one of those expected
 |  by the routine it is passed to.
 |
 |  If constructing low-level functions from a PyCapsule, the name of the
 |  capsule must be the corresponding signature, in the format::
 |
 |      return_type (arg1_type, arg2_type, ...)
 |
 |  For example::
 |
 |      "void (double)"
 |      "double (double, int *, void *)"
 |
 |  The context of a PyCapsule passed in as ``function`` is used as ``user_data``,
 |  if an explicit value for ``user_data`` was not given.
 |
 |  Method resolution order:
 |      LowLevelCallable
 |      builtins.tuple
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __getitem__(self, idx)
 |      Return self[key].
 |
 |  __repr__(self)
 |      Return repr(self).
 |
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |
 |  from_cython(module, name, user_data=None, signature=None)
 |      Create a low-level callback function from an exported Cython function.
 |
 |      Parameters
 |      ----------
 |      module : module
 |          Cython module where the exported function resides
 |      name : str
 |          Name of the exported function
 |      user_data : {PyCapsule, ctypes void pointer, cffi void pointer}, optional
 |          User data to pass on to the callback function.
 |      signature : str, optional
 |          Signature of the function. If omitted, determined from *function*.
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(cls, function, user_data=None, signature=None)
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Readonly properties defined here:
 |
 |  function
 |
 |  signature
 |
 |  user_data
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from builtins.tuple:
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __contains__(self, key, /)
 |      Return bool(key in self).
 |
 |  __eq__(self, value, /)
 |      Return self==value.
 |
 |  __ge__(self, value, /)
 |      Return self>=value.
 |
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |
 |  __getnewargs__(self, /)
 |
 |  __gt__(self, value, /)
 |      Return self>value.
 |
 |  __hash__(self, /)
 |      Return hash(self).
 |
 |  __iter__(self, /)
 |      Implement iter(self).
 |
 |  __le__(self, value, /)
 |      Return self<=value.
 |
 |  __len__(self, /)
 |      Return len(self).
 |
 |  __lt__(self, value, /)
 |      Return self<value.
 |
 |  __mul__(self, value, /)
 |      Return self*value.
 |
 |  __ne__(self, value, /)
 |      Return self!=value.
 |
 |  __rmul__(self, value, /)
 |      Return value*self.
 |
 |  count(self, value, /)
 |      Return number of occurrences of value.
 |
 |  index(self, value, start=0, stop=9223372036854775807, /)
 |      Return first index of value.
 |
 |      Raises ValueError if the value is not present.
 |
 |  ----------------------------------------------------------------------
 |  Class methods inherited from builtins.tuple:
 |
 |  __class_getitem__(...)
 |      See PEP 585
scipy.cluster
Python Library Documentation: package scipy.cluster in scipy

NAME
    scipy.cluster

DESCRIPTION
    =========================================
    Clustering package (:mod:`scipy.cluster`)
    =========================================

    .. currentmodule:: scipy.cluster

    .. toctree::
       :hidden:

       cluster.vq
       cluster.hierarchy

    Clustering algorithms are useful in information theory, target detection,
    communications, compression, and other areas. The `vq` module only
    supports vector quantization and the k-means algorithms.

    The `hierarchy` module provides functions for hierarchical and
    agglomerative clustering.  Its features include generating hierarchical
    clusters from distance matrices,
    calculating statistics on clusters, cutting linkages
    to generate flat clusters, and visualizing clusters with dendrograms.

PACKAGE CONTENTS
    _hierarchy
    _optimal_leaf_ordering
    _vq
    hierarchy
    tests (package)
    vq

DATA
    __all__ = ['vq', 'hierarchy']

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\cluster\__init__.py

scipy.constants
Python Library Documentation: package scipy.constants in scipy

NAME
    scipy.constants

DESCRIPTION
    ==================================
    Constants (:mod:`scipy.constants`)
    ==================================

    .. currentmodule:: scipy.constants

    Physical and mathematical constants and units.


    Mathematical constants
    ======================

    ================  =================================================================
    ``pi``            Pi
    ``golden``        Golden ratio
    ``golden_ratio``  Golden ratio
    ================  =================================================================


    Physical constants
    ==================

    ===========================  =================================================================
    ``c``                        speed of light in vacuum
    ``speed_of_light``           speed of light in vacuum
    ``mu_0``                     the magnetic constant :math:`\mu_0`
    ``epsilon_0``                the electric constant (vacuum permittivity), :math:`\epsilon_0`
    ``h``                        the Planck constant :math:`h`
    ``Planck``                   the Planck constant :math:`h`
    ``hbar``                     :math:`\hbar = h/(2\pi)`
    ``G``                        Newtonian constant of gravitation
    ``gravitational_constant``   Newtonian constant of gravitation
    ``g``                        standard acceleration of gravity
    ``e``                        elementary charge
    ``elementary_charge``        elementary charge
    ``R``                        molar gas constant
    ``gas_constant``             molar gas constant
    ``alpha``                    fine-structure constant
    ``fine_structure``           fine-structure constant
    ``N_A``                      Avogadro constant
    ``Avogadro``                 Avogadro constant
    ``k``                        Boltzmann constant
    ``Boltzmann``                Boltzmann constant
    ``sigma``                    Stefan-Boltzmann constant :math:`\sigma`
    ``Stefan_Boltzmann``         Stefan-Boltzmann constant :math:`\sigma`
    ``Wien``                     Wien displacement law constant
    ``Rydberg``                  Rydberg constant
    ``m_e``                      electron mass
    ``electron_mass``            electron mass
    ``m_p``                      proton mass
    ``proton_mass``              proton mass
    ``m_n``                      neutron mass
    ``neutron_mass``             neutron mass
    ===========================  =================================================================


    Constants database
    ------------------

    In addition to the above variables, :mod:`scipy.constants` also contains the
    2018 CODATA recommended values [CODATA2018]_ database containing more physical
    constants.

    .. autosummary::
       :toctree: generated/

       value      -- Value in physical_constants indexed by key
       unit       -- Unit in physical_constants indexed by key
       precision  -- Relative precision in physical_constants indexed by key
       find       -- Return list of physical_constant keys with a given string
       ConstantWarning -- Constant sought not in newest CODATA data set

    .. data:: physical_constants

       Dictionary of physical constants, of the format
       ``physical_constants[name] = (value, unit, uncertainty)``.

    Available constants:

    ======================================================================  ====
    ``alpha particle mass``                                                 6.6446573357e-27 kg
    ``alpha particle mass energy equivalent``                               5.9719201914e-10 J
    ``alpha particle mass energy equivalent in MeV``                        3727.3794066 MeV
    ``alpha particle mass in u``                                            4.001506179127 u
    ``alpha particle molar mass``                                           0.0040015061777 kg mol^-1
    ``alpha particle relative atomic mass``                                 4.001506179127
    ``alpha particle-electron mass ratio``                                  7294.29954142
    ``alpha particle-proton mass ratio``                                    3.97259969009
    ``Angstrom star``                                                       1.00001495e-10 m
    ``atomic mass constant``                                                1.6605390666e-27 kg
    ``atomic mass constant energy equivalent``                              1.4924180856e-10 J
    ``atomic mass constant energy equivalent in MeV``                       931.49410242 MeV
    ``atomic mass unit-electron volt relationship``                         931494102.42 eV
    ``atomic mass unit-hartree relationship``                               34231776.874 E_h
    ``atomic mass unit-hertz relationship``                                 2.25234271871e+23 Hz
    ``atomic mass unit-inverse meter relationship``                         751300661040000.0 m^-1
    ``atomic mass unit-joule relationship``                                 1.4924180856e-10 J
    ``atomic mass unit-kelvin relationship``                                10809540191600.0 K
    ``atomic mass unit-kilogram relationship``                              1.6605390666e-27 kg
    ``atomic unit of 1st hyperpolarizability``                              3.2063613061e-53 C^3 m^3 J^-2
    ``atomic unit of 2nd hyperpolarizability``                              6.2353799905e-65 C^4 m^4 J^-3
    ``atomic unit of action``                                               1.054571817e-34 J s
    ``atomic unit of charge``                                               1.602176634e-19 C
    ``atomic unit of charge density``                                       1081202384570.0 C m^-3
    ``atomic unit of current``                                              0.00662361823751 A
    ``atomic unit of electric dipole mom.``                                 8.4783536255e-30 C m
    ``atomic unit of electric field``                                       514220674763.0 V m^-1
    ``atomic unit of electric field gradient``                              9.7173624292e+21 V m^-2
    ``atomic unit of electric polarizability``                              1.64877727436e-41 C^2 m^2 J^-1
    ``atomic unit of electric potential``                                   27.211386245988 V
    ``atomic unit of electric quadrupole mom.``                             4.4865515246e-40 C m^2
    ``atomic unit of energy``                                               4.3597447222071e-18 J
    ``atomic unit of force``                                                8.2387234983e-08 N
    ``atomic unit of length``                                               5.29177210903e-11 m
    ``atomic unit of mag. dipole mom.``                                     1.85480201566e-23 J T^-1
    ``atomic unit of mag. flux density``                                    235051.756758 T
    ``atomic unit of magnetizability``                                      7.8910366008e-29 J T^-2
    ``atomic unit of mass``                                                 9.1093837015e-31 kg
    ``atomic unit of momentum``                                             1.9928519141e-24 kg m s^-1
    ``atomic unit of permittivity``                                         1.11265005545e-10 F m^-1
    ``atomic unit of time``                                                 2.4188843265857e-17 s
    ``atomic unit of velocity``                                             2187691.26364 m s^-1
    ``Avogadro constant``                                                   6.02214076e+23 mol^-1
    ``Bohr magneton``                                                       9.2740100783e-24 J T^-1
    ``Bohr magneton in eV/T``                                               5.788381806e-05 eV T^-1
    ``Bohr magneton in Hz/T``                                               13996244936.1 Hz T^-1
    ``Bohr magneton in inverse meter per tesla``                            46.686447783 m^-1 T^-1
    ``Bohr magneton in K/T``                                                0.67171381563 K T^-1
    ``Bohr radius``                                                         5.29177210903e-11 m
    ``Boltzmann constant``                                                  1.380649e-23 J K^-1
    ``Boltzmann constant in eV/K``                                          8.617333262e-05 eV K^-1
    ``Boltzmann constant in Hz/K``                                          20836619120.0 Hz K^-1
    ``Boltzmann constant in inverse meter per kelvin``                      69.50348004 m^-1 K^-1
    ``characteristic impedance of vacuum``                                  376.730313668 ohm
    ``classical electron radius``                                           2.8179403262e-15 m
    ``Compton wavelength``                                                  2.42631023867e-12 m
    ``conductance quantum``                                                 7.748091729e-05 S
    ``conventional value of ampere-90``                                     1.00000008887 A
    ``conventional value of coulomb-90``                                    1.00000008887 C
    ``conventional value of farad-90``                                      0.9999999822 F
    ``conventional value of henry-90``                                      1.00000001779 H
    ``conventional value of Josephson constant``                            483597900000000.0 Hz V^-1
    ``conventional value of ohm-90``                                        1.00000001779 ohm
    ``conventional value of volt-90``                                       1.00000010666 V
    ``conventional value of von Klitzing constant``                         25812.807 ohm
    ``conventional value of watt-90``                                       1.00000019553 W
    ``Cu x unit``                                                           1.00207697e-13 m
    ``deuteron g factor``                                                   0.8574382338
    ``deuteron mag. mom.``                                                  4.330735094e-27 J T^-1
    ``deuteron mag. mom. to Bohr magneton ratio``                           0.000466975457
    ``deuteron mag. mom. to nuclear magneton ratio``                        0.8574382338
    ``deuteron mass``                                                       3.3435837724e-27 kg
    ``deuteron mass energy equivalent``                                     3.00506323102e-10 J
    ``deuteron mass energy equivalent in MeV``                              1875.61294257 MeV
    ``deuteron mass in u``                                                  2.013553212745 u
    ``deuteron molar mass``                                                 0.00201355321205 kg mol^-1
    ``deuteron relative atomic mass``                                       2.013553212745
    ``deuteron rms charge radius``                                          2.12799e-15 m
    ``deuteron-electron mag. mom. ratio``                                   -0.0004664345551
    ``deuteron-electron mass ratio``                                        3670.48296788
    ``deuteron-neutron mag. mom. ratio``                                    -0.44820653
    ``deuteron-proton mag. mom. ratio``                                     0.30701220939
    ``deuteron-proton mass ratio``                                          1.99900750139
    ``electron charge to mass quotient``                                    -175882001076.0 C kg^-1
    ``electron g factor``                                                   -2.00231930436256
    ``electron gyromag. ratio``                                             176085963023.0 s^-1 T^-1
    ``electron gyromag. ratio in MHz/T``                                    28024.9514242 MHz T^-1
    ``electron mag. mom.``                                                  -9.2847647043e-24 J T^-1
    ``electron mag. mom. anomaly``                                          0.00115965218128
    ``electron mag. mom. to Bohr magneton ratio``                           -1.00115965218128
    ``electron mag. mom. to nuclear magneton ratio``                        -1838.28197188
    ``electron mass``                                                       9.1093837015e-31 kg
    ``electron mass energy equivalent``                                     8.1871057769e-14 J
    ``electron mass energy equivalent in MeV``                              0.51099895 MeV
    ``electron mass in u``                                                  0.000548579909065 u
    ``electron molar mass``                                                 5.4857990888e-07 kg mol^-1
    ``electron relative atomic mass``                                       0.000548579909065
    ``electron to alpha particle mass ratio``                               0.0001370933554787
    ``electron to shielded helion mag. mom. ratio``                         864.058257
    ``electron to shielded proton mag. mom. ratio``                         -658.2275971
    ``electron volt``                                                       1.602176634e-19 J
    ``electron volt-atomic mass unit relationship``                         1.07354410233e-09 u
    ``electron volt-hartree relationship``                                  0.036749322175655 E_h
    ``electron volt-hertz relationship``                                    241798924200000.0 Hz
    ``electron volt-inverse meter relationship``                            806554.3937 m^-1
    ``electron volt-joule relationship``                                    1.602176634e-19 J
    ``electron volt-kelvin relationship``                                   11604.51812 K
    ``electron volt-kilogram relationship``                                 1.782661921e-36 kg
    ``electron-deuteron mag. mom. ratio``                                   -2143.9234915
    ``electron-deuteron mass ratio``                                        0.0002724437107462
    ``electron-helion mass ratio``                                          0.0001819543074573
    ``electron-muon mag. mom. ratio``                                       206.7669883
    ``electron-muon mass ratio``                                            0.00483633169
    ``electron-neutron mag. mom. ratio``                                    960.9205
    ``electron-neutron mass ratio``                                         0.00054386734424
    ``electron-proton mag. mom. ratio``                                     -658.21068789
    ``electron-proton mass ratio``                                          0.000544617021487
    ``electron-tau mass ratio``                                             0.000287585
    ``electron-triton mass ratio``                                          0.0001819200062251
    ``elementary charge``                                                   1.602176634e-19 C
    ``elementary charge over h-bar``                                        1519267447000000.0 A J^-1
    ``Faraday constant``                                                    96485.33212 C mol^-1
    ``Fermi coupling constant``                                             1.1663787e-05 GeV^-2
    ``fine-structure constant``                                             0.0072973525693
    ``first radiation constant``                                            3.741771852e-16 W m^2
    ``first radiation constant for spectral radiance``                      1.191042972e-16 W m^2 sr^-1
    ``Hartree energy``                                                      4.3597447222071e-18 J
    ``Hartree energy in eV``                                                27.211386245988 eV
    ``hartree-atomic mass unit relationship``                               2.92126232205e-08 u
    ``hartree-electron volt relationship``                                  27.211386245988 eV
    ``hartree-hertz relationship``                                          6579683920502000.0 Hz
    ``hartree-inverse meter relationship``                                  21947463.13632 m^-1
    ``hartree-joule relationship``                                          4.3597447222071e-18 J
    ``hartree-kelvin relationship``                                         315775.02480407 K
    ``hartree-kilogram relationship``                                       4.8508702095432e-35 kg
    ``helion g factor``                                                     -4.255250615
    ``helion mag. mom.``                                                    -1.074617532e-26 J T^-1
    ``helion mag. mom. to Bohr magneton ratio``                             -0.001158740958
    ``helion mag. mom. to nuclear magneton ratio``                          -2.127625307
    ``helion mass``                                                         5.0064127796e-27 kg
    ``helion mass energy equivalent``                                       4.4995394125e-10 J
    ``helion mass energy equivalent in MeV``                                2808.39160743 MeV
    ``helion mass in u``                                                    3.014932247175 u
    ``helion molar mass``                                                   0.00301493224613 kg mol^-1
    ``helion relative atomic mass``                                         3.014932247175
    ``helion shielding shift``                                              5.996743e-05
    ``helion-electron mass ratio``                                          5495.88528007
    ``helion-proton mass ratio``                                            2.99315267167
    ``hertz-atomic mass unit relationship``                                 4.4398216652e-24 u
    ``hertz-electron volt relationship``                                    4.135667696e-15 eV
    ``hertz-hartree relationship``                                          1.519829846057e-16 E_h
    ``hertz-inverse meter relationship``                                    3.3356409519815204e-09 m^-1
    ``hertz-joule relationship``                                            6.62607015e-34 J
    ``hertz-kelvin relationship``                                           4.799243073e-11 K
    ``hertz-kilogram relationship``                                         7.372497323e-51 kg
    ``hyperfine transition frequency of Cs-133``                            9192631770.0 Hz
    ``inverse fine-structure constant``                                     137.035999084
    ``inverse meter-atomic mass unit relationship``                         1.3310250501e-15 u
    ``inverse meter-electron volt relationship``                            1.239841984e-06 eV
    ``inverse meter-hartree relationship``                                  4.556335252912e-08 E_h
    ``inverse meter-hertz relationship``                                    299792458.0 Hz
    ``inverse meter-joule relationship``                                    1.986445857e-25 J
    ``inverse meter-kelvin relationship``                                   0.01438776877 K
    ``inverse meter-kilogram relationship``                                 2.210219094e-42 kg
    ``inverse of conductance quantum``                                      12906.40372 ohm
    ``Josephson constant``                                                  483597848400000.0 Hz V^-1
    ``joule-atomic mass unit relationship``                                 6700535256.5 u
    ``joule-electron volt relationship``                                    6.241509074e+18 eV
    ``joule-hartree relationship``                                          2.2937122783963e+17 E_h
    ``joule-hertz relationship``                                            1.509190179e+33 Hz
    ``joule-inverse meter relationship``                                    5.034116567e+24 m^-1
    ``joule-kelvin relationship``                                           7.242970516e+22 K
    ``joule-kilogram relationship``                                         1.1126500560536185e-17 kg
    ``kelvin-atomic mass unit relationship``                                9.2510873014e-14 u
    ``kelvin-electron volt relationship``                                   8.617333262e-05 eV
    ``kelvin-hartree relationship``                                         3.1668115634556e-06 E_h
    ``kelvin-hertz relationship``                                           20836619120.0 Hz
    ``kelvin-inverse meter relationship``                                   69.50348004 m^-1
    ``kelvin-joule relationship``                                           1.380649e-23 J
    ``kelvin-kilogram relationship``                                        1.536179187e-40 kg
    ``kilogram-atomic mass unit relationship``                              6.0221407621e+26 u
    ``kilogram-electron volt relationship``                                 5.609588603e+35 eV
    ``kilogram-hartree relationship``                                       2.0614857887409e+34 E_h
    ``kilogram-hertz relationship``                                         1.356392489e+50 Hz
    ``kilogram-inverse meter relationship``                                 4.524438335e+41 m^-1
    ``kilogram-joule relationship``                                         8.987551787368176e+16 J
    ``kilogram-kelvin relationship``                                        6.50965726e+39 K
    ``lattice parameter of silicon``                                        5.431020511e-10 m
    ``lattice spacing of ideal Si (220)``                                   1.920155716e-10 m
    ``Loschmidt constant (273.15 K, 100 kPa)``                              2.651645804e+25 m^-3
    ``Loschmidt constant (273.15 K, 101.325 kPa)``                          2.686780111e+25 m^-3
    ``luminous efficacy``                                                   683.0 lm W^-1
    ``mag. flux quantum``                                                   2.067833848e-15 Wb
    ``Mo x unit``                                                           1.00209952e-13 m
    ``molar gas constant``                                                  8.314462618 J mol^-1 K^-1
    ``molar mass constant``                                                 0.00099999999965 kg mol^-1
    ``molar mass of carbon-12``                                             0.0119999999958 kg mol^-1
    ``molar Planck constant``                                               3.990312712e-10 J Hz^-1 mol^-1
    ``molar volume of ideal gas (273.15 K, 100 kPa)``                       0.02271095464 m^3 mol^-1
    ``molar volume of ideal gas (273.15 K, 101.325 kPa)``                   0.02241396954 m^3 mol^-1
    ``molar volume of silicon``                                             1.205883199e-05 m^3 mol^-1
    ``muon Compton wavelength``                                             1.17344411e-14 m
    ``muon g factor``                                                       -2.0023318418
    ``muon mag. mom.``                                                      -4.4904483e-26 J T^-1
    ``muon mag. mom. anomaly``                                              0.00116592089
    ``muon mag. mom. to Bohr magneton ratio``                               -0.00484197047
    ``muon mag. mom. to nuclear magneton ratio``                            -8.89059703
    ``muon mass``                                                           1.883531627e-28 kg
    ``muon mass energy equivalent``                                         1.692833804e-11 J
    ``muon mass energy equivalent in MeV``                                  105.6583755 MeV
    ``muon mass in u``                                                      0.1134289259 u
    ``muon molar mass``                                                     0.0001134289259 kg mol^-1
    ``muon-electron mass ratio``                                            206.768283
    ``muon-neutron mass ratio``                                             0.112454517
    ``muon-proton mag. mom. ratio``                                         -3.183345142
    ``muon-proton mass ratio``                                              0.1126095264
    ``muon-tau mass ratio``                                                 0.0594635
    ``natural unit of action``                                              1.054571817e-34 J s
    ``natural unit of action in eV s``                                      6.582119569e-16 eV s
    ``natural unit of energy``                                              8.1871057769e-14 J
    ``natural unit of energy in MeV``                                       0.51099895 MeV
    ``natural unit of length``                                              3.8615926796e-13 m
    ``natural unit of mass``                                                9.1093837015e-31 kg
    ``natural unit of momentum``                                            2.730924488e-22 kg m s^-1
    ``natural unit of momentum in MeV/c``                                   0.5109989461 MeV/c
    ``natural unit of time``                                                1.28808866819e-21 s
    ``natural unit of velocity``                                            299792458.0 m s^-1
    ``neutron Compton wavelength``                                          1.31959090581e-15 m
    ``neutron g factor``                                                    -3.82608545
    ``neutron gyromag. ratio``                                              183247171.0 s^-1 T^-1
    ``neutron gyromag. ratio in MHz/T``                                     29.1646931 MHz T^-1
    ``neutron mag. mom.``                                                   -9.6623651e-27 J T^-1
    ``neutron mag. mom. to Bohr magneton ratio``                            -0.00104187563
    ``neutron mag. mom. to nuclear magneton ratio``                         -1.91304273
    ``neutron mass``                                                        1.67492749804e-27 kg
    ``neutron mass energy equivalent``                                      1.50534976287e-10 J
    ``neutron mass energy equivalent in MeV``                               939.56542052 MeV
    ``neutron mass in u``                                                   1.00866491595 u
    ``neutron molar mass``                                                  0.0010086649156 kg mol^-1
    ``neutron relative atomic mass``                                        1.00866491595
    ``neutron to shielded proton mag. mom. ratio``                          -0.68499694
    ``neutron-electron mag. mom. ratio``                                    0.00104066882
    ``neutron-electron mass ratio``                                         1838.68366173
    ``neutron-muon mass ratio``                                             8.89248406
    ``neutron-proton mag. mom. ratio``                                      -0.68497934
    ``neutron-proton mass difference``                                      2.30557435e-30 kg
    ``neutron-proton mass difference energy equivalent``                    2.07214689e-13 J
    ``neutron-proton mass difference energy equivalent in MeV``             1.29333236 MeV
    ``neutron-proton mass difference in u``                                 0.00138844933 u
    ``neutron-proton mass ratio``                                           1.00137841931
    ``neutron-tau mass ratio``                                              0.528779
    ``Newtonian constant of gravitation``                                   6.6743e-11 m^3 kg^-1 s^-2
    ``Newtonian constant of gravitation over h-bar c``                      6.70883e-39 (GeV/c^2)^-2
    ``nuclear magneton``                                                    5.0507837461e-27 J T^-1
    ``nuclear magneton in eV/T``                                            3.15245125844e-08 eV T^-1
    ``nuclear magneton in inverse meter per tesla``                         0.0254262341353 m^-1 T^-1
    ``nuclear magneton in K/T``                                             0.00036582677756 K T^-1
    ``nuclear magneton in MHz/T``                                           7.6225932291 MHz T^-1
    ``Planck constant``                                                     6.62607015e-34 J Hz^-1
    ``Planck constant in eV/Hz``                                            4.135667696e-15 eV Hz^-1
    ``Planck length``                                                       1.616255e-35 m
    ``Planck mass``                                                         2.176434e-08 kg
    ``Planck mass energy equivalent in GeV``                                1.22089e+19 GeV
    ``Planck temperature``                                                  1.416784e+32 K
    ``Planck time``                                                         5.391247e-44 s
    ``proton charge to mass quotient``                                      95788331.56 C kg^-1
    ``proton Compton wavelength``                                           1.32140985539e-15 m
    ``proton g factor``                                                     5.5856946893
    ``proton gyromag. ratio``                                               267522187.44 s^-1 T^-1
    ``proton gyromag. ratio in MHz/T``                                      42.577478518 MHz T^-1
    ``proton mag. mom.``                                                    1.41060679736e-26 J T^-1
    ``proton mag. mom. to Bohr magneton ratio``                             0.0015210322023
    ``proton mag. mom. to nuclear magneton ratio``                          2.79284734463
    ``proton mag. shielding correction``                                    2.5689e-05
    ``proton mass``                                                         1.67262192369e-27 kg
    ``proton mass energy equivalent``                                       1.50327761598e-10 J
    ``proton mass energy equivalent in MeV``                                938.27208816 MeV
    ``proton mass in u``                                                    1.007276466621 u
    ``proton molar mass``                                                   0.00100727646627 kg mol^-1
    ``proton relative atomic mass``                                         1.007276466621
    ``proton rms charge radius``                                            8.414e-16 m
    ``proton-electron mass ratio``                                          1836.15267343
    ``proton-muon mass ratio``                                              8.88024337
    ``proton-neutron mag. mom. ratio``                                      -1.45989805
    ``proton-neutron mass ratio``                                           0.99862347812
    ``proton-tau mass ratio``                                               0.528051
    ``quantum of circulation``                                              0.00036369475516 m^2 s^-1
    ``quantum of circulation times 2``                                      0.00072738951032 m^2 s^-1
    ``reduced Compton wavelength``                                          3.8615926796e-13 m
    ``reduced muon Compton wavelength``                                     1.867594306e-15 m
    ``reduced neutron Compton wavelength``                                  2.1001941552e-16 m
    ``reduced Planck constant``                                             1.054571817e-34 J s
    ``reduced Planck constant in eV s``                                     6.582119569e-16 eV s
    ``reduced Planck constant times c in MeV fm``                           197.3269804 MeV fm
    ``reduced proton Compton wavelength``                                   2.10308910336e-16 m
    ``reduced tau Compton wavelength``                                      1.110538e-16 m
    ``Rydberg constant``                                                    10973731.56816 m^-1
    ``Rydberg constant times c in Hz``                                      3289841960250800.0 Hz
    ``Rydberg constant times hc in eV``                                     13.605693122994 eV
    ``Rydberg constant times hc in J``                                      2.1798723611035e-18 J
    ``Sackur-Tetrode constant (1 K, 100 kPa)``                              -1.15170753706
    ``Sackur-Tetrode constant (1 K, 101.325 kPa)``                          -1.16487052358
    ``second radiation constant``                                           0.01438776877 m K
    ``shielded helion gyromag. ratio``                                      203789456.9 s^-1 T^-1
    ``shielded helion gyromag. ratio in MHz/T``                             32.43409942 MHz T^-1
    ``shielded helion mag. mom.``                                           -1.07455309e-26 J T^-1
    ``shielded helion mag. mom. to Bohr magneton ratio``                    -0.001158671471
    ``shielded helion mag. mom. to nuclear magneton ratio``                 -2.127497719
    ``shielded helion to proton mag. mom. ratio``                           -0.7617665618
    ``shielded helion to shielded proton mag. mom. ratio``                  -0.7617861313
    ``shielded proton gyromag. ratio``                                      267515315.1 s^-1 T^-1
    ``shielded proton gyromag. ratio in MHz/T``                             42.57638474 MHz T^-1
    ``shielded proton mag. mom.``                                           1.41057056e-26 J T^-1
    ``shielded proton mag. mom. to Bohr magneton ratio``                    0.001520993128
    ``shielded proton mag. mom. to nuclear magneton ratio``                 2.792775599
    ``shielding difference of d and p in HD``                               2.02e-08
    ``shielding difference of t and p in HT``                               2.414e-08
    ``speed of light in vacuum``                                            299792458.0 m s^-1
    ``standard acceleration of gravity``                                    9.80665 m s^-2
    ``standard atmosphere``                                                 101325.0 Pa
    ``standard-state pressure``                                             100000.0 Pa
    ``Stefan-Boltzmann constant``                                           5.670374419e-08 W m^-2 K^-4
    ``tau Compton wavelength``                                              6.97771e-16 m
    ``tau energy equivalent``                                               1776.86 MeV
    ``tau mass``                                                            3.16754e-27 kg
    ``tau mass energy equivalent``                                          2.84684e-10 J
    ``tau mass in u``                                                       1.90754 u
    ``tau molar mass``                                                      0.00190754 kg mol^-1
    ``tau-electron mass ratio``                                             3477.23
    ``tau-muon mass ratio``                                                 16.817
    ``tau-neutron mass ratio``                                              1.89115
    ``tau-proton mass ratio``                                               1.89376
    ``Thomson cross section``                                               6.6524587321e-29 m^2
    ``triton g factor``                                                     5.957924931
    ``triton mag. mom.``                                                    1.5046095202e-26 J T^-1
    ``triton mag. mom. to Bohr magneton ratio``                             0.0016223936651
    ``triton mag. mom. to nuclear magneton ratio``                          2.9789624656
    ``triton mass``                                                         5.0073567446e-27 kg
    ``triton mass energy equivalent``                                       4.500387806e-10 J
    ``triton mass energy equivalent in MeV``                                2808.92113298 MeV
    ``triton mass in u``                                                    3.01550071621 u
    ``triton molar mass``                                                   0.00301550071517 kg mol^-1
    ``triton relative atomic mass``                                         3.01550071621
    ``triton to proton mag. mom. ratio``                                    1.0666399191
    ``triton-electron mass ratio``                                          5496.92153573
    ``triton-proton mass ratio``                                            2.99371703414
    ``unified atomic mass unit``                                            1.6605390666e-27 kg
    ``vacuum electric permittivity``                                        8.8541878128e-12 F m^-1
    ``vacuum mag. permeability``                                            1.25663706212e-06 N A^-2
    ``von Klitzing constant``                                               25812.80745 ohm
    ``W to Z mass ratio``                                                   0.88153
    ``weak mixing angle``                                                   0.2229
    ``Wien frequency displacement law constant``                            58789257570.0 Hz K^-1
    ``Wien wavelength displacement law constant``                           0.002897771955 m K
    ======================================================================  ====


    Units
    =====

    SI prefixes
    -----------

    ============  =================================================================
    ``quetta``    :math:`10^{30}`
    ``ronna``     :math:`10^{27}`
    ``yotta``     :math:`10^{24}`
    ``zetta``     :math:`10^{21}`
    ``exa``       :math:`10^{18}`
    ``peta``      :math:`10^{15}`
    ``tera``      :math:`10^{12}`
    ``giga``      :math:`10^{9}`
    ``mega``      :math:`10^{6}`
    ``kilo``      :math:`10^{3}`
    ``hecto``     :math:`10^{2}`
    ``deka``      :math:`10^{1}`
    ``deci``      :math:`10^{-1}`
    ``centi``     :math:`10^{-2}`
    ``milli``     :math:`10^{-3}`
    ``micro``     :math:`10^{-6}`
    ``nano``      :math:`10^{-9}`
    ``pico``      :math:`10^{-12}`
    ``femto``     :math:`10^{-15}`
    ``atto``      :math:`10^{-18}`
    ``zepto``     :math:`10^{-21}`
    ``yocto``     :math:`10^{-24}`
    ``ronto``     :math:`10^{-27}`
    ``quecto``    :math:`10^{-30}`
    ============  =================================================================

    Binary prefixes
    ---------------

    ============  =================================================================
    ``kibi``      :math:`2^{10}`
    ``mebi``      :math:`2^{20}`
    ``gibi``      :math:`2^{30}`
    ``tebi``      :math:`2^{40}`
    ``pebi``      :math:`2^{50}`
    ``exbi``      :math:`2^{60}`
    ``zebi``      :math:`2^{70}`
    ``yobi``      :math:`2^{80}`
    ============  =================================================================

    Mass
    ----

    =================  ============================================================
    ``gram``           :math:`10^{-3}` kg
    ``metric_ton``     :math:`10^{3}` kg
    ``grain``          one grain in kg
    ``lb``             one pound (avoirdupous) in kg
    ``pound``          one pound (avoirdupous) in kg
    ``blob``           one inch version of a slug in kg (added in 1.0.0)
    ``slinch``         one inch version of a slug in kg (added in 1.0.0)
    ``slug``           one slug in kg (added in 1.0.0)
    ``oz``             one ounce in kg
    ``ounce``          one ounce in kg
    ``stone``          one stone in kg
    ``grain``          one grain in kg
    ``long_ton``       one long ton in kg
    ``short_ton``      one short ton in kg
    ``troy_ounce``     one Troy ounce in kg
    ``troy_pound``     one Troy pound in kg
    ``carat``          one carat in kg
    ``m_u``            atomic mass constant (in kg)
    ``u``              atomic mass constant (in kg)
    ``atomic_mass``    atomic mass constant (in kg)
    =================  ============================================================

    Angle
    -----

    =================  ============================================================
    ``degree``         degree in radians
    ``arcmin``         arc minute in radians
    ``arcminute``      arc minute in radians
    ``arcsec``         arc second in radians
    ``arcsecond``      arc second in radians
    =================  ============================================================


    Time
    ----

    =================  ============================================================
    ``minute``         one minute in seconds
    ``hour``           one hour in seconds
    ``day``            one day in seconds
    ``week``           one week in seconds
    ``year``           one year (365 days) in seconds
    ``Julian_year``    one Julian year (365.25 days) in seconds
    =================  ============================================================


    Length
    ------

    =====================  ============================================================
    ``inch``               one inch in meters
    ``foot``               one foot in meters
    ``yard``               one yard in meters
    ``mile``               one mile in meters
    ``mil``                one mil in meters
    ``pt``                 one point in meters
    ``point``              one point in meters
    ``survey_foot``        one survey foot in meters
    ``survey_mile``        one survey mile in meters
    ``nautical_mile``      one nautical mile in meters
    ``fermi``              one Fermi in meters
    ``angstrom``           one Angstrom in meters
    ``micron``             one micron in meters
    ``au``                 one astronomical unit in meters
    ``astronomical_unit``  one astronomical unit in meters
    ``light_year``         one light year in meters
    ``parsec``             one parsec in meters
    =====================  ============================================================

    Pressure
    --------

    =================  ============================================================
    ``atm``            standard atmosphere in pascals
    ``atmosphere``     standard atmosphere in pascals
    ``bar``            one bar in pascals
    ``torr``           one torr (mmHg) in pascals
    ``mmHg``           one torr (mmHg) in pascals
    ``psi``            one psi in pascals
    =================  ============================================================

    Area
    ----

    =================  ============================================================
    ``hectare``        one hectare in square meters
    ``acre``           one acre in square meters
    =================  ============================================================


    Volume
    ------

    ===================    ========================================================
    ``liter``              one liter in cubic meters
    ``litre``              one liter in cubic meters
    ``gallon``             one gallon (US) in cubic meters
    ``gallon_US``          one gallon (US) in cubic meters
    ``gallon_imp``         one gallon (UK) in cubic meters
    ``fluid_ounce``        one fluid ounce (US) in cubic meters
    ``fluid_ounce_US``     one fluid ounce (US) in cubic meters
    ``fluid_ounce_imp``    one fluid ounce (UK) in cubic meters
    ``bbl``                one barrel in cubic meters
    ``barrel``             one barrel in cubic meters
    ===================    ========================================================

    Speed
    -----

    ==================    ==========================================================
    ``kmh``               kilometers per hour in meters per second
    ``mph``               miles per hour in meters per second
    ``mach``              one Mach (approx., at 15 C, 1 atm) in meters per second
    ``speed_of_sound``    one Mach (approx., at 15 C, 1 atm) in meters per second
    ``knot``              one knot in meters per second
    ==================    ==========================================================


    Temperature
    -----------

    =====================  =======================================================
    ``zero_Celsius``       zero of Celsius scale in Kelvin
    ``degree_Fahrenheit``  one Fahrenheit (only differences) in Kelvins
    =====================  =======================================================

    .. autosummary::
       :toctree: generated/

       convert_temperature

    Energy
    ------

    ====================  =======================================================
    ``eV``                one electron volt in Joules
    ``electron_volt``     one electron volt in Joules
    ``calorie``           one calorie (thermochemical) in Joules
    ``calorie_th``        one calorie (thermochemical) in Joules
    ``calorie_IT``        one calorie (International Steam Table calorie, 1956) in Joules
    ``erg``               one erg in Joules
    ``Btu``               one British thermal unit (International Steam Table) in Joules
    ``Btu_IT``            one British thermal unit (International Steam Table) in Joules
    ``Btu_th``            one British thermal unit (thermochemical) in Joules
    ``ton_TNT``           one ton of TNT in Joules
    ====================  =======================================================

    Power
    -----

    ====================  =======================================================
    ``hp``                one horsepower in watts
    ``horsepower``        one horsepower in watts
    ====================  =======================================================

    Force
    -----

    ====================  =======================================================
    ``dyn``               one dyne in newtons
    ``dyne``              one dyne in newtons
    ``lbf``               one pound force in newtons
    ``pound_force``       one pound force in newtons
    ``kgf``               one kilogram force in newtons
    ``kilogram_force``    one kilogram force in newtons
    ====================  =======================================================

    Optics
    ------

    .. autosummary::
       :toctree: generated/

       lambda2nu
       nu2lambda

    References
    ==========

    .. [CODATA2018] CODATA Recommended Values of the Fundamental
       Physical Constants 2018.

       https://physics.nist.gov/cuu/Constants/

PACKAGE CONTENTS
    _codata
    _constants
    codata
    constants
    tests (package)

CLASSES
    builtins.DeprecationWarning(builtins.Warning)
        scipy.constants._codata.ConstantWarning

    class ConstantWarning(builtins.DeprecationWarning)
     |  Accessing a constant no longer in current CODATA data set
     |
     |  Method resolution order:
     |      ConstantWarning
     |      builtins.DeprecationWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.DeprecationWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.DeprecationWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.DeprecationWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

FUNCTIONS
    convert_temperature(val: 'npt.ArrayLike', old_scale: 'str', new_scale: 'str') -> 'Any'
        Convert from a temperature scale to another one among Celsius, Kelvin,
        Fahrenheit, and Rankine scales.

        Parameters
        ----------
        val : array_like
            Value(s) of the temperature(s) to be converted expressed in the
            original scale.
        old_scale : str
            Specifies as a string the original scale from which the temperature
            value(s) will be converted. Supported scales are Celsius ('Celsius',
            'celsius', 'C' or 'c'), Kelvin ('Kelvin', 'kelvin', 'K', 'k'),
            Fahrenheit ('Fahrenheit', 'fahrenheit', 'F' or 'f'), and Rankine
            ('Rankine', 'rankine', 'R', 'r').
        new_scale : str
            Specifies as a string the new scale to which the temperature
            value(s) will be converted. Supported scales are Celsius ('Celsius',
            'celsius', 'C' or 'c'), Kelvin ('Kelvin', 'kelvin', 'K', 'k'),
            Fahrenheit ('Fahrenheit', 'fahrenheit', 'F' or 'f'), and Rankine
            ('Rankine', 'rankine', 'R', 'r').

        Returns
        -------
        res : float or array of floats
            Value(s) of the converted temperature(s) expressed in the new scale.

        Notes
        -----
        .. versionadded:: 0.18.0

        Examples
        --------
        >>> from scipy.constants import convert_temperature
        >>> import numpy as np
        >>> convert_temperature(np.array([-40, 40]), 'Celsius', 'Kelvin')
        array([ 233.15,  313.15])

    find(sub: 'str | None' = None, disp: 'bool' = False) -> 'Any'
        Return list of physical_constant keys containing a given string.

        Parameters
        ----------
        sub : str
            Sub-string to search keys for. By default, return all keys.
        disp : bool
            If True, print the keys that are found and return None.
            Otherwise, return the list of keys without printing anything.

        Returns
        -------
        keys : list or None
            If `disp` is False, the list of keys is returned.
            Otherwise, None is returned.

        Examples
        --------
        >>> from scipy.constants import find, physical_constants

        Which keys in the ``physical_constants`` dictionary contain 'boltzmann'?

        >>> find('boltzmann')
        ['Boltzmann constant',
         'Boltzmann constant in Hz/K',
         'Boltzmann constant in eV/K',
         'Boltzmann constant in inverse meter per kelvin',
         'Stefan-Boltzmann constant']

        Get the constant called 'Boltzmann constant in Hz/K':

        >>> physical_constants['Boltzmann constant in Hz/K']
        (20836619120.0, 'Hz K^-1', 0.0)

        Find constants with 'radius' in the key:

        >>> find('radius')
        ['Bohr radius',
         'classical electron radius',
         'deuteron rms charge radius',
         'proton rms charge radius']
        >>> physical_constants['classical electron radius']
        (2.8179403262e-15, 'm', 1.3e-24)

    lambda2nu(lambda_: 'npt.ArrayLike') -> 'Any'
        Convert wavelength to optical frequency

        Parameters
        ----------
        lambda_ : array_like
            Wavelength(s) to be converted.

        Returns
        -------
        nu : float or array of floats
            Equivalent optical frequency.

        Notes
        -----
        Computes ``nu = c / lambda`` where c = 299792458.0, i.e., the
        (vacuum) speed of light in meters/second.

        Examples
        --------
        >>> from scipy.constants import lambda2nu, speed_of_light
        >>> import numpy as np
        >>> lambda2nu(np.array((1, speed_of_light)))
        array([  2.99792458e+08,   1.00000000e+00])

    nu2lambda(nu: 'npt.ArrayLike') -> 'Any'
        Convert optical frequency to wavelength.

        Parameters
        ----------
        nu : array_like
            Optical frequency to be converted.

        Returns
        -------
        lambda : float or array of floats
            Equivalent wavelength(s).

        Notes
        -----
        Computes ``lambda = c / nu`` where c = 299792458.0, i.e., the
        (vacuum) speed of light in meters/second.

        Examples
        --------
        >>> from scipy.constants import nu2lambda, speed_of_light
        >>> import numpy as np
        >>> nu2lambda(np.array((1, speed_of_light)))
        array([  2.99792458e+08,   1.00000000e+00])

    precision(key: 'str') -> 'float'
        Relative precision in physical_constants indexed by key

        Parameters
        ----------
        key : Python string
            Key in dictionary `physical_constants`

        Returns
        -------
        prec : float
            Relative precision in `physical_constants` corresponding to `key`

        Examples
        --------
        >>> from scipy import constants
        >>> constants.precision('proton mass')
        5.1e-37

    unit(key: 'str') -> 'str'
        Unit in physical_constants indexed by key

        Parameters
        ----------
        key : Python string
            Key in dictionary `physical_constants`

        Returns
        -------
        unit : Python string
            Unit in `physical_constants` corresponding to `key`

        Examples
        --------
        >>> from scipy import constants
        >>> constants.unit('proton mass')
        'kg'

    value(key: 'str') -> 'float'
        Value in physical_constants indexed by key

        Parameters
        ----------
        key : Python string
            Key in dictionary `physical_constants`

        Returns
        -------
        value : float
            Value in `physical_constants` corresponding to `key`

        Examples
        --------
        >>> from scipy import constants
        >>> constants.value('elementary charge')
        1.602176634e-19

DATA
    Avogadro = 6.02214076e+23
    Boltzmann = 1.380649e-23
    Btu = 1055.05585262
    Btu_IT = 1055.05585262
    Btu_th = 1054.3502644888888
    G = 6.6743e-11
    Julian_year = 31557600.0
    N_A = 6.02214076e+23
    Planck = 6.62607015e-34
    R = 8.314462618
    Rydberg = 10973731.56816
    Stefan_Boltzmann = 5.670374419e-08
    Wien = 0.002897771955
    __all__ = ['Avogadro', 'Boltzmann', 'Btu', 'Btu_IT', 'Btu_th', 'Consta...
    acre = 4046.8564223999992
    alpha = 0.0072973525693
    angstrom = 1e-10
    arcmin = 0.0002908882086657216
    arcminute = 0.0002908882086657216
    arcsec = 4.84813681109536e-06
    arcsecond = 4.84813681109536e-06
    astronomical_unit = 149597870700.0
    atm = 101325.0
    atmosphere = 101325.0
    atomic_mass = 1.6605390666e-27
    atto = 1e-18
    au = 149597870700.0
    bar = 100000.0
    barrel = 0.15898729492799998
    bbl = 0.15898729492799998
    blob = 175.12683524647636
    c = 299792458.0
    calorie = 4.184
    calorie_IT = 4.1868
    calorie_th = 4.184
    carat = 0.0002
    centi = 0.01
    day = 86400.0
    deci = 0.1
    degree = 0.017453292519943295
    degree_Fahrenheit = 0.5555555555555556
    deka = 10.0
    dyn = 1e-05
    dyne = 1e-05
    e = 1.602176634e-19
    eV = 1.602176634e-19
    electron_mass = 9.1093837015e-31
    electron_volt = 1.602176634e-19
    elementary_charge = 1.602176634e-19
    epsilon_0 = 8.8541878128e-12
    erg = 1e-07
    exa = 1e+18
    exbi = 1152921504606846976
    femto = 1e-15
    fermi = 1e-15
    fine_structure = 0.0072973525693
    fluid_ounce = 2.9573529562499998e-05
    fluid_ounce_US = 2.9573529562499998e-05
    fluid_ounce_imp = 2.84130625e-05
    foot = 0.30479999999999996
    g = 9.80665
    gallon = 0.0037854117839999997
    gallon_US = 0.0037854117839999997
    gallon_imp = 0.00454609
    gas_constant = 8.314462618
    gibi = 1073741824
    giga = 1000000000.0
    golden = 1.618033988749895
    golden_ratio = 1.618033988749895
    grain = 6.479891e-05
    gram = 0.001
    gravitational_constant = 6.6743e-11
    h = 6.62607015e-34
    hbar = 1.0545718176461565e-34
    hectare = 10000.0
    hecto = 100.0
    horsepower = 745.6998715822701
    hour = 3600.0
    hp = 745.6998715822701
    inch = 0.0254
    k = 1.380649e-23
    kgf = 9.80665
    kibi = 1024
    kilo = 1000.0
    kilogram_force = 9.80665
    kmh = 0.2777777777777778
    knot = 0.5144444444444445
    lb = 0.45359236999999997
    lbf = 4.4482216152605
    light_year = 9460730472580800.0
    liter = 0.001
    litre = 0.001
    long_ton = 1016.0469088
    m_e = 9.1093837015e-31
    m_n = 1.67492749804e-27
    m_p = 1.67262192369e-27
    m_u = 1.6605390666e-27
    mach = 340.5
    mebi = 1048576
    mega = 1000000.0
    metric_ton = 1000.0
    micro = 1e-06
    micron = 1e-06
    mil = 2.5399999999999997e-05
    mile = 1609.3439999999998
    milli = 0.001
    minute = 60.0
    mmHg = 133.32236842105263
    mph = 0.44703999999999994
    mu_0 = 1.25663706212e-06
    nano = 1e-09
    nautical_mile = 1852.0
    neutron_mass = 1.67492749804e-27
    ounce = 0.028349523124999998
    oz = 0.028349523124999998
    parsec = 3.085677581491367e+16
    pebi = 1125899906842624
    peta = 1000000000000000.0
    physical_constants = {'Angstrom star': (1.00001495e-10, 'm', 9e-17), '...
    pi = 3.141592653589793
    pico = 1e-12
    point = 0.00035277777777777776
    pound = 0.45359236999999997
    pound_force = 4.4482216152605
    proton_mass = 1.67262192369e-27
    psi = 6894.757293168361
    pt = 0.00035277777777777776
    quecto = 1e-30
    quetta = 1e+30
    ronna = 1e+27
    ronto = 1e-27
    short_ton = 907.1847399999999
    sigma = 5.670374419e-08
    slinch = 175.12683524647636
    slug = 14.593902937206364
    speed_of_light = 299792458.0
    speed_of_sound = 340.5
    stone = 6.3502931799999995
    survey_foot = 0.3048006096012192
    survey_mile = 1609.3472186944373
    tebi = 1099511627776
    tera = 1000000000000.0
    ton_TNT = 4184000000.0
    torr = 133.32236842105263
    troy_ounce = 0.031103476799999998
    troy_pound = 0.37324172159999996
    u = 1.6605390666e-27
    week = 604800.0
    yard = 0.9143999999999999
    year = 31536000.0
    yobi = 1208925819614629174706176
    yocto = 1e-24
    yotta = 1e+24
    zebi = 1180591620717411303424
    zepto = 1e-21
    zero_Celsius = 273.15
    zetta = 1e+21

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\constants\__init__.py

scipy.datasets
Python Library Documentation: package scipy.datasets in scipy

NAME
    scipy.datasets

DESCRIPTION
    ================================
    Datasets (:mod:`scipy.datasets`)
    ================================

    .. currentmodule:: scipy.datasets

    Dataset Methods
    ===============

    .. autosummary::
       :toctree: generated/

       ascent
       face
       electrocardiogram

    Utility Methods
    ===============

    .. autosummary::
       :toctree: generated/

       download_all    -- Download all the dataset files to specified path.
       clear_cache     -- Clear cached dataset directory.


    Usage of Datasets
    =================

    SciPy dataset methods can be simply called as follows: ``'<dataset-name>()'``
    This downloads the dataset files over the network once, and saves the cache,
    before returning a `numpy.ndarray` object representing the dataset.

    Note that the return data structure and data type might be different for
    different dataset methods. For a more detailed example on usage, please look
    into the particular dataset method documentation above.


    How dataset retrieval and storage works
    =======================================

    SciPy dataset files are stored within individual github repositories under the
    SciPy GitHub organization, following a naming convention as
    ``'dataset-<name>'``, for example `scipy.datasets.face` files live at
    https://github.com/scipy/dataset-face.  The `scipy.datasets` submodule utilizes
    and depends on `Pooch <https://www.fatiando.org/pooch/latest/>`_, a Python
    package built to simplify fetching data files. Pooch uses these repos to
    retrieve the respective dataset files when calling the dataset function.

    A registry of all the datasets, essentially a mapping of filenames with their
    SHA256 hash and repo urls are maintained, which Pooch uses to handle and verify
    the downloads on function call. After downloading the dataset once, the files
    are saved in the system cache directory under ``'scipy-data'``.

    Dataset cache locations may vary on different platforms.

    For macOS::

        '~/Library/Caches/scipy-data'

    For Linux and other Unix-like platforms::

        '~/.cache/scipy-data'  # or the value of the XDG_CACHE_HOME env var, if defined

    For Windows::

        'C:\Users\<user>\AppData\Local\<AppAuthor>\scipy-data\Cache'


    In environments with constrained network connectivity for various security
    reasons or on systems without continuous internet connections, one may manually
    load the cache of the datasets by placing the contents of the dataset repo in
    the above mentioned cache directory to avoid fetching dataset errors without
    the internet connectivity.

PACKAGE CONTENTS
    _download_all
    _fetchers
    _registry
    _utils
    tests (package)

FUNCTIONS
    ascent()
        Get an 8-bit grayscale bit-depth, 512 x 512 derived image for easy
        use in demos.

        The image is derived from
        https://pixnio.com/people/accent-to-the-top

        Parameters
        ----------
        None

        Returns
        -------
        ascent : ndarray
           convenient image to use for testing and demonstration

        Examples
        --------
        >>> import scipy.datasets
        >>> ascent = scipy.datasets.ascent()
        >>> ascent.shape
        (512, 512)
        >>> ascent.max()
        255

        >>> import matplotlib.pyplot as plt
        >>> plt.gray()
        >>> plt.imshow(ascent)
        >>> plt.show()

    clear_cache(datasets=None)
        Cleans the scipy datasets cache directory.

        If a scipy.datasets method or a list/tuple of the same is
        provided, then clear_cache removes all the data files
        associated to the passed dataset method callable(s).

        By default, it removes all the cached data files.

        Parameters
        ----------
        datasets : callable or list/tuple of callable or None

        Examples
        --------
        >>> from scipy import datasets
        >>> ascent_array = datasets.ascent()
        >>> ascent_array.shape
        (512, 512)
        >>> datasets.clear_cache([datasets.ascent])
        Cleaning the file ascent.dat for dataset ascent

    download_all(path=None)
        Utility method to download all the dataset files
        for `scipy.datasets` module.

        Parameters
        ----------
        path : str, optional
            Directory path to download all the dataset files.
            If None, default to the system cache_dir detected by pooch.

    electrocardiogram()
        Load an electrocardiogram as an example for a 1-D signal.

        The returned signal is a 5 minute long electrocardiogram (ECG), a medical
        recording of the heart's electrical activity, sampled at 360 Hz.

        Returns
        -------
        ecg : ndarray
            The electrocardiogram in millivolt (mV) sampled at 360 Hz.

        Notes
        -----
        The provided signal is an excerpt (19:35 to 24:35) from the `record 208`_
        (lead MLII) provided by the MIT-BIH Arrhythmia Database [1]_ on
        PhysioNet [2]_. The excerpt includes noise induced artifacts, typical
        heartbeats as well as pathological changes.

        .. _record 208: https://physionet.org/physiobank/database/html/mitdbdir/records.htm#208

        .. versionadded:: 1.1.0

        References
        ----------
        .. [1] Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database.
               IEEE Eng in Med and Biol 20(3):45-50 (May-June 2001).
               (PMID: 11446209); :doi:`10.13026/C2F305`
        .. [2] Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh,
               Mark RG, Mietus JE, Moody GB, Peng C-K, Stanley HE. PhysioBank,
               PhysioToolkit, and PhysioNet: Components of a New Research Resource
               for Complex Physiologic Signals. Circulation 101(23):e215-e220;
               :doi:`10.1161/01.CIR.101.23.e215`

        Examples
        --------
        >>> from scipy.datasets import electrocardiogram
        >>> ecg = electrocardiogram()
        >>> ecg
        array([-0.245, -0.215, -0.185, ..., -0.405, -0.395, -0.385])
        >>> ecg.shape, ecg.mean(), ecg.std()
        ((108000,), -0.16510875, 0.5992473991177294)

        As stated the signal features several areas with a different morphology.
        E.g., the first few seconds show the electrical activity of a heart in
        normal sinus rhythm as seen below.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> fs = 360
        >>> time = np.arange(ecg.size) / fs
        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(9, 10.2)
        >>> plt.ylim(-1, 1.5)
        >>> plt.show()

        After second 16, however, the first premature ventricular contractions,
        also called extrasystoles, appear. These have a different morphology
        compared to typical heartbeats. The difference can easily be observed
        in the following plot.

        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(46.5, 50)
        >>> plt.ylim(-2, 1.5)
        >>> plt.show()

        At several points large artifacts disturb the recording, e.g.:

        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(207, 215)
        >>> plt.ylim(-2, 3.5)
        >>> plt.show()

        Finally, examining the power spectrum reveals that most of the biosignal is
        made up of lower frequencies. At 60 Hz the noise induced by the mains
        electricity can be clearly observed.

        >>> from scipy.signal import welch
        >>> f, Pxx = welch(ecg, fs=fs, nperseg=2048, scaling="spectrum")
        >>> plt.semilogy(f, Pxx)
        >>> plt.xlabel("Frequency in Hz")
        >>> plt.ylabel("Power spectrum of the ECG in mV**2")
        >>> plt.xlim(f[[0, -1]])
        >>> plt.show()

    face(gray=False)
        Get a 1024 x 768, color image of a raccoon face.

        The image is derived from
        https://pixnio.com/fauna-animals/raccoons/raccoon-procyon-lotor

        Parameters
        ----------
        gray : bool, optional
            If True return 8-bit grey-scale image, otherwise return a color image

        Returns
        -------
        face : ndarray
            image of a raccoon face

        Examples
        --------
        >>> import scipy.datasets
        >>> face = scipy.datasets.face()
        >>> face.shape
        (768, 1024, 3)
        >>> face.max()
        255
        >>> face.dtype
        dtype('uint8')

        >>> import matplotlib.pyplot as plt
        >>> plt.gray()
        >>> plt.imshow(face)
        >>> plt.show()

DATA
    __all__ = ['ascent', 'electrocardiogram', 'face', 'download_all', 'cle...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\datasets\__init__.py

scipy.fft
Python Library Documentation: package scipy.fft in scipy

NAME
    scipy.fft

DESCRIPTION
    ==============================================
    Discrete Fourier transforms (:mod:`scipy.fft`)
    ==============================================

    .. currentmodule:: scipy.fft

    Fast Fourier Transforms (FFTs)
    ==============================

    .. autosummary::
       :toctree: generated/

       fft - Fast (discrete) Fourier Transform (FFT)
       ifft - Inverse FFT
       fft2 - 2-D FFT
       ifft2 - 2-D inverse FFT
       fftn - N-D FFT
       ifftn - N-D inverse FFT
       rfft - FFT of strictly real-valued sequence
       irfft - Inverse of rfft
       rfft2 - 2-D FFT of real sequence
       irfft2 - Inverse of rfft2
       rfftn - N-D FFT of real sequence
       irfftn - Inverse of rfftn
       hfft - FFT of a Hermitian sequence (real spectrum)
       ihfft - Inverse of hfft
       hfft2 - 2-D FFT of a Hermitian sequence
       ihfft2 - Inverse of hfft2
       hfftn - N-D FFT of a Hermitian sequence
       ihfftn - Inverse of hfftn

    Discrete Sin and Cosine Transforms (DST and DCT)
    ================================================

    .. autosummary::
       :toctree: generated/

       dct - Discrete cosine transform
       idct - Inverse discrete cosine transform
       dctn - N-D Discrete cosine transform
       idctn - N-D Inverse discrete cosine transform
       dst - Discrete sine transform
       idst - Inverse discrete sine transform
       dstn - N-D Discrete sine transform
       idstn - N-D Inverse discrete sine transform

    Fast Hankel Transforms
    ======================

    .. autosummary::
       :toctree: generated/

       fht - Fast Hankel transform
       ifht - Inverse of fht

    Helper functions
    ================

    .. autosummary::
       :toctree: generated/

       fftshift - Shift the zero-frequency component to the center of the spectrum
       ifftshift - The inverse of `fftshift`
       fftfreq - Return the Discrete Fourier Transform sample frequencies
       rfftfreq - DFT sample frequencies (for usage with rfft, irfft)
       fhtoffset - Compute an optimal offset for the Fast Hankel Transform
       next_fast_len - Find the optimal length to zero-pad an FFT for speed
       prev_fast_len - Find the maximum slice length that results in a fast FFT
       set_workers - Context manager to set default number of workers
       get_workers - Get the current default number of workers

    Backend control
    ===============

    .. autosummary::
       :toctree: generated/

       set_backend - Context manager to set the backend within a fixed scope
       skip_backend - Context manager to skip a backend within a fixed scope
       set_global_backend - Sets the global fft backend
       register_backend - Register a backend for permanent use

PACKAGE CONTENTS
    _backend
    _basic
    _basic_backend
    _debug_backends
    _fftlog
    _fftlog_backend
    _helper
    _pocketfft (package)
    _realtransforms
    _realtransforms_backend
    tests (package)

FUNCTIONS
    dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return the Discrete Cosine Transform of arbitrary type sequence x.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the dct is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized DCT variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idct : Inverse DCT

        Notes
        -----
        For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to
        MATLAB ``dct(x)``.

        .. warning:: For ``type in {1, 2, 3}``, ``norm="ortho"`` breaks the direct
                     correspondence with the direct Fourier transform. To recover
                     it you must specify ``orthogonalize=False``.

        For ``norm="ortho"`` both the `dct` and `idct` are scaled by the same
        overall factor in both directions. By default, the transform is also
        orthogonalized which for types 1, 2 and 3 means the transform definition is
        modified to give orthogonality of the DCT matrix (see below).

        For ``norm="backward"``, there is no scaling on `dct` and the `idct` is
        scaled by ``1/N`` where ``N`` is the "logical" size of the DCT. For
        ``norm="forward"`` the ``1/N`` normalization is applied to the forward
        `dct` instead and the `idct` is unnormalized.

        There are, theoretically, 8 types of the DCT, only the first 4 types are
        implemented in SciPy.'The' DCT generally refers to DCT type 2, and 'the'
        Inverse DCT generally refers to DCT type 3.

        **Type I**

        There are several definitions of the DCT-I; we use the following
        (for ``norm="backward"``)

        .. math::

           y_k = x_0 + (-1)^k x_{N-1} + 2 \sum_{n=1}^{N-2} x_n \cos\left(
           \frac{\pi k n}{N-1} \right)

        If ``orthogonalize=True``, ``x[0]`` and ``x[N-1]`` are multiplied by a
        scaling factor of :math:`\sqrt{2}`, and ``y[0]`` and ``y[N-1]`` are divided
        by :math:`\sqrt{2}`. When combined with ``norm="ortho"``, this makes the
        corresponding matrix of coefficients orthonormal (``O @ O.T = np.eye(N)``).

        .. note::
           The DCT-I is only supported for input size > 1.

        **Type II**

        There are several definitions of the DCT-II; we use the following
        (for ``norm="backward"``)

        .. math::

           y_k = 2 \sum_{n=0}^{N-1} x_n \cos\left(\frac{\pi k(2n+1)}{2N} \right)

        If ``orthogonalize=True``, ``y[0]`` is divided by :math:`\sqrt{2}` which,
        when combined with ``norm="ortho"``, makes the corresponding matrix of
        coefficients orthonormal (``O @ O.T = np.eye(N)``).

        **Type III**

        There are several definitions, we use the following (for
        ``norm="backward"``)

        .. math::

           y_k = x_0 + 2 \sum_{n=1}^{N-1} x_n \cos\left(\frac{\pi(2k+1)n}{2N}\right)

        If ``orthogonalize=True``, ``x[0]`` terms are multiplied by
        :math:`\sqrt{2}` which, when combined with ``norm="ortho"``, makes the
        corresponding matrix of coefficients orthonormal (``O @ O.T = np.eye(N)``).

        The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up
        to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of
        the orthonormalized DCT-II.

        **Type IV**

        There are several definitions of the DCT-IV; we use the following
        (for ``norm="backward"``)

        .. math::

           y_k = 2 \sum_{n=0}^{N-1} x_n \cos\left(\frac{\pi(2k+1)(2n+1)}{4N} \right)

        ``orthogonalize`` has no effect here, as the DCT-IV matrix is already
        orthogonal up to a scale factor of ``2N``.

        References
        ----------
        .. [1] 'A Fast Cosine Transform in One and Two Dimensions', by J.
               Makhoul, `IEEE Transactions on acoustics, speech and signal
               processing` vol. 28(1), pp. 27-34,
               :doi:`10.1109/TASSP.1980.1163351` (1980).
        .. [2] Wikipedia, "Discrete cosine transform",
               https://en.wikipedia.org/wiki/Discrete_cosine_transform

        Examples
        --------
        The Type 1 DCT is equivalent to the FFT (though faster) for real,
        even-symmetrical inputs. The output is also real and even-symmetrical.
        Half of the FFT input is used to generate half of the FFT output:

        >>> from scipy.fft import fft, dct
        >>> import numpy as np
        >>> fft(np.array([4., 3., 5., 10., 5., 3.])).real
        array([ 30.,  -8.,   6.,  -2.,   6.,  -8.])
        >>> dct(np.array([4., 3., 5., 10.]), 1)
        array([ 30.,  -8.,   6.,  -2.])

    dctn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, orthogonalize=None)
        Return multidimensional Discrete Cosine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        s : int or array_like of ints or None, optional
            The shape of the result. If both `s` and `axes` (see below) are None,
            `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
            ``numpy.take(x.shape, axes, axis=0)``.
            If ``s[i] > x.shape[i]``, the ith dimension of the input is padded with zeros.
            If ``s[i] < x.shape[i]``, the ith dimension of the input is truncated to length
            ``s[i]``.
            If any element of `s` is -1, the size of the corresponding dimension of
            `x` is used.
        axes : int or array_like of ints or None, optional
            Axes over which the DCT is computed. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized DCT variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idctn : Inverse multidimensional DCT

        Notes
        -----
        For full details of the DCT types and normalization modes, as well as
        references, see `dct`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fft import dctn, idctn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idctn(dctn(y)))
        True

    dst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return the Discrete Sine Transform of arbitrary type sequence x.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        n : int, optional
            Length of the transform. If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the dst is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized DST variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        dst : ndarray of reals
            The transformed input array.

        See Also
        --------
        idst : Inverse DST

        Notes
        -----
        .. warning:: For ``type in {2, 3}``, ``norm="ortho"`` breaks the direct
                     correspondence with the direct Fourier transform. To recover
                     it you must specify ``orthogonalize=False``.

        For ``norm="ortho"`` both the `dst` and `idst` are scaled by the same
        overall factor in both directions. By default, the transform is also
        orthogonalized which for types 2 and 3 means the transform definition is
        modified to give orthogonality of the DST matrix (see below).

        For ``norm="backward"``, there is no scaling on the `dst` and the `idst` is
        scaled by ``1/N`` where ``N`` is the "logical" size of the DST.

        There are, theoretically, 8 types of the DST for different combinations of
        even/odd boundary conditions and boundary off sets [1]_, only the first
        4 types are implemented in SciPy.

        **Type I**

        There are several definitions of the DST-I; we use the following for
        ``norm="backward"``. DST-I assumes the input is odd around :math:`n=-1` and
        :math:`n=N`.

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(k+1)(n+1)}{N+1}\right)

        Note that the DST-I is only supported for input size > 1.
        The (unnormalized) DST-I is its own inverse, up to a factor :math:`2(N+1)`.
        The orthonormalized DST-I is exactly its own inverse.

        ``orthogonalize`` has no effect here, as the DST-I matrix is already
        orthogonal up to a scale factor of ``2N``.

        **Type II**

        There are several definitions of the DST-II; we use the following for
        ``norm="backward"``. DST-II assumes the input is odd around :math:`n=-1/2` and
        :math:`n=N-1/2`; the output is odd around :math:`k=-1` and even around :math:`k=N-1`

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(k+1)(2n+1)}{2N}\right)

        If ``orthogonalize=True``, ``y[-1]`` is divided :math:`\sqrt{2}` which, when
        combined with ``norm="ortho"``, makes the corresponding matrix of
        coefficients orthonormal (``O @ O.T = np.eye(N)``).

        **Type III**

        There are several definitions of the DST-III, we use the following (for
        ``norm="backward"``). DST-III assumes the input is odd around :math:`n=-1` and
        even around :math:`n=N-1`

        .. math::

            y_k = (-1)^k x_{N-1} + 2 \sum_{n=0}^{N-2} x_n \sin\left(
            \frac{\pi(2k+1)(n+1)}{2N}\right)

        If ``orthogonalize=True``, ``x[-1]`` is multiplied by :math:`\sqrt{2}`
        which, when combined with ``norm="ortho"``, makes the corresponding matrix
        of coefficients orthonormal (``O @ O.T = np.eye(N)``).

        The (unnormalized) DST-III is the inverse of the (unnormalized) DST-II, up
        to a factor :math:`2N`. The orthonormalized DST-III is exactly the inverse of the
        orthonormalized DST-II.

        **Type IV**

        There are several definitions of the DST-IV, we use the following (for
        ``norm="backward"``). DST-IV assumes the input is odd around :math:`n=-0.5` and
        even around :math:`n=N-0.5`

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(2k+1)(2n+1)}{4N}\right)

        ``orthogonalize`` has no effect here, as the DST-IV matrix is already
        orthogonal up to a scale factor of ``2N``.

        The (unnormalized) DST-IV is its own inverse, up to a factor :math:`2N`. The
        orthonormalized DST-IV is exactly its own inverse.

        References
        ----------
        .. [1] Wikipedia, "Discrete sine transform",
               https://en.wikipedia.org/wiki/Discrete_sine_transform

    dstn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return multidimensional Discrete Sine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        s : int or array_like of ints or None, optional
            The shape of the result.  If both `s` and `axes` (see below) are None,
            `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
            ``numpy.take(x.shape, axes, axis=0)``.
            If ``s[i] > x.shape[i]``, the ith dimension of the input is padded with zeros.
            If ``s[i] < x.shape[i]``, the ith dimension of the input is truncated to length
            ``s[i]``.
            If any element of `shape` is -1, the size of the corresponding dimension
            of `x` is used.
        axes : int or array_like of ints or None, optional
            Axes over which the DST is computed. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized DST variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idstn : Inverse multidimensional DST

        Notes
        -----
        For full details of the DST types and normalization modes, as well as
        references, see `dst`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fft import dstn, idstn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idstn(dstn(y)))
        True

    fft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 1-D discrete Fourier Transform.

        This function computes the 1-D *n*-point discrete Fourier
        Transform (DFT) with the efficient Fast Fourier Transform (FFT)
        algorithm [1]_.

        Parameters
        ----------
        x : array_like
            Input array, can be complex.
        n : int, optional
            Length of the transformed axis of the output.
            If `n` is smaller than the length of the input, the input is cropped.
            If it is larger, the input is padded with zeros. If `n` is not given,
            the length of the input along the axis specified by `axis` is used.
        axis : int, optional
            Axis over which to compute the FFT. If not given, the last axis is
            used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode. Default is "backward", meaning no normalization on
            the forward transforms and scaling by ``1/n`` on the `ifft`.
            "forward" instead applies the ``1/n`` factor on the forward transform.
            For ``norm="ortho"``, both directions are scaled by ``1/sqrt(n)``.

            .. versionadded:: 1.6.0
               ``norm={"forward", "backward"}`` options were added

        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See the notes below for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``. See below for more
            details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.

        Raises
        ------
        IndexError
            if `axes` is larger than the last axis of `x`.

        See Also
        --------
        ifft : The inverse of `fft`.
        fft2 : The 2-D FFT.
        fftn : The N-D FFT.
        rfftn : The N-D FFT of real input.
        fftfreq : Frequency bins for given FFT parameters.
        next_fast_len : Size to pad input to for most efficient transforms

        Notes
        -----
        FFT (Fast Fourier Transform) refers to a way the discrete Fourier Transform
        (DFT) can be calculated efficiently, by using symmetries in the calculated
        terms. The symmetry is highest when `n` is a power of 2, and the transform
        is therefore most efficient for these sizes. For poorly factorizable sizes,
        `scipy.fft` uses Bluestein's algorithm [2]_ and so is never worse than
        O(`n` log `n`). Further performance improvements may be seen by zero-padding
        the input using `next_fast_len`.

        If ``x`` is a 1d array, then the `fft` is equivalent to ::

            y[k] = np.sum(x * np.exp(-2j * np.pi * k * np.arange(n)/n))

        The frequency term ``f=k/n`` is found at ``y[k]``. At ``y[n/2]`` we reach
        the Nyquist frequency and wrap around to the negative-frequency terms. So,
        for an 8-point transform, the frequencies of the result are
        [0, 1, 2, 3, -4, -3, -2, -1]. To rearrange the fft output so that the
        zero-frequency component is centered, like [-4, -3, -2, -1, 0, 1, 2, 3],
        use `fftshift`.

        Transforms can be done in single, double, or extended precision (long
        double) floating point. Half precision inputs will be converted to single
        precision and non-floating-point inputs will be converted to double
        precision.

        If the data type of ``x`` is real, a "real FFT" algorithm is automatically
        used, which roughly halves the computation time. To increase efficiency
        a little further, use `rfft`, which does the same calculation, but only
        outputs half of the symmetrical spectrum. If the data are both real and
        symmetrical, the `dct` can again double the efficiency, by generating
        half of the spectrum from half of the signal.

        When ``overwrite_x=True`` is specified, the memory referenced by ``x`` may
        be used by the implementation in any way. This may include reusing the
        memory for the result, but this is in no way guaranteed. You should not
        rely on the contents of ``x`` after the transform as this may change in
        future without warning.

        The ``workers`` argument specifies the maximum number of parallel jobs to
        split the FFT computation into. This will execute independent 1-D
        FFTs within ``x``. So, ``x`` must be at least 2-D and the
        non-transformed axes must be large enough to split into chunks. If ``x`` is
        too small, fewer jobs may be used than requested.

        References
        ----------
        .. [1] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the
               machine calculation of complex Fourier series," *Math. Comput.*
               19: 297-301.
        .. [2] Bluestein, L., 1970, "A linear filtering approach to the
               computation of discrete Fourier transform". *IEEE Transactions on
               Audio and Electroacoustics.* 18 (4): 451-455.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> scipy.fft.fft(np.exp(2j * np.pi * np.arange(8) / 8))
        array([-2.33486982e-16+1.14423775e-17j,  8.00000000e+00-1.25557246e-15j,
                2.33486982e-16+2.33486982e-16j,  0.00000000e+00+1.22464680e-16j,
               -1.14423775e-17+2.33486982e-16j,  0.00000000e+00+5.20784380e-16j,
                1.14423775e-17+1.14423775e-17j,  0.00000000e+00+1.22464680e-16j])

        In this example, real input has an FFT which is Hermitian, i.e., symmetric
        in the real part and anti-symmetric in the imaginary part:

        >>> from scipy.fft import fft, fftfreq, fftshift
        >>> import matplotlib.pyplot as plt
        >>> t = np.arange(256)
        >>> sp = fftshift(fft(np.sin(t)))
        >>> freq = fftshift(fftfreq(t.shape[-1]))
        >>> plt.plot(freq, sp.real, freq, sp.imag)
        [<matplotlib.lines.Line2D object at 0x...>,
         <matplotlib.lines.Line2D object at 0x...>]
        >>> plt.show()

    fft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 2-D discrete Fourier Transform

        This function computes the N-D discrete Fourier Transform
        over any axes in an M-D array by means of the
        Fast Fourier Transform (FFT). By default, the transform is computed over
        the last two axes of the input array, i.e., a 2-dimensional FFT.

        Parameters
        ----------
        x : array_like
            Input array, can be complex
        s : sequence of ints, optional
            Shape (length of each transformed axis) of the output
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
            This corresponds to ``n`` for ``fft(x, n)``.
            Along each axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used.
        axes : sequence of ints, optional
            Axes over which to compute the FFT. If not given, the last two axes are
            used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or the last two axes if `axes` is not given.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length, or `axes` not given and
            ``len(s) != 2``.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        ifft2 : The inverse 2-D FFT.
        fft : The 1-D FFT.
        fftn : The N-D FFT.
        fftshift : Shifts zero-frequency terms to the center of the array.
            For 2-D input, swaps first and third quadrants, and second
            and fourth quadrants.

        Notes
        -----
        `fft2` is just `fftn` with a different default for `axes`.

        The output, analogously to `fft`, contains the term for zero frequency in
        the low-order corner of the transformed axes, the positive frequency terms
        in the first half of these axes, the term for the Nyquist frequency in the
        middle of the axes and the negative frequency terms in the second half of
        the axes, in order of decreasingly negative frequency.

        See `fftn` for details and a plotting example, and `fft` for
        definitions and conventions used.


        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.mgrid[:5, :5][0]
        >>> scipy.fft.fft2(x)
        array([[ 50.  +0.j        ,   0.  +0.j        ,   0.  +0.j        , # may vary
                  0.  +0.j        ,   0.  +0.j        ],
               [-12.5+17.20477401j,   0.  +0.j        ,   0.  +0.j        ,
                  0.  +0.j        ,   0.  +0.j        ],
               [-12.5 +4.0614962j ,   0.  +0.j        ,   0.  +0.j        ,
                  0.  +0.j        ,   0.  +0.j        ],
               [-12.5 -4.0614962j ,   0.  +0.j        ,   0.  +0.j        ,
                  0.  +0.j        ,   0.  +0.j        ],
               [-12.5-17.20477401j,   0.  +0.j        ,   0.  +0.j        ,
                  0.  +0.j        ,   0.  +0.j        ]])

    fftfreq(n, d=1.0, *, xp=None, device=None)
        Return the Discrete Fourier Transform sample frequencies.

        The returned float array `f` contains the frequency bin centers in cycles
        per unit of the sample spacing (with zero at the start).  For instance, if
        the sample spacing is in seconds, then the frequency unit is cycles/second.

        Given a window length `n` and a sample spacing `d`::

          f = [0, 1, ...,   n/2-1,     -n/2, ..., -1] / (d*n)   if n is even
          f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n)   if n is odd

        Parameters
        ----------
        n : int
            Window length.
        d : scalar, optional
            Sample spacing (inverse of the sampling rate). Defaults to 1.
        xp : array_namespace, optional
            The namespace for the return array. Default is None, where NumPy is used.
        device : device, optional
            The device for the return array.
            Only valid when `xp.fft.fftfreq` implements the device parameter.

        Returns
        -------
        f : ndarray
            Array of length `n` containing the sample frequencies.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.fft
        >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
        >>> fourier = scipy.fft.fft(signal)
        >>> n = signal.size
        >>> timestep = 0.1
        >>> freq = scipy.fft.fftfreq(n, d=timestep)
        >>> freq
        array([ 0.  ,  1.25,  2.5 , ..., -3.75, -2.5 , -1.25])

    fftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the N-D discrete Fourier Transform.

        This function computes the N-D discrete Fourier Transform over
        any number of axes in an M-D array by means of the Fast Fourier
        Transform (FFT).

        Parameters
        ----------
        x : array_like
            Input array, can be complex.
        s : sequence of ints, optional
            Shape (length of each transformed axis) of the output
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
            This corresponds to ``n`` for ``fft(x, n)``.
            Along any axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used.
        axes : sequence of ints, optional
            Axes over which to compute the FFT. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` and `x`,
            as explained in the parameters section above.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        ifftn : The inverse of `fftn`, the inverse N-D FFT.
        fft : The 1-D FFT, with definitions and conventions used.
        rfftn : The N-D FFT of real input.
        fft2 : The 2-D FFT.
        fftshift : Shifts zero-frequency terms to centre of array.

        Notes
        -----
        The output, analogously to `fft`, contains the term for zero frequency in
        the low-order corner of all axes, the positive frequency terms in the
        first half of all axes, the term for the Nyquist frequency in the middle
        of all axes and the negative frequency terms in the second half of all
        axes, in order of decreasingly negative frequency.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.mgrid[:3, :3, :3][0]
        >>> scipy.fft.fftn(x, axes=(1, 2))
        array([[[ 0.+0.j,   0.+0.j,   0.+0.j], # may vary
                [ 0.+0.j,   0.+0.j,   0.+0.j],
                [ 0.+0.j,   0.+0.j,   0.+0.j]],
               [[ 9.+0.j,   0.+0.j,   0.+0.j],
                [ 0.+0.j,   0.+0.j,   0.+0.j],
                [ 0.+0.j,   0.+0.j,   0.+0.j]],
               [[18.+0.j,   0.+0.j,   0.+0.j],
                [ 0.+0.j,   0.+0.j,   0.+0.j],
                [ 0.+0.j,   0.+0.j,   0.+0.j]]])
        >>> scipy.fft.fftn(x, (2, 2), axes=(0, 1))
        array([[[ 2.+0.j,  2.+0.j,  2.+0.j], # may vary
                [ 0.+0.j,  0.+0.j,  0.+0.j]],
               [[-2.+0.j, -2.+0.j, -2.+0.j],
                [ 0.+0.j,  0.+0.j,  0.+0.j]]])

        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> [X, Y] = np.meshgrid(2 * np.pi * np.arange(200) / 12,
        ...                      2 * np.pi * np.arange(200) / 34)
        >>> S = np.sin(X) + np.cos(Y) + rng.uniform(0, 1, X.shape)
        >>> FS = scipy.fft.fftn(S)
        >>> plt.imshow(np.log(np.abs(scipy.fft.fftshift(FS))**2))
        <matplotlib.image.AxesImage object at 0x...>
        >>> plt.show()

    fftshift(x, axes=None)
        Shift the zero-frequency component to the center of the spectrum.

        This function swaps half-spaces for all axes listed (defaults to all).
        Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.

        Parameters
        ----------
        x : array_like
            Input array.
        axes : int or shape tuple, optional
            Axes over which to shift.  Default is None, which shifts all axes.

        Returns
        -------
        y : ndarray
            The shifted array.

        See Also
        --------
        ifftshift : The inverse of `fftshift`.

        Examples
        --------
        >>> import numpy as np
        >>> freqs = np.fft.fftfreq(10, 0.1)
        >>> freqs
        array([ 0.,  1.,  2., ..., -3., -2., -1.])
        >>> np.fft.fftshift(freqs)
        array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])

        Shift the zero-frequency component only along the second axis:

        >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
        >>> freqs
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])
        >>> np.fft.fftshift(freqs, axes=(1,))
        array([[ 2.,  0.,  1.],
               [-4.,  3.,  4.],
               [-1., -3., -2.]])

    fht(a, dln, mu, offset=0.0, bias=0.0)
        Compute the fast Hankel transform.

        Computes the discrete Hankel transform of a logarithmically spaced periodic
        sequence using the FFTLog algorithm [1]_, [2]_.

        Parameters
        ----------
        a : array_like (..., n)
            Real periodic input array, uniformly logarithmically spaced.  For
            multidimensional input, the transform is performed over the last axis.
        dln : float
            Uniform logarithmic spacing of the input array.
        mu : float
            Order of the Hankel transform, any positive or negative real number.
        offset : float, optional
            Offset of the uniform logarithmic spacing of the output array.
        bias : float, optional
            Exponent of power law bias, any positive or negative real number.

        Returns
        -------
        A : array_like (..., n)
            The transformed output array, which is real, periodic, uniformly
            logarithmically spaced, and of the same shape as the input array.

        See Also
        --------
        ifht : The inverse of `fht`.
        fhtoffset : Return an optimal offset for `fht`.

        Notes
        -----
        This function computes a discrete version of the Hankel transform

        .. math::

            A(k) = \int_{0}^{\infty} \! a(r) \, J_\mu(kr) \, k \, dr \;,

        where :math:`J_\mu` is the Bessel function of order :math:`\mu`.  The index
        :math:`\mu` may be any real number, positive or negative.  Note that the
        numerical Hankel transform uses an integrand of :math:`k \, dr`, while the
        mathematical Hankel transform is commonly defined using :math:`r \, dr`.

        The input array `a` is a periodic sequence of length :math:`n`, uniformly
        logarithmically spaced with spacing `dln`,

        .. math::

            a_j = a(r_j) \;, \quad
            r_j = r_c \exp[(j-j_c) \, \mathtt{dln}]

        centred about the point :math:`r_c`.  Note that the central index
        :math:`j_c = (n-1)/2` is half-integral if :math:`n` is even, so that
        :math:`r_c` falls between two input elements.  Similarly, the output
        array `A` is a periodic sequence of length :math:`n`, also uniformly
        logarithmically spaced with spacing `dln`

        .. math::

           A_j = A(k_j) \;, \quad
           k_j = k_c \exp[(j-j_c) \, \mathtt{dln}]

        centred about the point :math:`k_c`.

        The centre points :math:`r_c` and :math:`k_c` of the periodic intervals may
        be chosen arbitrarily, but it would be usual to choose the product
        :math:`k_c r_c = k_j r_{n-1-j} = k_{n-1-j} r_j` to be unity.  This can be
        changed using the `offset` parameter, which controls the logarithmic offset
        :math:`\log(k_c) = \mathtt{offset} - \log(r_c)` of the output array.
        Choosing an optimal value for `offset` may reduce ringing of the discrete
        Hankel transform.

        If the `bias` parameter is nonzero, this function computes a discrete
        version of the biased Hankel transform

        .. math::

            A(k) = \int_{0}^{\infty} \! a_q(r) \, (kr)^q \, J_\mu(kr) \, k \, dr

        where :math:`q` is the value of `bias`, and a power law bias
        :math:`a_q(r) = a(r) \, (kr)^{-q}` is applied to the input sequence.
        Biasing the transform can help approximate the continuous transform of
        :math:`a(r)` if there is a value :math:`q` such that :math:`a_q(r)` is
        close to a periodic sequence, in which case the resulting :math:`A(k)` will
        be close to the continuous transform.

        References
        ----------
        .. [1] Talman J. D., 1978, J. Comp. Phys., 29, 35
        .. [2] Hamilton A. J. S., 2000, MNRAS, 312, 257 (astro-ph/9905191)

        Examples
        --------

        This example is the adapted version of ``fftlogtest.f`` which is provided
        in [2]_. It evaluates the integral

        .. math::

            \int^\infty_0 r^{\mu+1} \exp(-r^2/2) J_\mu(k, r) k dr
            = k^{\mu+1} \exp(-k^2/2) .

        >>> import numpy as np
        >>> from scipy import fft
        >>> import matplotlib.pyplot as plt

        Parameters for the transform.

        >>> mu = 0.0                     # Order mu of Bessel function
        >>> r = np.logspace(-7, 1, 128)  # Input evaluation points
        >>> dln = np.log(r[1]/r[0])      # Step size
        >>> offset = fft.fhtoffset(dln, initial=-6*np.log(10), mu=mu)
        >>> k = np.exp(offset)/r[::-1]   # Output evaluation points

        Define the analytical function.

        >>> def f(x, mu):
        ...     """Analytical function: x^(mu+1) exp(-x^2/2)."""
        ...     return x**(mu + 1)*np.exp(-x**2/2)

        Evaluate the function at ``r`` and compute the corresponding values at
        ``k`` using FFTLog.

        >>> a_r = f(r, mu)
        >>> fht = fft.fht(a_r, dln, mu=mu, offset=offset)

        For this example we can actually compute the analytical response (which in
        this case is the same as the input function) for comparison and compute the
        relative error.

        >>> a_k = f(k, mu)
        >>> rel_err = abs((fht-a_k)/a_k)

        Plot the result.

        >>> figargs = {'sharex': True, 'sharey': True, 'constrained_layout': True}
        >>> fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4), **figargs)
        >>> ax1.set_title(r'$r^{\mu+1}\ \exp(-r^2/2)$')
        >>> ax1.loglog(r, a_r, 'k', lw=2)
        >>> ax1.set_xlabel('r')
        >>> ax2.set_title(r'$k^{\mu+1} \exp(-k^2/2)$')
        >>> ax2.loglog(k, a_k, 'k', lw=2, label='Analytical')
        >>> ax2.loglog(k, fht, 'C3--', lw=2, label='FFTLog')
        >>> ax2.set_xlabel('k')
        >>> ax2.legend(loc=3, framealpha=1)
        >>> ax2.set_ylim([1e-10, 1e1])
        >>> ax2b = ax2.twinx()
        >>> ax2b.loglog(k, rel_err, 'C0', label='Rel. Error (-)')
        >>> ax2b.set_ylabel('Rel. Error (-)', color='C0')
        >>> ax2b.tick_params(axis='y', labelcolor='C0')
        >>> ax2b.legend(loc=4, framealpha=1)
        >>> ax2b.set_ylim([1e-9, 1e-3])
        >>> plt.show()

    fhtoffset(dln, mu, initial=0.0, bias=0.0)
        Return optimal offset for a fast Hankel transform.

        Returns an offset close to `initial` that fulfils the low-ringing
        condition of [1]_ for the fast Hankel transform `fht` with logarithmic
        spacing `dln`, order `mu` and bias `bias`.

        Parameters
        ----------
        dln : float
            Uniform logarithmic spacing of the transform.
        mu : float
            Order of the Hankel transform, any positive or negative real number.
        initial : float, optional
            Initial value for the offset. Returns the closest value that fulfils
            the low-ringing condition.
        bias : float, optional
            Exponent of power law bias, any positive or negative real number.

        Returns
        -------
        offset : float
            Optimal offset of the uniform logarithmic spacing of the transform that
            fulfils a low-ringing condition.

        Examples
        --------
        >>> from scipy.fft import fhtoffset
        >>> dln = 0.1
        >>> mu = 2.0
        >>> initial = 0.5
        >>> bias = 0.0
        >>> offset = fhtoffset(dln, mu, initial, bias)
        >>> offset
        0.5454581477676637

        See Also
        --------
        fht : Definition of the fast Hankel transform.

        References
        ----------
        .. [1] Hamilton A. J. S., 2000, MNRAS, 312, 257 (astro-ph/9905191)

    get_workers()
        Returns the default number of workers within the current context

        Examples
        --------
        >>> from scipy import fft
        >>> fft.get_workers()
        1
        >>> with fft.set_workers(4):
        ...     fft.get_workers()
        4

    hfft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the FFT of a signal that has Hermitian symmetry, i.e., a real
        spectrum.

        Parameters
        ----------
        x : array_like
            The input array.
        n : int, optional
            Length of the transformed axis of the output. For `n` output
            points, ``n//2 + 1`` input points are necessary. If the input is
            longer than this, it is cropped. If it is shorter than this, it is
            padded with zeros. If `n` is not given, it is taken to be ``2*(m-1)``,
            where ``m`` is the length of the input along the axis specified by
            `axis`.
        axis : int, optional
            Axis over which to compute the FFT. If not given, the last
            axis is used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See `fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.
            The length of the transformed axis is `n`, or, if `n` is not given,
            ``2*m - 2``, where ``m`` is the length of the transformed axis of
            the input. To get an odd number of output points, `n` must be
            specified, for instance, as ``2*m - 1`` in the typical case,

        Raises
        ------
        IndexError
            If `axis` is larger than the last axis of `a`.

        See Also
        --------
        rfft : Compute the 1-D FFT for real input.
        ihfft : The inverse of `hfft`.
        hfftn : Compute the N-D FFT of a Hermitian signal.

        Notes
        -----
        `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
        opposite case: here the signal has Hermitian symmetry in the time
        domain and is real in the frequency domain. So, here, it's `hfft`, for
        which you must supply the length of the result if it is to be odd.
        * even: ``ihfft(hfft(a, 2*len(a) - 2) == a``, within roundoff error,
        * odd: ``ihfft(hfft(a, 2*len(a) - 1) == a``, within roundoff error.

        Examples
        --------
        >>> from scipy.fft import fft, hfft
        >>> import numpy as np
        >>> a = 2 * np.pi * np.arange(10) / 10
        >>> signal = np.cos(a) + 3j * np.sin(3 * a)
        >>> fft(signal).round(10)
        array([ -0.+0.j,   5.+0.j,  -0.+0.j,  15.-0.j,   0.+0.j,   0.+0.j,
                -0.+0.j, -15.-0.j,   0.+0.j,   5.+0.j])
        >>> hfft(signal[:6]).round(10) # Input first half of signal
        array([  0.,   5.,   0.,  15.,  -0.,   0.,   0., -15.,  -0.,   5.])
        >>> hfft(signal, 10)  # Input entire signal and truncate
        array([  0.,   5.,   0.,  15.,  -0.,   0.,   0., -15.,  -0.,   5.])

    hfft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 2-D FFT of a Hermitian complex array.

        Parameters
        ----------
        x : array
            Input array, taken to be Hermitian complex.
        s : sequence of ints, optional
            Shape of the real output.
        axes : sequence of ints, optional
            Axes over which to compute the FFT.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See `fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The real result of the 2-D Hermitian complex real FFT.

        See Also
        --------
        hfftn : Compute the N-D discrete Fourier Transform for Hermitian
                complex input.

        Notes
        -----
        This is really just `hfftn` with different default behavior.
        For more details see `hfftn`.

    hfftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the N-D FFT of Hermitian symmetric complex input, i.e., a
        signal with a real spectrum.

        This function computes the N-D discrete Fourier Transform for a
        Hermitian symmetric complex input over any number of axes in an
        M-D array by means of the Fast Fourier Transform (FFT). In other
        words, ``ihfftn(hfftn(x, s)) == x`` to within numerical accuracy. (``s``
        here is ``x.shape`` with ``s[-1] = x.shape[-1] * 2 - 1``, this is necessary
        for the same reason ``x.shape`` would be necessary for `irfft`.)

        Parameters
        ----------
        x : array_like
            Input array.
        s : sequence of ints, optional
            Shape (length of each transformed axis) of the output
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the
            number of input points used along this axis, except for the last axis,
            where ``s[-1]//2+1`` points of the input are used.
            Along any axis, if the shape indicated by `s` is smaller than that of
            the input, the input is cropped. If it is larger, the input is padded
            with zeros. If `s` is not given, the shape of the input along the axes
            specified by axes is used. Except for the last axis which is taken to be
            ``2*(m-1)`` where ``m`` is the length of the input along that axis.
        axes : sequence of ints, optional
            Axes over which to compute the inverse FFT. If not given, the last
            `len(s)` axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` or `x`,
            as explained in the parameters section above.
            The length of each transformed axis is as given by the corresponding
            element of `s`, or the length of the input in every axis except for the
            last one if `s` is not given.  In the final transformed axis the length
            of the output when `s` is not given is ``2*(m-1)`` where ``m`` is the
            length of the final transformed axis of the input.  To get an odd
            number of output points in the final axis, `s` must be specified.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        ihfftn : The inverse N-D FFT with real spectrum. Inverse of `hfftn`.
        fft : The 1-D FFT, with definitions and conventions used.
        rfft : Forward FFT of real input.

        Notes
        -----
        For a 1-D signal ``x`` to have a real spectrum, it must satisfy
        the Hermitian property::

            x[i] == np.conj(x[-i]) for all i

        This generalizes into higher dimensions by reflecting over each axis in
        turn::

            x[i, j, k, ...] == np.conj(x[-i, -j, -k, ...]) for all i, j, k, ...

        This should not be confused with a Hermitian matrix, for which the
        transpose is its own conjugate::

            x[i, j] == np.conj(x[j, i]) for all i, j


        The default value of `s` assumes an even output length in the final
        transformation axis. When performing the final complex to real
        transformation, the Hermitian symmetry requires that the last imaginary
        component along that axis must be 0 and so it is ignored. To avoid losing
        information, the correct length of the real input *must* be given.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.ones((3, 2, 2))
        >>> scipy.fft.hfftn(x)
        array([[[12.,  0.],
                [ 0.,  0.]],
               [[ 0.,  0.],
                [ 0.,  0.]],
               [[ 0.,  0.],
                [ 0.,  0.]]])

    idct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return the Inverse Discrete Cosine Transform of an arbitrary type sequence.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the idct is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized IDCT variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        idct : ndarray of real
            The transformed input array.

        See Also
        --------
        dct : Forward DCT

        Notes
        -----
        For a single dimension array `x`, ``idct(x, norm='ortho')`` is equal to
        MATLAB ``idct(x)``.

        .. warning:: For ``type in {1, 2, 3}``, ``norm="ortho"`` breaks the direct
                     correspondence with the inverse direct Fourier transform. To
                     recover it you must specify ``orthogonalize=False``.

        For ``norm="ortho"`` both the `dct` and `idct` are scaled by the same
        overall factor in both directions. By default, the transform is also
        orthogonalized which for types 1, 2 and 3 means the transform definition is
        modified to give orthogonality of the IDCT matrix (see `dct` for the full
        definitions).

        'The' IDCT is the IDCT-II, which is the same as the normalized DCT-III.

        The IDCT is equivalent to a normal DCT except for the normalization and
        type. DCT type 1 and 4 are their own inverse and DCTs 2 and 3 are each
        other's inverses.

        Examples
        --------
        The Type 1 DCT is equivalent to the DFT for real, even-symmetrical
        inputs. The output is also real and even-symmetrical. Half of the IFFT
        input is used to generate half of the IFFT output:

        >>> from scipy.fft import ifft, idct
        >>> import numpy as np
        >>> ifft(np.array([ 30.,  -8.,   6.,  -2.,   6.,  -8.])).real
        array([  4.,   3.,   5.,  10.,   5.,   3.])
        >>> idct(np.array([ 30.,  -8.,   6.,  -2.]), 1)
        array([  4.,   3.,   5.,  10.])

    idctn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return multidimensional Inverse Discrete Cosine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        s : int or array_like of ints or None, optional
            The shape of the result.  If both `s` and `axes` (see below) are
            None, `s` is ``x.shape``; if `s` is None but `axes` is
            not None, then `s` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``s[i] > x.shape[i]``, the ith dimension of the input is padded with zeros.
            If ``s[i] < x.shape[i]``, the ith dimension of the input is truncated to length
            ``s[i]``.
            If any element of `s` is -1, the size of the corresponding dimension of
            `x` is used.
        axes : int or array_like of ints or None, optional
            Axes over which the IDCT is computed. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized IDCT variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        dctn : multidimensional DCT

        Notes
        -----
        For full details of the IDCT types and normalization modes, as well as
        references, see `idct`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fft import dctn, idctn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idctn(dctn(y)))
        True

    idst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return the Inverse Discrete Sine Transform of an arbitrary type sequence.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        n : int, optional
            Length of the transform. If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the idst is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized IDST variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        idst : ndarray of real
            The transformed input array.

        See Also
        --------
        dst : Forward DST

        Notes
        -----
        .. warning:: For ``type in {2, 3}``, ``norm="ortho"`` breaks the direct
                     correspondence with the inverse direct Fourier transform.

        For ``norm="ortho"`` both the `dst` and `idst` are scaled by the same
        overall factor in both directions. By default, the transform is also
        orthogonalized which for types 2 and 3 means the transform definition is
        modified to give orthogonality of the DST matrix (see `dst` for the full
        definitions).

        'The' IDST is the IDST-II, which is the same as the normalized DST-III.

        The IDST is equivalent to a normal DST except for the normalization and
        type. DST type 1 and 4 are their own inverse and DSTs 2 and 3 are each
        other's inverses.

    idstn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, orthogonalize=None)
        Return multidimensional Inverse Discrete Sine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        s : int or array_like of ints or None, optional
            The shape of the result.  If both `s` and `axes` (see below) are None,
            `s` is ``x.shape``; if `s` is None but `axes` is not None, then `s` is
            ``numpy.take(x.shape, axes, axis=0)``.
            If ``s[i] > x.shape[i]``, the ith dimension of the input is padded with zeros.
            If ``s[i] < x.shape[i]``, the ith dimension of the input is truncated to length
            ``s[i]``.
            If any element of `s` is -1, the size of the corresponding dimension of
            `x` is used.
        axes : int or array_like of ints or None, optional
            Axes over which the IDST is computed. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see Notes). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        orthogonalize : bool, optional
            Whether to use the orthogonalized IDST variant (see Notes).
            Defaults to ``True`` when ``norm="ortho"`` and ``False`` otherwise.

            .. versionadded:: 1.8.0

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        dstn : multidimensional DST

        Notes
        -----
        For full details of the IDST types and normalization modes, as well as
        references, see `idst`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fft import dstn, idstn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idstn(dstn(y)))
        True

    ifft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 1-D inverse discrete Fourier Transform.

        This function computes the inverse of the 1-D *n*-point
        discrete Fourier transform computed by `fft`.  In other words,
        ``ifft(fft(x)) == x`` to within numerical accuracy.

        The input should be ordered in the same way as is returned by `fft`,
        i.e.,

        * ``x[0]`` should contain the zero frequency term,
        * ``x[1:n//2]`` should contain the positive-frequency terms,
        * ``x[n//2 + 1:]`` should contain the negative-frequency terms, in
          increasing order starting from the most negative frequency.

        For an even number of input points, ``x[n//2]`` represents the sum of
        the values at the positive and negative Nyquist frequencies, as the two
        are aliased together. See `fft` for details.

        Parameters
        ----------
        x : array_like
            Input array, can be complex.
        n : int, optional
            Length of the transformed axis of the output.
            If `n` is smaller than the length of the input, the input is cropped.
            If it is larger, the input is padded with zeros. If `n` is not given,
            the length of the input along the axis specified by `axis` is used.
            See notes about padding issues.
        axis : int, optional
            Axis over which to compute the inverse DFT. If not given, the last
            axis is used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.

        Raises
        ------
        IndexError
            If `axes` is larger than the last axis of `x`.

        See Also
        --------
        fft : The 1-D (forward) FFT, of which `ifft` is the inverse.
        ifft2 : The 2-D inverse FFT.
        ifftn : The N-D inverse FFT.

        Notes
        -----
        If the input parameter `n` is larger than the size of the input, the input
        is padded by appending zeros at the end. Even though this is the common
        approach, it might lead to surprising results. If a different padding is
        desired, it must be performed before calling `ifft`.

        If ``x`` is a 1-D array, then the `ifft` is equivalent to ::

            y[k] = np.sum(x * np.exp(2j * np.pi * k * np.arange(n)/n)) / len(x)

        As with `fft`, `ifft` has support for all floating point types and is
        optimized for real input.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> scipy.fft.ifft([0, 4, 0, 0])
        array([ 1.+0.j,  0.+1.j, -1.+0.j,  0.-1.j]) # may vary

        Create and plot a band-limited signal with random phases:

        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> t = np.arange(400)
        >>> n = np.zeros((400,), dtype=complex)
        >>> n[40:60] = np.exp(1j*rng.uniform(0, 2*np.pi, (20,)))
        >>> s = scipy.fft.ifft(n)
        >>> plt.plot(t, s.real, 'b-', t, s.imag, 'r--')
        [<matplotlib.lines.Line2D object at ...>, <matplotlib.lines.Line2D object at ...>]
        >>> plt.legend(('real', 'imaginary'))
        <matplotlib.legend.Legend object at ...>
        >>> plt.show()

    ifft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 2-D inverse discrete Fourier Transform.

        This function computes the inverse of the 2-D discrete Fourier
        Transform over any number of axes in an M-D array by means of
        the Fast Fourier Transform (FFT). In other words, ``ifft2(fft2(x)) == x``
        to within numerical accuracy. By default, the inverse transform is
        computed over the last two axes of the input array.

        The input, analogously to `ifft`, should be ordered in the same way as is
        returned by `fft2`, i.e., it should have the term for zero frequency
        in the low-order corner of the two axes, the positive frequency terms in
        the first half of these axes, the term for the Nyquist frequency in the
        middle of the axes and the negative frequency terms in the second half of
        both axes, in order of decreasingly negative frequency.

        Parameters
        ----------
        x : array_like
            Input array, can be complex.
        s : sequence of ints, optional
            Shape (length of each axis) of the output (``s[0]`` refers to axis 0,
            ``s[1]`` to axis 1, etc.). This corresponds to `n` for ``ifft(x, n)``.
            Along each axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used.  See notes for issue on `ifft` zero padding.
        axes : sequence of ints, optional
            Axes over which to compute the FFT. If not given, the last two
            axes are used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or the last two axes if `axes` is not given.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length, or `axes` not given and
            ``len(s) != 2``.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        fft2 : The forward 2-D FFT, of which `ifft2` is the inverse.
        ifftn : The inverse of the N-D FFT.
        fft : The 1-D FFT.
        ifft : The 1-D inverse FFT.

        Notes
        -----
        `ifft2` is just `ifftn` with a different default for `axes`.

        See `ifftn` for details and a plotting example, and `fft` for
        definition and conventions used.

        Zero-padding, analogously with `ifft`, is performed by appending zeros to
        the input along the specified dimension. Although this is the common
        approach, it might lead to surprising results. If another form of zero
        padding is desired, it must be performed before `ifft2` is called.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = 4 * np.eye(4)
        >>> scipy.fft.ifft2(x)
        array([[1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j], # may vary
               [0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j],
               [0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
               [0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j]])

    ifftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the N-D inverse discrete Fourier Transform.

        This function computes the inverse of the N-D discrete
        Fourier Transform over any number of axes in an M-D array by
        means of the Fast Fourier Transform (FFT).  In other words,
        ``ifftn(fftn(x)) == x`` to within numerical accuracy.

        The input, analogously to `ifft`, should be ordered in the same way as is
        returned by `fftn`, i.e., it should have the term for zero frequency
        in all axes in the low-order corner, the positive frequency terms in the
        first half of all axes, the term for the Nyquist frequency in the middle
        of all axes and the negative frequency terms in the second half of all
        axes, in order of decreasingly negative frequency.

        Parameters
        ----------
        x : array_like
            Input array, can be complex.
        s : sequence of ints, optional
            Shape (length of each transformed axis) of the output
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
            This corresponds to ``n`` for ``ifft(x, n)``.
            Along any axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used. See notes for issue on `ifft` zero padding.
        axes : sequence of ints, optional
            Axes over which to compute the IFFT.  If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` or `x`,
            as explained in the parameters section above.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        fftn : The forward N-D FFT, of which `ifftn` is the inverse.
        ifft : The 1-D inverse FFT.
        ifft2 : The 2-D inverse FFT.
        ifftshift : Undoes `fftshift`, shifts zero-frequency terms to beginning
            of array.

        Notes
        -----
        Zero-padding, analogously with `ifft`, is performed by appending zeros to
        the input along the specified dimension. Although this is the common
        approach, it might lead to surprising results. If another form of zero
        padding is desired, it must be performed before `ifftn` is called.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.eye(4)
        >>> scipy.fft.ifftn(scipy.fft.fftn(x, axes=(0,)), axes=(1,))
        array([[1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j], # may vary
               [0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],
               [0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
               [0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j]])


        Create and plot an image with band-limited frequency content:

        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> n = np.zeros((200,200), dtype=complex)
        >>> n[60:80, 20:40] = np.exp(1j*rng.uniform(0, 2*np.pi, (20, 20)))
        >>> im = scipy.fft.ifftn(n).real
        >>> plt.imshow(im)
        <matplotlib.image.AxesImage object at 0x...>
        >>> plt.show()

    ifftshift(x, axes=None)
        The inverse of `fftshift`. Although identical for even-length `x`, the
        functions differ by one sample for odd-length `x`.

        Parameters
        ----------
        x : array_like
            Input array.
        axes : int or shape tuple, optional
            Axes over which to calculate.  Defaults to None, which shifts all axes.

        Returns
        -------
        y : ndarray
            The shifted array.

        See Also
        --------
        fftshift : Shift zero-frequency component to the center of the spectrum.

        Examples
        --------
        >>> import numpy as np
        >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
        >>> freqs
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])
        >>> np.fft.ifftshift(np.fft.fftshift(freqs))
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])

    ifht(A, dln, mu, offset=0.0, bias=0.0)
        Compute the inverse fast Hankel transform.

        Computes the discrete inverse Hankel transform of a logarithmically spaced
        periodic sequence. This is the inverse operation to `fht`.

        Parameters
        ----------
        A : array_like (..., n)
            Real periodic input array, uniformly logarithmically spaced.  For
            multidimensional input, the transform is performed over the last axis.
        dln : float
            Uniform logarithmic spacing of the input array.
        mu : float
            Order of the Hankel transform, any positive or negative real number.
        offset : float, optional
            Offset of the uniform logarithmic spacing of the output array.
        bias : float, optional
            Exponent of power law bias, any positive or negative real number.

        Returns
        -------
        a : array_like (..., n)
            The transformed output array, which is real, periodic, uniformly
            logarithmically spaced, and of the same shape as the input array.

        See Also
        --------
        fht : Definition of the fast Hankel transform.
        fhtoffset : Return an optimal offset for `ifht`.

        Notes
        -----
        This function computes a discrete version of the Hankel transform

        .. math::

            a(r) = \int_{0}^{\infty} \! A(k) \, J_\mu(kr) \, r \, dk \;,

        where :math:`J_\mu` is the Bessel function of order :math:`\mu`.  The index
        :math:`\mu` may be any real number, positive or negative. Note that the
        numerical inverse Hankel transform uses an integrand of :math:`r \, dk`, while the
        mathematical inverse Hankel transform is commonly defined using :math:`k \, dk`.

        See `fht` for further details.

    ihfft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the inverse FFT of a signal that has Hermitian symmetry.

        Parameters
        ----------
        x : array_like
            Input array.
        n : int, optional
            Length of the inverse FFT, the number of points along
            transformation axis in the input to use.  If `n` is smaller than
            the length of the input, the input is cropped. If it is larger,
            the input is padded with zeros. If `n` is not given, the length of
            the input along the axis specified by `axis` is used.
        axis : int, optional
            Axis over which to compute the inverse FFT. If not given, the last
            axis is used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See `fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.
            The length of the transformed axis is ``n//2 + 1``.

        See Also
        --------
        hfft, irfft

        Notes
        -----
        `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the
        opposite case: here, the signal has Hermitian symmetry in the time
        domain and is real in the frequency domain. So, here, it's `hfft`, for
        which you must supply the length of the result if it is to be odd:
        * even: ``ihfft(hfft(a, 2*len(a) - 2) == a``, within roundoff error,
        * odd: ``ihfft(hfft(a, 2*len(a) - 1) == a``, within roundoff error.

        Examples
        --------
        >>> from scipy.fft import ifft, ihfft
        >>> import numpy as np
        >>> spectrum = np.array([ 15, -4, 0, -1, 0, -4])
        >>> ifft(spectrum)
        array([1.+0.j,  2.+0.j,  3.+0.j,  4.+0.j,  3.+0.j,  2.+0.j]) # may vary
        >>> ihfft(spectrum)
        array([ 1.-0.j,  2.-0.j,  3.-0.j,  4.-0.j]) # may vary

    ihfft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 2-D inverse FFT of a real spectrum.

        Parameters
        ----------
        x : array_like
            The input array
        s : sequence of ints, optional
            Shape of the real input to the inverse FFT.
        axes : sequence of ints, optional
            The axes over which to compute the inverse fft.
            Default is the last two axes.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The result of the inverse real 2-D FFT.

        See Also
        --------
        ihfftn : Compute the inverse of the N-D FFT of Hermitian input.

        Notes
        -----
        This is really `ihfftn` with different defaults.
        For more details see `ihfftn`.

    ihfftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the N-D inverse discrete Fourier Transform for a real
        spectrum.

        This function computes the N-D inverse discrete Fourier Transform
        over any number of axes in an M-D real array by means of the Fast
        Fourier Transform (FFT). By default, all axes are transformed, with the
        real transform performed over the last axis, while the remaining transforms
        are complex.

        Parameters
        ----------
        x : array_like
            Input array, taken to be real.
        s : sequence of ints, optional
            Shape (length along each transformed axis) to use from the input.
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
            Along any axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used.
        axes : sequence of ints, optional
            Axes over which to compute the FFT. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` and `x`,
            as explained in the parameters section above.
            The length of the last axis transformed will be ``s[-1]//2+1``,
            while the remaining transformed axes will have lengths according to
            `s`, or unchanged from the input.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        hfftn : The forward N-D FFT of Hermitian input.
        hfft : The 1-D FFT of Hermitian input.
        fft : The 1-D FFT, with definitions and conventions used.
        fftn : The N-D FFT.
        hfft2 : The 2-D FFT of Hermitian input.

        Notes
        -----
        The transform for real input is performed over the last transformation
        axis, as by `ihfft`, then the transform over the remaining axes is
        performed as by `ifftn`. The order of the output is the positive part of
        the Hermitian output signal, in the same format as `rfft`.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.ones((2, 2, 2))
        >>> scipy.fft.ihfftn(x)
        array([[[1.+0.j,  0.+0.j], # may vary
                [0.+0.j,  0.+0.j]],
               [[0.+0.j,  0.+0.j],
                [0.+0.j,  0.+0.j]]])
        >>> scipy.fft.ihfftn(x, axes=(2, 0))
        array([[[1.+0.j,  0.+0.j], # may vary
                [1.+0.j,  0.+0.j]],
               [[0.+0.j,  0.+0.j],
                [0.+0.j,  0.+0.j]]])

    irfft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Computes the inverse of `rfft`.

        This function computes the inverse of the 1-D *n*-point
        discrete Fourier Transform of real input computed by `rfft`.
        In other words, ``irfft(rfft(x), len(x)) == x`` to within numerical
        accuracy. (See Notes below for why ``len(a)`` is necessary here.)

        The input is expected to be in the form returned by `rfft`, i.e., the
        real zero-frequency term followed by the complex positive frequency terms
        in order of increasing frequency. Since the discrete Fourier Transform of
        real input is Hermitian-symmetric, the negative frequency terms are taken
        to be the complex conjugates of the corresponding positive frequency terms.

        Parameters
        ----------
        x : array_like
            The input array.
        n : int, optional
            Length of the transformed axis of the output.
            For `n` output points, ``n//2+1`` input points are necessary. If the
            input is longer than this, it is cropped. If it is shorter than this,
            it is padded with zeros. If `n` is not given, it is taken to be
            ``2*(m-1)``, where ``m`` is the length of the input along the axis
            specified by `axis`.
        axis : int, optional
            Axis over which to compute the inverse FFT. If not given, the last
            axis is used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.
            The length of the transformed axis is `n`, or, if `n` is not given,
            ``2*(m-1)`` where ``m`` is the length of the transformed axis of the
            input. To get an odd number of output points, `n` must be specified.

        Raises
        ------
        IndexError
            If `axis` is larger than the last axis of `x`.

        See Also
        --------
        rfft : The 1-D FFT of real input, of which `irfft` is inverse.
        fft : The 1-D FFT.
        irfft2 : The inverse of the 2-D FFT of real input.
        irfftn : The inverse of the N-D FFT of real input.

        Notes
        -----
        Returns the real valued `n`-point inverse discrete Fourier transform
        of `x`, where `x` contains the non-negative frequency terms of a
        Hermitian-symmetric sequence. `n` is the length of the result, not the
        input.

        If you specify an `n` such that `a` must be zero-padded or truncated, the
        extra/removed values will be added/removed at high frequencies. One can
        thus resample a series to `m` points via Fourier interpolation by:
        ``a_resamp = irfft(rfft(a), m)``.

        The default value of `n` assumes an even output length. By the Hermitian
        symmetry, the last imaginary component must be 0 and so is ignored. To
        avoid losing information, the correct length of the real input *must* be
        given.

        Examples
        --------
        >>> import scipy.fft
        >>> scipy.fft.ifft([1, -1j, -1, 1j])
        array([0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j]) # may vary
        >>> scipy.fft.irfft([1, -1j, -1])
        array([0.,  1.,  0.,  0.])

        Notice how the last term in the input to the ordinary `ifft` is the
        complex conjugate of the second term, and the output has zero imaginary
        part everywhere. When calling `irfft`, the negative frequencies are not
        specified, and the output array is purely real.

    irfft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Computes the inverse of `rfft2`

        Parameters
        ----------
        x : array_like
            The input array
        s : sequence of ints, optional
            Shape of the real output to the inverse FFT.
        axes : sequence of ints, optional
            The axes over which to compute the inverse fft.
            Default is the last two axes.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The result of the inverse real 2-D FFT.

        See Also
        --------
        rfft2 : The 2-D FFT of real input.
        irfft : The inverse of the 1-D FFT of real input.
        irfftn : The inverse of the N-D FFT of real input.

        Notes
        -----
        This is really `irfftn` with different defaults.
        For more details see `irfftn`.

    irfftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Computes the inverse of `rfftn`

        This function computes the inverse of the N-D discrete
        Fourier Transform for real input over any number of axes in an
        M-D array by means of the Fast Fourier Transform (FFT). In
        other words, ``irfftn(rfftn(x), x.shape) == x`` to within numerical
        accuracy. (The ``a.shape`` is necessary like ``len(a)`` is for `irfft`,
        and for the same reason.)

        The input should be ordered in the same way as is returned by `rfftn`,
        i.e., as for `irfft` for the final transformation axis, and as for `ifftn`
        along all the other axes.

        Parameters
        ----------
        x : array_like
            Input array.
        s : sequence of ints, optional
            Shape (length of each transformed axis) of the output
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the
            number of input points used along this axis, except for the last axis,
            where ``s[-1]//2+1`` points of the input are used.
            Along any axis, if the shape indicated by `s` is smaller than that of
            the input, the input is cropped. If it is larger, the input is padded
            with zeros. If `s` is not given, the shape of the input along the axes
            specified by axes is used. Except for the last axis which is taken to be
            ``2*(m-1)``, where ``m`` is the length of the input along that axis.
        axes : sequence of ints, optional
            Axes over which to compute the inverse FFT. If not given, the last
            `len(s)` axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` or `x`,
            as explained in the parameters section above.
            The length of each transformed axis is as given by the corresponding
            element of `s`, or the length of the input in every axis except for the
            last one if `s` is not given. In the final transformed axis the length
            of the output when `s` is not given is ``2*(m-1)``, where ``m`` is the
            length of the final transformed axis of the input. To get an odd
            number of output points in the final axis, `s` must be specified.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        rfftn : The forward N-D FFT of real input,
                of which `ifftn` is the inverse.
        fft : The 1-D FFT, with definitions and conventions used.
        irfft : The inverse of the 1-D FFT of real input.
        irfft2 : The inverse of the 2-D FFT of real input.

        Notes
        -----
        See `fft` for definitions and conventions used.

        See `rfft` for definitions and conventions used for real input.

        The default value of `s` assumes an even output length in the final
        transformation axis. When performing the final complex to real
        transformation, the Hermitian symmetry requires that the last imaginary
        component along that axis must be 0 and so it is ignored. To avoid losing
        information, the correct length of the real input *must* be given.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.zeros((3, 2, 2))
        >>> x[0, 0, 0] = 3 * 2 * 2
        >>> scipy.fft.irfftn(x)
        array([[[1.,  1.],
                [1.,  1.]],
               [[1.,  1.],
                [1.,  1.]],
               [[1.,  1.],
                [1.,  1.]]])

    next_fast_len(target, real=False)
        Find the next fast size of input data to ``fft``, for zero-padding, etc.

        SciPy's FFT algorithms gain their speed by a recursive divide and conquer
        strategy. This relies on efficient functions for small prime factors of the
        input length. Thus, the transforms are fastest when using composites of the
        prime factors handled by the fft implementation. If there are efficient
        functions for all radices <= `n`, then the result will be a number `x`
        >= ``target`` with only prime factors < `n`. (Also known as `n`-smooth
        numbers)

        Parameters
        ----------
        target : int
            Length to start searching from. Must be a positive integer.
        real : bool, optional
            True if the FFT involves real input or output (e.g., `rfft` or `hfft`
            but not `fft`). Defaults to False.

        Returns
        -------
        out : int
            The smallest fast length greater than or equal to ``target``.

        Notes
        -----
        The result of this function may change in future as performance
        considerations change, for example, if new prime factors are added.

        Calling `fft` or `ifft` with real input data performs an ``'R2C'``
        transform internally.

        Examples
        --------
        On a particular machine, an FFT of prime length takes 11.4 ms:

        >>> from scipy import fft
        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> min_len = 93059  # prime length is worst case for speed
        >>> a = rng.standard_normal(min_len)
        >>> b = fft.fft(a)

        Zero-padding to the next regular length reduces computation time to
        1.6 ms, a speedup of 7.3 times:

        >>> fft.next_fast_len(min_len, real=True)
        93312
        >>> b = fft.fft(a, 93312)

        Rounding up to the next power of 2 is not optimal, taking 3.0 ms to
        compute; 1.9 times longer than the size given by ``next_fast_len``:

        >>> b = fft.fft(a, 131072)

    prev_fast_len(target, real=False)
        Find the previous fast size of input data to ``fft``.
        Useful for discarding a minimal number of samples before FFT.

        SciPy's FFT algorithms gain their speed by a recursive divide and conquer
        strategy. This relies on efficient functions for small prime factors of the
        input length. Thus, the transforms are fastest when using composites of the
        prime factors handled by the fft implementation. If there are efficient
        functions for all radices <= `n`, then the result will be a number `x`
        <= ``target`` with only prime factors <= `n`. (Also known as `n`-smooth
        numbers)

        Parameters
        ----------
        target : int
            Maximum length to search until. Must be a positive integer.
        real : bool, optional
            True if the FFT involves real input or output (e.g., `rfft` or `hfft`
            but not `fft`). Defaults to False.

        Returns
        -------
        out : int
            The largest fast length less than or equal to ``target``.

        Notes
        -----
        The result of this function may change in future as performance
        considerations change, for example, if new prime factors are added.

        Calling `fft` or `ifft` with real input data performs an ``'R2C'``
        transform internally.

        In the current implementation, prev_fast_len assumes radices of
        2,3,5,7,11 for complex FFT and 2,3,5 for real FFT.

        Examples
        --------
        On a particular machine, an FFT of prime length takes 16.2 ms:

        >>> from scipy import fft
        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> max_len = 93059  # prime length is worst case for speed
        >>> a = rng.standard_normal(max_len)
        >>> b = fft.fft(a)

        Performing FFT on the maximum fast length less than max_len
        reduces the computation time to 1.5 ms, a speedup of 10.5 times:

        >>> fft.prev_fast_len(max_len, real=True)
        92160
        >>> c = fft.fft(a[:92160]) # discard last 899 samples

    register_backend(backend)
        Register a backend for permanent use.

        Registered backends have the lowest priority and will be tried after the
        global backend.

        Parameters
        ----------
        backend : {object, 'scipy'}
            The backend to use.
            Can either be a ``str`` containing the name of a known backend
            {'scipy'} or an object that implements the uarray protocol.

        Raises
        ------
        ValueError: If the backend does not implement ``numpy.scipy.fft``.

        Examples
        --------
        We can register a new fft backend:

        >>> from scipy.fft import fft, register_backend, set_global_backend
        >>> class NoopBackend:  # Define an invalid Backend
        ...     __ua_domain__ = "numpy.scipy.fft"
        ...     def __ua_function__(self, func, args, kwargs):
        ...          return NotImplemented
        >>> set_global_backend(NoopBackend())  # Set the invalid backend as global
        >>> register_backend("scipy")  # Register a new backend
        # The registered backend is called because
        # the global backend returns `NotImplemented`
        >>> fft([1])
        array([1.+0.j])
        >>> set_global_backend("scipy")  # Restore global backend to default

    rfft(x, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 1-D discrete Fourier Transform for real input.

        This function computes the 1-D *n*-point discrete Fourier
        Transform (DFT) of a real-valued array by means of an efficient algorithm
        called the Fast Fourier Transform (FFT).

        Parameters
        ----------
        x : array_like
            Input array
        n : int, optional
            Number of points along transformation axis in the input to use.
            If `n` is smaller than the length of the input, the input is cropped.
            If it is larger, the input is padded with zeros. If `n` is not given,
            the length of the input along the axis specified by `axis` is used.
        axis : int, optional
            Axis over which to compute the FFT. If not given, the last axis is
            used.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axis
            indicated by `axis`, or the last one if `axis` is not specified.
            If `n` is even, the length of the transformed axis is ``(n/2)+1``.
            If `n` is odd, the length is ``(n+1)/2``.

        Raises
        ------
        IndexError
            If `axis` is larger than the last axis of `a`.

        See Also
        --------
        irfft : The inverse of `rfft`.
        fft : The 1-D FFT of general (complex) input.
        fftn : The N-D FFT.
        rfft2 : The 2-D FFT of real input.
        rfftn : The N-D FFT of real input.

        Notes
        -----
        When the DFT is computed for purely real input, the output is
        Hermitian-symmetric, i.e., the negative frequency terms are just the complex
        conjugates of the corresponding positive-frequency terms, and the
        negative-frequency terms are therefore redundant. This function does not
        compute the negative frequency terms, and the length of the transformed
        axis of the output is therefore ``n//2 + 1``.

        When ``X = rfft(x)`` and fs is the sampling frequency, ``X[0]`` contains
        the zero-frequency term 0*fs, which is real due to Hermitian symmetry.

        If `n` is even, ``A[-1]`` contains the term representing both positive
        and negative Nyquist frequency (+fs/2 and -fs/2), and must also be purely
        real. If `n` is odd, there is no term at fs/2; ``A[-1]`` contains
        the largest positive frequency (fs/2*(n-1)/n), and is complex in the
        general case.

        If the input `a` contains an imaginary part, it is silently discarded.

        Examples
        --------
        >>> import scipy.fft
        >>> scipy.fft.fft([0, 1, 0, 0])
        array([ 1.+0.j,  0.-1.j, -1.+0.j,  0.+1.j]) # may vary
        >>> scipy.fft.rfft([0, 1, 0, 0])
        array([ 1.+0.j,  0.-1.j, -1.+0.j]) # may vary

        Notice how the final element of the `fft` output is the complex conjugate
        of the second element, for real input. For `rfft`, this symmetry is
        exploited to compute only the non-negative frequency terms.

    rfft2(x, s=None, axes=(-2, -1), norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the 2-D FFT of a real array.

        Parameters
        ----------
        x : array
            Input array, taken to be real.
        s : sequence of ints, optional
            Shape of the FFT.
        axes : sequence of ints, optional
            Axes over which to compute the FFT.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : ndarray
            The result of the real 2-D FFT.

        See Also
        --------
        irfft2 : The inverse of the 2-D FFT of real input.
        rfft : The 1-D FFT of real input.
        rfftn : Compute the N-D discrete Fourier Transform for real
                input.

        Notes
        -----
        This is really just `rfftn` with different default behavior.
        For more details see `rfftn`.

    rfftfreq(n, d=1.0, *, xp=None, device=None)
        Return the Discrete Fourier Transform sample frequencies
        (for usage with rfft, irfft).

        The returned float array `f` contains the frequency bin centers in cycles
        per unit of the sample spacing (with zero at the start).  For instance, if
        the sample spacing is in seconds, then the frequency unit is cycles/second.

        Given a window length `n` and a sample spacing `d`::

          f = [0, 1, ...,     n/2-1,     n/2] / (d*n)   if n is even
          f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n)   if n is odd

        Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`)
        the Nyquist frequency component is considered to be positive.

        Parameters
        ----------
        n : int
            Window length.
        d : scalar, optional
            Sample spacing (inverse of the sampling rate). Defaults to 1.
        xp : array_namespace, optional
            The namespace for the return array. Default is None, where NumPy is used.
        device : device, optional
            The device for the return array.
            Only valid when `xp.fft.rfftfreq` implements the device parameter.

        Returns
        -------
        f : ndarray
            Array of length ``n//2 + 1`` containing the sample frequencies.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.fft
        >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float)
        >>> fourier = scipy.fft.rfft(signal)
        >>> n = signal.size
        >>> sample_rate = 100
        >>> freq = scipy.fft.fftfreq(n, d=1./sample_rate)
        >>> freq
        array([  0.,  10.,  20., ..., -30., -20., -10.])
        >>> freq = scipy.fft.rfftfreq(n, d=1./sample_rate)
        >>> freq
        array([  0.,  10.,  20.,  30.,  40.,  50.])

    rfftn(x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None)
        Compute the N-D discrete Fourier Transform for real input.

        This function computes the N-D discrete Fourier Transform over
        any number of axes in an M-D real array by means of the Fast
        Fourier Transform (FFT). By default, all axes are transformed, with the
        real transform performed over the last axis, while the remaining
        transforms are complex.

        Parameters
        ----------
        x : array_like
            Input array, taken to be real.
        s : sequence of ints, optional
            Shape (length along each transformed axis) to use from the input.
            (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.).
            The final element of `s` corresponds to `n` for ``rfft(x, n)``, while
            for the remaining axes, it corresponds to `n` for ``fft(x, n)``.
            Along any axis, if the given shape is smaller than that of the input,
            the input is cropped. If it is larger, the input is padded with zeros.
            if `s` is not given, the shape of the input along the axes specified
            by `axes` is used.
        axes : sequence of ints, optional
            Axes over which to compute the FFT. If not given, the last ``len(s)``
            axes are used, or all axes if `s` is also not specified.
        norm : {"backward", "ortho", "forward"}, optional
            Normalization mode (see `fft`). Default is "backward".
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.
            See :func:`fft` for more details.
        workers : int, optional
            Maximum number of workers to use for parallel computation. If negative,
            the value wraps around from ``os.cpu_count()``.
            See :func:`~scipy.fft.fft` for more details.
        plan : object, optional
            This argument is reserved for passing in a precomputed plan provided
            by downstream FFT vendors. It is currently not used in SciPy.

            .. versionadded:: 1.5.0

        Returns
        -------
        out : complex ndarray
            The truncated or zero-padded input, transformed along the axes
            indicated by `axes`, or by a combination of `s` and `x`,
            as explained in the parameters section above.
            The length of the last axis transformed will be ``s[-1]//2+1``,
            while the remaining transformed axes will have lengths according to
            `s`, or unchanged from the input.

        Raises
        ------
        ValueError
            If `s` and `axes` have different length.
        IndexError
            If an element of `axes` is larger than the number of axes of `x`.

        See Also
        --------
        irfftn : The inverse of `rfftn`, i.e., the inverse of the N-D FFT
             of real input.
        fft : The 1-D FFT, with definitions and conventions used.
        rfft : The 1-D FFT of real input.
        fftn : The N-D FFT.
        rfft2 : The 2-D FFT of real input.

        Notes
        -----
        The transform for real input is performed over the last transformation
        axis, as by `rfft`, then the transform over the remaining axes is
        performed as by `fftn`. The order of the output is as for `rfft` for the
        final transformation axis, and as for `fftn` for the remaining
        transformation axes.

        See `fft` for details, definitions and conventions used.

        Examples
        --------
        >>> import scipy.fft
        >>> import numpy as np
        >>> x = np.ones((2, 2, 2))
        >>> scipy.fft.rfftn(x)
        array([[[8.+0.j,  0.+0.j], # may vary
                [0.+0.j,  0.+0.j]],
               [[0.+0.j,  0.+0.j],
                [0.+0.j,  0.+0.j]]])

        >>> scipy.fft.rfftn(x, axes=(2, 0))
        array([[[4.+0.j,  0.+0.j], # may vary
                [4.+0.j,  0.+0.j]],
               [[0.+0.j,  0.+0.j],
                [0.+0.j,  0.+0.j]]])

    set_backend(backend, coerce=False, only=False)
        Context manager to set the backend within a fixed scope.

        Upon entering the ``with`` statement, the given backend will be added to
        the list of available backends with the highest priority. Upon exit, the
        backend is reset to the state before entering the scope.

        Parameters
        ----------
        backend : {object, 'scipy'}
            The backend to use.
            Can either be a ``str`` containing the name of a known backend
            {'scipy'} or an object that implements the uarray protocol.
        coerce : bool, optional
            Whether to allow expensive conversions for the ``x`` parameter. e.g.,
            copying a NumPy array to the GPU for a CuPy backend. Implies ``only``.
        only : bool, optional
            If only is ``True`` and this backend returns ``NotImplemented``, then a
            BackendNotImplemented error will be raised immediately. Ignoring any
            lower priority backends.

        Examples
        --------
        >>> import scipy.fft as fft
        >>> with fft.set_backend('scipy', only=True):
        ...     fft.fft([1])  # Always calls the scipy implementation
        array([1.+0.j])

    set_global_backend(backend, coerce=False, only=False, try_last=False)
        Sets the global fft backend

        This utility method replaces the default backend for permanent use. It
        will be tried in the list of backends automatically, unless the
        ``only`` flag is set on a backend. This will be the first tried
        backend outside the :obj:`set_backend` context manager.

        Parameters
        ----------
        backend : {object, 'scipy'}
            The backend to use.
            Can either be a ``str`` containing the name of a known backend
            {'scipy'} or an object that implements the uarray protocol.
        coerce : bool
            Whether to coerce input types when trying this backend.
        only : bool
            If ``True``, no more backends will be tried if this fails.
            Implied by ``coerce=True``.
        try_last : bool
            If ``True``, the global backend is tried after registered backends.

        Raises
        ------
        ValueError: If the backend does not implement ``numpy.scipy.fft``.

        Notes
        -----
        This will overwrite the previously set global backend, which, by default, is
        the SciPy implementation.

        Examples
        --------
        We can set the global fft backend:

        >>> from scipy.fft import fft, set_global_backend
        >>> set_global_backend("scipy")  # Sets global backend (default is "scipy").
        >>> fft([1])  # Calls the global backend
        array([1.+0.j])

    set_workers(workers)
        Context manager for the default number of workers used in `scipy.fft`

        Parameters
        ----------
        workers : int
            The default number of workers to use

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import fft, signal
        >>> rng = np.random.default_rng()
        >>> x = rng.standard_normal((128, 64))
        >>> with fft.set_workers(4):
        ...     y = signal.fftconvolve(x, x)

    skip_backend(backend)
        Context manager to skip a backend within a fixed scope.

        Within the context of a ``with`` statement, the given backend will not be
        called. This covers backends registered both locally and globally. Upon
        exit, the backend will again be considered.

        Parameters
        ----------
        backend : {object, 'scipy'}
            The backend to skip.
            Can either be a ``str`` containing the name of a known backend
            {'scipy'} or an object that implements the uarray protocol.

        Examples
        --------
        >>> import scipy.fft as fft
        >>> fft.fft([1])  # Calls default SciPy backend
        array([1.+0.j])
        >>> with fft.skip_backend('scipy'):  # We explicitly skip the SciPy backend
        ...     fft.fft([1])                 # leaving no implementation available
        Traceback (most recent call last):
            ...
        BackendNotImplementedError: No selected backends had an implementation ...

DATA
    __all__ = ['fft', 'ifft', 'fft2', 'ifft2', 'fftn', 'ifftn', 'rfft', 'i...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\fft\__init__.py

scipy.fftpack
Python Library Documentation: package scipy.fftpack in scipy

NAME
    scipy.fftpack

DESCRIPTION
    =========================================================
    Legacy discrete Fourier transforms (:mod:`scipy.fftpack`)
    =========================================================

    .. legacy::

       New code should use :mod:`scipy.fft`.

    Fast Fourier Transforms (FFTs)
    ==============================

    .. autosummary::
       :toctree: generated/

       fft - Fast (discrete) Fourier Transform (FFT)
       ifft - Inverse FFT
       fft2 - 2-D FFT
       ifft2 - 2-D inverse FFT
       fftn - N-D FFT
       ifftn - N-D inverse FFT
       rfft - FFT of strictly real-valued sequence
       irfft - Inverse of rfft
       dct - Discrete cosine transform
       idct - Inverse discrete cosine transform
       dctn - N-D Discrete cosine transform
       idctn - N-D Inverse discrete cosine transform
       dst - Discrete sine transform
       idst - Inverse discrete sine transform
       dstn - N-D Discrete sine transform
       idstn - N-D Inverse discrete sine transform

    Differential and pseudo-differential operators
    ==============================================

    .. autosummary::
       :toctree: generated/

       diff - Differentiation and integration of periodic sequences
       tilbert - Tilbert transform:         cs_diff(x,h,h)
       itilbert - Inverse Tilbert transform: sc_diff(x,h,h)
       hilbert - Hilbert transform:         cs_diff(x,inf,inf)
       ihilbert - Inverse Hilbert transform: sc_diff(x,inf,inf)
       cs_diff - cosh/sinh pseudo-derivative of periodic sequences
       sc_diff - sinh/cosh pseudo-derivative of periodic sequences
       ss_diff - sinh/sinh pseudo-derivative of periodic sequences
       cc_diff - cosh/cosh pseudo-derivative of periodic sequences
       shift - Shift periodic sequences

    Helper functions
    ================

    .. autosummary::
       :toctree: generated/

       fftshift - Shift the zero-frequency component to the center of the spectrum
       ifftshift - The inverse of `fftshift`
       fftfreq - Return the Discrete Fourier Transform sample frequencies
       rfftfreq - DFT sample frequencies (for usage with rfft, irfft)
       next_fast_len - Find the optimal length to zero-pad an FFT for speed

    Note that ``fftshift``, ``ifftshift`` and ``fftfreq`` are numpy functions
    exposed by ``fftpack``; importing them from ``numpy`` should be preferred.

    Convolutions (:mod:`scipy.fftpack.convolve`)
    ============================================

    .. module:: scipy.fftpack.convolve

    .. autosummary::
       :toctree: generated/

       convolve
       convolve_z
       init_convolution_kernel
       destroy_convolve_cache

PACKAGE CONTENTS
    _basic
    _helper
    _pseudo_diffs
    _realtransforms
    basic
    convolve
    helper
    pseudo_diffs
    realtransforms
    tests (package)

FUNCTIONS
    cc_diff(x, a, b, period=None, _cache={})
        Return (a,b)-cosh/cosh pseudo-derivative of a periodic sequence.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = cosh(j*a*2*pi/period)/cosh(j*b*2*pi/period) * x_j

        Parameters
        ----------
        x : array_like
            The array to take the pseudo-derivative from.
        a,b : float
            Defines the parameters of the sinh/sinh pseudo-differential
            operator.
        period : float, optional
            The period of the sequence x. Default is ``2*pi``.

        Returns
        -------
        cc_diff : ndarray
            Pseudo-derivative of periodic sequence `x`.

        Notes
        -----
        ``cc_diff(cc_diff(x,a,b),b,a) == x``

    cs_diff(x, a, b, period=None, _cache={})
        Return (a,b)-cosh/sinh pseudo-derivative of a periodic sequence.

        If ``x_j`` and ``y_j`` are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = -sqrt(-1)*cosh(j*a*2*pi/period)/sinh(j*b*2*pi/period) * x_j
          y_0 = 0

        Parameters
        ----------
        x : array_like
            The array to take the pseudo-derivative from.
        a, b : float
            Defines the parameters of the cosh/sinh pseudo-differential
            operator.
        period : float, optional
            The period of the sequence. Default period is ``2*pi``.

        Returns
        -------
        cs_diff : ndarray
            Pseudo-derivative of periodic sequence `x`.

        Notes
        -----
        For even len(`x`), the Nyquist mode of `x` is taken as zero.

    dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
        Return the Discrete Cosine Transform of arbitrary type sequence x.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the dct is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idct : Inverse DCT

        Notes
        -----
        For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to
        MATLAB ``dct(x)``.

        There are, theoretically, 8 types of the DCT, only the first 4 types are
        implemented in scipy. 'The' DCT generally refers to DCT type 2, and 'the'
        Inverse DCT generally refers to DCT type 3.

        **Type I**

        There are several definitions of the DCT-I; we use the following
        (for ``norm=None``)

        .. math::

           y_k = x_0 + (-1)^k x_{N-1} + 2 \sum_{n=1}^{N-2} x_n \cos\left(
           \frac{\pi k n}{N-1} \right)

        If ``norm='ortho'``, ``x[0]`` and ``x[N-1]`` are multiplied by a scaling
        factor of :math:`\sqrt{2}`, and ``y[k]`` is multiplied by a scaling factor
        ``f``

        .. math::

            f = \begin{cases}
             \frac{1}{2}\sqrt{\frac{1}{N-1}} & \text{if }k=0\text{ or }N-1, \\
             \frac{1}{2}\sqrt{\frac{2}{N-1}} & \text{otherwise} \end{cases}

        .. versionadded:: 1.2.0
           Orthonormalization in DCT-I.

        .. note::
           The DCT-I is only supported for input size > 1.

        **Type II**

        There are several definitions of the DCT-II; we use the following
        (for ``norm=None``)

        .. math::

           y_k = 2 \sum_{n=0}^{N-1} x_n \cos\left(\frac{\pi k(2n+1)}{2N} \right)

        If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor ``f``

        .. math::
           f = \begin{cases}
           \sqrt{\frac{1}{4N}} & \text{if }k=0, \\
           \sqrt{\frac{1}{2N}} & \text{otherwise} \end{cases}

        which makes the corresponding matrix of coefficients orthonormal
        (``O @ O.T = np.eye(N)``).

        **Type III**

        There are several definitions, we use the following (for ``norm=None``)

        .. math::

           y_k = x_0 + 2 \sum_{n=1}^{N-1} x_n \cos\left(\frac{\pi(2k+1)n}{2N}\right)

        or, for ``norm='ortho'``

        .. math::

           y_k = \frac{x_0}{\sqrt{N}} + \sqrt{\frac{2}{N}} \sum_{n=1}^{N-1} x_n
           \cos\left(\frac{\pi(2k+1)n}{2N}\right)

        The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up
        to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of
        the orthonormalized DCT-II.

        **Type IV**

        There are several definitions of the DCT-IV; we use the following
        (for ``norm=None``)

        .. math::

           y_k = 2 \sum_{n=0}^{N-1} x_n \cos\left(\frac{\pi(2k+1)(2n+1)}{4N} \right)

        If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor ``f``

        .. math::

            f = \frac{1}{\sqrt{2N}}

        .. versionadded:: 1.2.0
           Support for DCT-IV.

        References
        ----------
        .. [1] 'A Fast Cosine Transform in One and Two Dimensions', by J.
               Makhoul, `IEEE Transactions on acoustics, speech and signal
               processing` vol. 28(1), pp. 27-34,
               :doi:`10.1109/TASSP.1980.1163351` (1980).
        .. [2] Wikipedia, "Discrete cosine transform",
               https://en.wikipedia.org/wiki/Discrete_cosine_transform

        Examples
        --------
        The Type 1 DCT is equivalent to the FFT (though faster) for real,
        even-symmetrical inputs. The output is also real and even-symmetrical.
        Half of the FFT input is used to generate half of the FFT output:

        >>> from scipy.fftpack import fft, dct
        >>> import numpy as np
        >>> fft(np.array([4., 3., 5., 10., 5., 3.])).real
        array([ 30.,  -8.,   6.,  -2.,   6.,  -8.])
        >>> dct(np.array([4., 3., 5., 10.]), 1)
        array([ 30.,  -8.,   6.,  -2.])

    dctn(x, type=2, shape=None, axes=None, norm=None, overwrite_x=False)
        Return multidimensional Discrete Cosine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        shape : int or array_like of ints or None, optional
            The shape of the result. If both `shape` and `axes` (see below) are
            None, `shape` is ``x.shape``; if `shape` is None but `axes` is
            not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``shape[i] > x.shape[i]``, the ith dimension is padded with zeros.
            If ``shape[i] < x.shape[i]``, the ith dimension is truncated to
            length ``shape[i]``.
            If any element of `shape` is -1, the size of the corresponding
            dimension of `x` is used.
        axes : int or array_like of ints or None, optional
            Axes along which the DCT is computed.
            The default is over all axes.
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idctn : Inverse multidimensional DCT

        Notes
        -----
        For full details of the DCT types and normalization modes, as well as
        references, see `dct`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import dctn, idctn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idctn(dctn(y, norm='ortho'), norm='ortho'))
        True

    diff(x, order=1, period=None, _cache={})
        Return kth derivative (or integral) of a periodic sequence x.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = pow(sqrt(-1)*j*2*pi/period, order) * x_j
          y_0 = 0 if order is not 0.

        Parameters
        ----------
        x : array_like
            Input array.
        order : int, optional
            The order of differentiation. Default order is 1. If order is
            negative, then integration is carried out under the assumption
            that ``x_0 == 0``.
        period : float, optional
            The assumed period of the sequence. Default is ``2*pi``.

        Notes
        -----
        If ``sum(x, axis=0) = 0`` then ``diff(diff(x, k), -k) == x`` (within
        numerical accuracy).

        For odd order and even ``len(x)``, the Nyquist mode is taken zero.

    dst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
        Return the Discrete Sine Transform of arbitrary type sequence x.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the dst is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        dst : ndarray of reals
            The transformed input array.

        See Also
        --------
        idst : Inverse DST

        Notes
        -----
        For a single dimension array ``x``.

        There are, theoretically, 8 types of the DST for different combinations of
        even/odd boundary conditions and boundary off sets [1]_, only the first
        4 types are implemented in scipy.

        **Type I**

        There are several definitions of the DST-I; we use the following
        for ``norm=None``. DST-I assumes the input is odd around `n=-1` and `n=N`.

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(k+1)(n+1)}{N+1}\right)

        Note that the DST-I is only supported for input size > 1.
        The (unnormalized) DST-I is its own inverse, up to a factor `2(N+1)`.
        The orthonormalized DST-I is exactly its own inverse.

        **Type II**

        There are several definitions of the DST-II; we use the following for
        ``norm=None``. DST-II assumes the input is odd around `n=-1/2` and
        `n=N-1/2`; the output is odd around :math:`k=-1` and even around `k=N-1`

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(k+1)(2n+1)}{2N}\right)

        if ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor ``f``

        .. math::

            f = \begin{cases}
            \sqrt{\frac{1}{4N}} & \text{if }k = 0, \\
            \sqrt{\frac{1}{2N}} & \text{otherwise} \end{cases}

        **Type III**

        There are several definitions of the DST-III, we use the following (for
        ``norm=None``). DST-III assumes the input is odd around `n=-1` and even
        around `n=N-1`

        .. math::

            y_k = (-1)^k x_{N-1} + 2 \sum_{n=0}^{N-2} x_n \sin\left(
            \frac{\pi(2k+1)(n+1)}{2N}\right)

        The (unnormalized) DST-III is the inverse of the (unnormalized) DST-II, up
        to a factor `2N`. The orthonormalized DST-III is exactly the inverse of the
        orthonormalized DST-II.

        .. versionadded:: 0.11.0

        **Type IV**

        There are several definitions of the DST-IV, we use the following (for
        ``norm=None``). DST-IV assumes the input is odd around `n=-0.5` and even
        around `n=N-0.5`

        .. math::

            y_k = 2 \sum_{n=0}^{N-1} x_n \sin\left(\frac{\pi(2k+1)(2n+1)}{4N}\right)

        The (unnormalized) DST-IV is its own inverse, up to a factor `2N`. The
        orthonormalized DST-IV is exactly its own inverse.

        .. versionadded:: 1.2.0
           Support for DST-IV.

        References
        ----------
        .. [1] Wikipedia, "Discrete sine transform",
               https://en.wikipedia.org/wiki/Discrete_sine_transform

    dstn(x, type=2, shape=None, axes=None, norm=None, overwrite_x=False)
        Return multidimensional Discrete Sine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        shape : int or array_like of ints or None, optional
            The shape of the result.  If both `shape` and `axes` (see below) are
            None, `shape` is ``x.shape``; if `shape` is None but `axes` is
            not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``shape[i] > x.shape[i]``, the ith dimension is padded with zeros.
            If ``shape[i] < x.shape[i]``, the ith dimension is truncated to
            length ``shape[i]``.
            If any element of `shape` is -1, the size of the corresponding
            dimension of `x` is used.
        axes : int or array_like of ints or None, optional
            Axes along which the DCT is computed.
            The default is over all axes.
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        idstn : Inverse multidimensional DST

        Notes
        -----
        For full details of the DST types and normalization modes, as well as
        references, see `dst`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import dstn, idstn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idstn(dstn(y, norm='ortho'), norm='ortho'))
        True

    fft(x, n=None, axis=-1, overwrite_x=False)
        Return discrete Fourier transform of real or complex sequence.

        The returned complex array contains ``y(0), y(1),..., y(n-1)``, where

        ``y(j) = (x * exp(-2*pi*sqrt(-1)*j*np.arange(n)/n)).sum()``.

        Parameters
        ----------
        x : array_like
            Array to Fourier transform.
        n : int, optional
            Length of the Fourier transform. If ``n < x.shape[axis]``, `x` is
            truncated. If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the fft's are computed; the default is over the
            last axis (i.e., ``axis=-1``).
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        z : complex ndarray
            with the elements::

                [y(0),y(1),..,y(n/2),y(1-n/2),...,y(-1)]        if n is even
                [y(0),y(1),..,y((n-1)/2),y(-(n-1)/2),...,y(-1)]  if n is odd

            where::

                y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k* 2*pi/n), j = 0..n-1

        See Also
        --------
        ifft : Inverse FFT
        rfft : FFT of a real sequence

        Notes
        -----
        The packing of the result is "standard": If ``A = fft(a, n)``, then
        ``A[0]`` contains the zero-frequency term, ``A[1:n/2]`` contains the
        positive-frequency terms, and ``A[n/2:]`` contains the negative-frequency
        terms, in order of decreasingly negative frequency. So ,for an 8-point
        transform, the frequencies of the result are [0, 1, 2, 3, -4, -3, -2, -1].
        To rearrange the fft output so that the zero-frequency component is
        centered, like [-4, -3, -2, -1,  0,  1,  2,  3], use `fftshift`.

        Both single and double precision routines are implemented. Half precision
        inputs will be converted to single precision. Non-floating-point inputs
        will be converted to double precision. Long-double precision inputs are
        not supported.

        This function is most efficient when `n` is a power of two, and least
        efficient when `n` is prime.

        Note that if ``x`` is real-valued, then ``A[j] == A[n-j].conjugate()``.
        If ``x`` is real-valued and ``n`` is even, then ``A[n/2]`` is real.

        If the data type of `x` is real, a "real FFT" algorithm is automatically
        used, which roughly halves the computation time. To increase efficiency
        a little further, use `rfft`, which does the same calculation, but only
        outputs half of the symmetrical spectrum. If the data is both real and
        symmetrical, the `dct` can again double the efficiency by generating
        half of the spectrum from half of the signal.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import fft, ifft
        >>> x = np.arange(5)
        >>> np.allclose(fft(ifft(x)), x, atol=1e-15)  # within numerical accuracy.
        True

    fft2(x, shape=None, axes=(-2, -1), overwrite_x=False)
        2-D discrete Fourier transform.

        Return the 2-D discrete Fourier transform of the 2-D argument
        `x`.

        See Also
        --------
        fftn : for detailed information.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import fft2, ifft2
        >>> y = np.mgrid[:5, :5][0]
        >>> y
        array([[0, 0, 0, 0, 0],
               [1, 1, 1, 1, 1],
               [2, 2, 2, 2, 2],
               [3, 3, 3, 3, 3],
               [4, 4, 4, 4, 4]])
        >>> np.allclose(y, ifft2(fft2(y)))
        True

    fftfreq(n, d=1.0, device=None)
        Return the Discrete Fourier Transform sample frequencies.

        The returned float array `f` contains the frequency bin centers in cycles
        per unit of the sample spacing (with zero at the start).  For instance, if
        the sample spacing is in seconds, then the frequency unit is cycles/second.

        Given a window length `n` and a sample spacing `d`::

          f = [0, 1, ...,   n/2-1,     -n/2, ..., -1] / (d*n)   if n is even
          f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n)   if n is odd

        Parameters
        ----------
        n : int
            Window length.
        d : scalar, optional
            Sample spacing (inverse of the sampling rate). Defaults to 1.
        device : str, optional
            The device on which to place the created array. Default: ``None``.
            For Array-API interoperability only, so must be ``"cpu"`` if passed.

            .. versionadded:: 2.0.0

        Returns
        -------
        f : ndarray
            Array of length `n` containing the sample frequencies.

        Examples
        --------
        >>> import numpy as np
        >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
        >>> fourier = np.fft.fft(signal)
        >>> n = signal.size
        >>> timestep = 0.1
        >>> freq = np.fft.fftfreq(n, d=timestep)
        >>> freq
        array([ 0.  ,  1.25,  2.5 , ..., -3.75, -2.5 , -1.25])

    fftn(x, shape=None, axes=None, overwrite_x=False)
        Return multidimensional discrete Fourier transform.

        The returned array contains::

          y[j_1,..,j_d] = sum[k_1=0..n_1-1, ..., k_d=0..n_d-1]
             x[k_1,..,k_d] * prod[i=1..d] exp(-sqrt(-1)*2*pi/n_i * j_i * k_i)

        where d = len(x.shape) and n = x.shape.

        Parameters
        ----------
        x : array_like
            The (N-D) array to transform.
        shape : int or array_like of ints or None, optional
            The shape of the result. If both `shape` and `axes` (see below) are
            None, `shape` is ``x.shape``; if `shape` is None but `axes` is
            not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``shape[i] > x.shape[i]``, the ith dimension is padded with zeros.
            If ``shape[i] < x.shape[i]``, the ith dimension is truncated to
            length ``shape[i]``.
            If any element of `shape` is -1, the size of the corresponding
            dimension of `x` is used.
        axes : int or array_like of ints or None, optional
            The axes of `x` (`y` if `shape` is not None) along which the
            transform is applied.
            The default is over all axes.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed. Default is False.

        Returns
        -------
        y : complex-valued N-D NumPy array
            The (N-D) DFT of the input array.

        See Also
        --------
        ifftn

        Notes
        -----
        If ``x`` is real-valued, then
        ``y[..., j_i, ...] == y[..., n_i-j_i, ...].conjugate()``.

        Both single and double precision routines are implemented. Half precision
        inputs will be converted to single precision. Non-floating-point inputs
        will be converted to double precision. Long-double precision inputs are
        not supported.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import fftn, ifftn
        >>> y = (-np.arange(16), 8 - np.arange(16), np.arange(16))
        >>> np.allclose(y, fftn(ifftn(y)))
        True

    fftshift(x, axes=None)
        Shift the zero-frequency component to the center of the spectrum.

        This function swaps half-spaces for all axes listed (defaults to all).
        Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.

        Parameters
        ----------
        x : array_like
            Input array.
        axes : int or shape tuple, optional
            Axes over which to shift.  Default is None, which shifts all axes.

        Returns
        -------
        y : ndarray
            The shifted array.

        See Also
        --------
        ifftshift : The inverse of `fftshift`.

        Examples
        --------
        >>> import numpy as np
        >>> freqs = np.fft.fftfreq(10, 0.1)
        >>> freqs
        array([ 0.,  1.,  2., ..., -3., -2., -1.])
        >>> np.fft.fftshift(freqs)
        array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])

        Shift the zero-frequency component only along the second axis:

        >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
        >>> freqs
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])
        >>> np.fft.fftshift(freqs, axes=(1,))
        array([[ 2.,  0.,  1.],
               [-4.,  3.,  4.],
               [-1., -3., -2.]])

    hilbert(x, _cache={})
        Return Hilbert transform of a periodic sequence x.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = sqrt(-1)*sign(j) * x_j
          y_0 = 0

        Parameters
        ----------
        x : array_like
            The input array, should be periodic.
        _cache : dict, optional
            Dictionary that contains the kernel used to do a convolution with.

        Returns
        -------
        y : ndarray
            The transformed input.

        See Also
        --------
        scipy.signal.hilbert : Compute the analytic signal, using the Hilbert
                               transform.

        Notes
        -----
        If ``sum(x, axis=0) == 0`` then ``hilbert(ihilbert(x)) == x``.

        For even len(x), the Nyquist mode of x is taken zero.

        The sign of the returned transform does not have a factor -1 that is more
        often than not found in the definition of the Hilbert transform. Note also
        that `scipy.signal.hilbert` does have an extra -1 factor compared to this
        function.

    idct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
        Return the Inverse Discrete Cosine Transform of an arbitrary type sequence.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated.  If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the idct is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        idct : ndarray of real
            The transformed input array.

        See Also
        --------
        dct : Forward DCT

        Notes
        -----
        For a single dimension array `x`, ``idct(x, norm='ortho')`` is equal to
        MATLAB ``idct(x)``.

        'The' IDCT is the IDCT of type 2, which is the same as DCT of type 3.

        IDCT of type 1 is the DCT of type 1, IDCT of type 2 is the DCT of type
        3, and IDCT of type 3 is the DCT of type 2. IDCT of type 4 is the DCT
        of type 4. For the definition of these types, see `dct`.

        Examples
        --------
        The Type 1 DCT is equivalent to the DFT for real, even-symmetrical
        inputs. The output is also real and even-symmetrical. Half of the IFFT
        input is used to generate half of the IFFT output:

        >>> from scipy.fftpack import ifft, idct
        >>> import numpy as np
        >>> ifft(np.array([ 30.,  -8.,   6.,  -2.,   6.,  -8.])).real
        array([  4.,   3.,   5.,  10.,   5.,   3.])
        >>> idct(np.array([ 30.,  -8.,   6.,  -2.]), 1) / 6
        array([  4.,   3.,   5.,  10.])

    idctn(x, type=2, shape=None, axes=None, norm=None, overwrite_x=False)
        Return multidimensional Discrete Cosine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DCT (see Notes). Default type is 2.
        shape : int or array_like of ints or None, optional
            The shape of the result.  If both `shape` and `axes` (see below) are
            None, `shape` is ``x.shape``; if `shape` is None but `axes` is
            not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``shape[i] > x.shape[i]``, the ith dimension is padded with zeros.
            If ``shape[i] < x.shape[i]``, the ith dimension is truncated to
            length ``shape[i]``.
            If any element of `shape` is -1, the size of the corresponding
            dimension of `x` is used.
        axes : int or array_like of ints or None, optional
            Axes along which the IDCT is computed.
            The default is over all axes.
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        dctn : multidimensional DCT

        Notes
        -----
        For full details of the IDCT types and normalization modes, as well as
        references, see `idct`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import dctn, idctn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idctn(dctn(y, norm='ortho'), norm='ortho'))
        True

    idst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False)
        Return the Inverse Discrete Sine Transform of an arbitrary type sequence.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        n : int, optional
            Length of the transform.  If ``n < x.shape[axis]``, `x` is
            truncated. If ``n > x.shape[axis]``, `x` is zero-padded. The
            default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the idst is computed; the default is over the
            last axis (i.e., ``axis=-1``).
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        idst : ndarray of real
            The transformed input array.

        See Also
        --------
        dst : Forward DST

        Notes
        -----
        'The' IDST is the IDST of type 2, which is the same as DST of type 3.

        IDST of type 1 is the DST of type 1, IDST of type 2 is the DST of type
        3, and IDST of type 3 is the DST of type 2. For the definition of these
        types, see `dst`.

        .. versionadded:: 0.11.0

    idstn(x, type=2, shape=None, axes=None, norm=None, overwrite_x=False)
        Return multidimensional Discrete Sine Transform along the specified axes.

        Parameters
        ----------
        x : array_like
            The input array.
        type : {1, 2, 3, 4}, optional
            Type of the DST (see Notes). Default type is 2.
        shape : int or array_like of ints or None, optional
            The shape of the result.  If both `shape` and `axes` (see below) are
            None, `shape` is ``x.shape``; if `shape` is None but `axes` is
            not None, then `shape` is ``numpy.take(x.shape, axes, axis=0)``.
            If ``shape[i] > x.shape[i]``, the ith dimension is padded with zeros.
            If ``shape[i] < x.shape[i]``, the ith dimension is truncated to
            length ``shape[i]``.
            If any element of `shape` is -1, the size of the corresponding
            dimension of `x` is used.
        axes : int or array_like of ints or None, optional
            Axes along which the IDST is computed.
            The default is over all axes.
        norm : {None, 'ortho'}, optional
            Normalization mode (see Notes). Default is None.
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        y : ndarray of real
            The transformed input array.

        See Also
        --------
        dstn : multidimensional DST

        Notes
        -----
        For full details of the IDST types and normalization modes, as well as
        references, see `idst`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import dstn, idstn
        >>> rng = np.random.default_rng()
        >>> y = rng.standard_normal((16, 16))
        >>> np.allclose(y, idstn(dstn(y, norm='ortho'), norm='ortho'))
        True

    ifft(x, n=None, axis=-1, overwrite_x=False)
        Return discrete inverse Fourier transform of real or complex sequence.

        The returned complex array contains ``y(0), y(1),..., y(n-1)``, where

        ``y(j) = (x * exp(2*pi*sqrt(-1)*j*np.arange(n)/n)).mean()``.

        Parameters
        ----------
        x : array_like
            Transformed data to invert.
        n : int, optional
            Length of the inverse Fourier transform.  If ``n < x.shape[axis]``,
            `x` is truncated. If ``n > x.shape[axis]``, `x` is zero-padded.
            The default results in ``n = x.shape[axis]``.
        axis : int, optional
            Axis along which the ifft's are computed; the default is over the
            last axis (i.e., ``axis=-1``).
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        ifft : ndarray of floats
            The inverse discrete Fourier transform.

        See Also
        --------
        fft : Forward FFT

        Notes
        -----
        Both single and double precision routines are implemented. Half precision
        inputs will be converted to single precision. Non-floating-point inputs
        will be converted to double precision. Long-double precision inputs are
        not supported.

        This function is most efficient when `n` is a power of two, and least
        efficient when `n` is prime.

        If the data type of `x` is real, a "real IFFT" algorithm is automatically
        used, which roughly halves the computation time.

        Examples
        --------
        >>> from scipy.fftpack import fft, ifft
        >>> import numpy as np
        >>> x = np.arange(5)
        >>> np.allclose(ifft(fft(x)), x, atol=1e-15)  # within numerical accuracy.
        True

    ifft2(x, shape=None, axes=(-2, -1), overwrite_x=False)
        2-D discrete inverse Fourier transform of real or complex sequence.

        Return inverse 2-D discrete Fourier transform of
        arbitrary type sequence x.

        See `ifft` for more information.

        See Also
        --------
        fft2, ifft

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.fftpack import fft2, ifft2
        >>> y = np.mgrid[:5, :5][0]
        >>> y
        array([[0, 0, 0, 0, 0],
               [1, 1, 1, 1, 1],
               [2, 2, 2, 2, 2],
               [3, 3, 3, 3, 3],
               [4, 4, 4, 4, 4]])
        >>> np.allclose(y, fft2(ifft2(y)))
        True

    ifftn(x, shape=None, axes=None, overwrite_x=False)
        Return inverse multidimensional discrete Fourier transform.

        The sequence can be of an arbitrary type.

        The returned array contains::

          y[j_1,..,j_d] = 1/p * sum[k_1=0..n_1-1, ..., k_d=0..n_d-1]
             x[k_1,..,k_d] * prod[i=1..d] exp(sqrt(-1)*2*pi/n_i * j_i * k_i)

        where ``d = len(x.shape)``, ``n = x.shape``, and ``p = prod[i=1..d] n_i``.

        For description of parameters see `fftn`.

        See Also
        --------
        fftn : for detailed information.

        Examples
        --------
        >>> from scipy.fftpack import fftn, ifftn
        >>> import numpy as np
        >>> y = (-np.arange(16), 8 - np.arange(16), np.arange(16))
        >>> np.allclose(y, ifftn(fftn(y)))
        True

    ifftshift(x, axes=None)
        The inverse of `fftshift`. Although identical for even-length `x`, the
        functions differ by one sample for odd-length `x`.

        Parameters
        ----------
        x : array_like
            Input array.
        axes : int or shape tuple, optional
            Axes over which to calculate.  Defaults to None, which shifts all axes.

        Returns
        -------
        y : ndarray
            The shifted array.

        See Also
        --------
        fftshift : Shift zero-frequency component to the center of the spectrum.

        Examples
        --------
        >>> import numpy as np
        >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
        >>> freqs
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])
        >>> np.fft.ifftshift(np.fft.fftshift(freqs))
        array([[ 0.,  1.,  2.],
               [ 3.,  4., -4.],
               [-3., -2., -1.]])

    ihilbert(x)
        Return inverse Hilbert transform of a periodic sequence x.

        If ``x_j`` and ``y_j`` are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = -sqrt(-1)*sign(j) * x_j
          y_0 = 0

    irfft(x, n=None, axis=-1, overwrite_x=False)
        Return inverse discrete Fourier transform of real sequence x.

        The contents of `x` are interpreted as the output of the `rfft`
        function.

        Parameters
        ----------
        x : array_like
            Transformed data to invert.
        n : int, optional
            Length of the inverse Fourier transform.
            If n < x.shape[axis], x is truncated.
            If n > x.shape[axis], x is zero-padded.
            The default results in n = x.shape[axis].
        axis : int, optional
            Axis along which the ifft's are computed; the default is over
            the last axis (i.e., axis=-1).
        overwrite_x : bool, optional
            If True, the contents of `x` can be destroyed; the default is False.

        Returns
        -------
        irfft : ndarray of floats
            The inverse discrete Fourier transform.

        See Also
        --------
        rfft, ifft, scipy.fft.irfft

        Notes
        -----
        The returned real array contains::

            [y(0),y(1),...,y(n-1)]

        where for n is even::

            y(j) = 1/n (sum[k=1..n/2-1] (x[2*k-1]+sqrt(-1)*x[2*k])
                                         * exp(sqrt(-1)*j*k* 2*pi/n)
                        + c.c. + x[0] + (-1)**(j) x[n-1])

        and for n is odd::

            y(j) = 1/n (sum[k=1..(n-1)/2] (x[2*k-1]+sqrt(-1)*x[2*k])
                                         * exp(sqrt(-1)*j*k* 2*pi/n)
                        + c.c. + x[0])

        c.c. denotes complex conjugate of preceding expression.

        For details on input parameters, see `rfft`.

        To process (conjugate-symmetric) frequency-domain data with a complex
        datatype, consider using the newer function `scipy.fft.irfft`.

        Examples
        --------
        >>> from scipy.fftpack import rfft, irfft
        >>> a = [1.0, 2.0, 3.0, 4.0, 5.0]
        >>> irfft(a)
        array([ 2.6       , -3.16405192,  1.24398433, -1.14955713,  1.46962473])
        >>> irfft(rfft(a))
        array([1., 2., 3., 4., 5.])

    itilbert(x, h, period=None, _cache={})
        Return inverse h-Tilbert transform of a periodic sequence x.

        If ``x_j`` and ``y_j`` are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = -sqrt(-1)*tanh(j*h*2*pi/period) * x_j
          y_0 = 0

        For more details, see `tilbert`.

    next_fast_len(target)
        Find the next fast size of input data to `fft`, for zero-padding, etc.

        SciPy's FFTPACK has efficient functions for radix {2, 3, 4, 5}, so this
        returns the next composite of the prime factors 2, 3, and 5 which is
        greater than or equal to `target`. (These are also known as 5-smooth
        numbers, regular numbers, or Hamming numbers.)

        Parameters
        ----------
        target : int
            Length to start searching from. Must be a positive integer.

        Returns
        -------
        out : int
            The first 5-smooth number greater than or equal to `target`.

        Notes
        -----
        .. versionadded:: 0.18.0

        Examples
        --------
        On a particular machine, an FFT of prime length takes 133 ms:

        >>> from scipy import fftpack
        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> min_len = 10007  # prime length is worst case for speed
        >>> a = rng.standard_normal(min_len)
        >>> b = fftpack.fft(a)

        Zero-padding to the next 5-smooth length reduces computation time to
        211 us, a speedup of 630 times:

        >>> fftpack.next_fast_len(min_len)
        10125
        >>> b = fftpack.fft(a, 10125)

        Rounding up to the next power of 2 is not optimal, taking 367 us to
        compute, 1.7 times as long as the 5-smooth size:

        >>> b = fftpack.fft(a, 16384)

    rfft(x, n=None, axis=-1, overwrite_x=False)
        Discrete Fourier transform of a real sequence.

        Parameters
        ----------
        x : array_like, real-valued
            The data to transform.
        n : int, optional
            Defines the length of the Fourier transform. If `n` is not specified
            (the default) then ``n = x.shape[axis]``. If ``n < x.shape[axis]``,
            `x` is truncated, if ``n > x.shape[axis]``, `x` is zero-padded.
        axis : int, optional
            The axis along which the transform is applied. The default is the
            last axis.
        overwrite_x : bool, optional
            If set to true, the contents of `x` can be overwritten. Default is
            False.

        Returns
        -------
        z : real ndarray
            The returned real array contains::

              [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))]              if n is even
              [y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))]   if n is odd

            where::

              y(j) = sum[k=0..n-1] x[k] * exp(-sqrt(-1)*j*k*2*pi/n)
              j = 0..n-1

        See Also
        --------
        fft, irfft, scipy.fft.rfft

        Notes
        -----
        Within numerical accuracy, ``y == rfft(irfft(y))``.

        Both single and double precision routines are implemented. Half precision
        inputs will be converted to single precision. Non-floating-point inputs
        will be converted to double precision. Long-double precision inputs are
        not supported.

        To get an output with a complex datatype, consider using the newer
        function `scipy.fft.rfft`.

        Examples
        --------
        >>> from scipy.fftpack import fft, rfft
        >>> a = [9, -9, 1, 3]
        >>> fft(a)
        array([  4. +0.j,   8.+12.j,  16. +0.j,   8.-12.j])
        >>> rfft(a)
        array([  4.,   8.,  12.,  16.])

    rfftfreq(n, d=1.0)
        DFT sample frequencies (for usage with rfft, irfft).

        The returned float array contains the frequency bins in
        cycles/unit (with zero at the start) given a window length `n` and a
        sample spacing `d`::

          f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2]/(d*n)   if n is even
          f = [0,1,1,2,2,...,n/2-1,n/2-1,n/2,n/2]/(d*n)   if n is odd

        Parameters
        ----------
        n : int
            Window length.
        d : scalar, optional
            Sample spacing. Default is 1.

        Returns
        -------
        out : ndarray
            The array of length `n`, containing the sample frequencies.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import fftpack
        >>> sig = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float)
        >>> sig_fft = fftpack.rfft(sig)
        >>> n = sig_fft.size
        >>> timestep = 0.1
        >>> freq = fftpack.rfftfreq(n, d=timestep)
        >>> freq
        array([ 0.  ,  1.25,  1.25,  2.5 ,  2.5 ,  3.75,  3.75,  5.  ])

    sc_diff(x, a, b, period=None, _cache={})
        Return (a,b)-sinh/cosh pseudo-derivative of a periodic sequence x.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = sqrt(-1)*sinh(j*a*2*pi/period)/cosh(j*b*2*pi/period) * x_j
          y_0 = 0

        Parameters
        ----------
        x : array_like
            Input array.
        a,b : float
            Defines the parameters of the sinh/cosh pseudo-differential
            operator.
        period : float, optional
            The period of the sequence x. Default is 2*pi.

        Notes
        -----
        ``sc_diff(cs_diff(x,a,b),b,a) == x``
        For even ``len(x)``, the Nyquist mode of x is taken as zero.

    shift(x, a, period=None, _cache={})
        Shift periodic sequence x by a: y(u) = x(u+a).

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

              y_j = exp(j*a*2*pi/period*sqrt(-1)) * x_f

        Parameters
        ----------
        x : array_like
            The array to take the pseudo-derivative from.
        a : float
            Defines the parameters of the sinh/sinh pseudo-differential
        period : float, optional
            The period of the sequences x and y. Default period is ``2*pi``.

    ss_diff(x, a, b, period=None, _cache={})
        Return (a,b)-sinh/sinh pseudo-derivative of a periodic sequence x.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

          y_j = sinh(j*a*2*pi/period)/sinh(j*b*2*pi/period) * x_j
          y_0 = a/b * x_0

        Parameters
        ----------
        x : array_like
            The array to take the pseudo-derivative from.
        a,b
            Defines the parameters of the sinh/sinh pseudo-differential
            operator.
        period : float, optional
            The period of the sequence x. Default is ``2*pi``.

        Notes
        -----
        ``ss_diff(ss_diff(x,a,b),b,a) == x``

    tilbert(x, h, period=None, _cache={})
        Return h-Tilbert transform of a periodic sequence x.

        If x_j and y_j are Fourier coefficients of periodic functions x
        and y, respectively, then::

            y_j = sqrt(-1)*coth(j*h*2*pi/period) * x_j
            y_0 = 0

        Parameters
        ----------
        x : array_like
            The input array to transform.
        h : float
            Defines the parameter of the Tilbert transform.
        period : float, optional
            The assumed period of the sequence. Default period is ``2*pi``.

        Returns
        -------
        tilbert : ndarray
            The result of the transform.

        Notes
        -----
        If ``sum(x, axis=0) == 0`` and ``n = len(x)`` is odd, then
        ``tilbert(itilbert(x)) == x``.

        If ``2 * pi * h / period`` is approximately 10 or larger, then
        numerically ``tilbert == hilbert``
        (theoretically oo-Tilbert == Hilbert).

        For even ``len(x)``, the Nyquist mode of ``x`` is taken zero.

DATA
    __all__ = ['fft', 'ifft', 'fftn', 'ifftn', 'rfft', 'irfft', 'fft2', 'i...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\fftpack\__init__.py

scipy.integrate
Python Library Documentation: package scipy.integrate in scipy

NAME
    scipy.integrate

DESCRIPTION
    =============================================
    Integration and ODEs (:mod:`scipy.integrate`)
    =============================================

    .. currentmodule:: scipy.integrate

    Integrating functions, given function object
    ============================================

    .. autosummary::
       :toctree: generated/

       quad          -- General purpose integration
       quad_vec      -- General purpose integration of vector-valued functions
       dblquad       -- General purpose double integration
       tplquad       -- General purpose triple integration
       nquad         -- General purpose N-D integration
       fixed_quad    -- Integrate func(x) using Gaussian quadrature of order n
       quadrature    -- Integrate with given tolerance using Gaussian quadrature
       romberg       -- Integrate func using Romberg integration
       newton_cotes  -- Weights and error coefficient for Newton-Cotes integration
       qmc_quad      -- N-D integration using Quasi-Monte Carlo quadrature
       IntegrationWarning -- Warning on issues during integration
       AccuracyWarning  -- Warning on issues during quadrature integration

    Integrating functions, given fixed samples
    ==========================================

    .. autosummary::
       :toctree: generated/

       trapezoid            -- Use trapezoidal rule to compute integral.
       cumulative_trapezoid -- Use trapezoidal rule to cumulatively compute integral.
       simpson              -- Use Simpson's rule to compute integral from samples.
       cumulative_simpson   -- Use Simpson's rule to cumulatively compute integral from samples.
       romb                 -- Use Romberg Integration to compute integral from
                            -- (2**k + 1) evenly-spaced samples.

    .. seealso::

       :mod:`scipy.special` for orthogonal polynomials (special) for Gaussian
       quadrature roots and weights for other weighting factors and regions.

    Solving initial value problems for ODE systems
    ==============================================

    The solvers are implemented as individual classes, which can be used directly
    (low-level usage) or through a convenience function.

    .. autosummary::
       :toctree: generated/

       solve_ivp     -- Convenient function for ODE integration.
       RK23          -- Explicit Runge-Kutta solver of order 3(2).
       RK45          -- Explicit Runge-Kutta solver of order 5(4).
       DOP853        -- Explicit Runge-Kutta solver of order 8.
       Radau         -- Implicit Runge-Kutta solver of order 5.
       BDF           -- Implicit multi-step variable order (1 to 5) solver.
       LSODA         -- LSODA solver from ODEPACK Fortran package.
       OdeSolver     -- Base class for ODE solvers.
       DenseOutput   -- Local interpolant for computing a dense output.
       OdeSolution   -- Class which represents a continuous ODE solution.


    Old API
    -------

    These are the routines developed earlier for SciPy. They wrap older solvers
    implemented in Fortran (mostly ODEPACK). While the interface to them is not
    particularly convenient and certain features are missing compared to the new
    API, the solvers themselves are of good quality and work fast as compiled
    Fortran code. In some cases, it might be worth using this old API.

    .. autosummary::
       :toctree: generated/

       odeint        -- General integration of ordinary differential equations.
       ode           -- Integrate ODE using VODE and ZVODE routines.
       complex_ode   -- Convert a complex-valued ODE to real-valued and integrate.
       ODEintWarning -- Warning raised during the execution of `odeint`.


    Solving boundary value problems for ODE systems
    ===============================================

    .. autosummary::
       :toctree: generated/

       solve_bvp     -- Solve a boundary value problem for a system of ODEs.

PACKAGE CONTENTS
    _bvp
    _dop
    _ivp (package)
    _lsoda
    _ode
    _odepack
    _odepack_py
    _quad_vec
    _quadpack
    _quadpack_py
    _quadrature
    _tanhsinh
    _test_multivariate
    _test_odeint_banded
    _vode
    dop
    lsoda
    odepack
    quadpack
    tests (package)
    vode

CLASSES
    builtins.UserWarning(builtins.Warning)
        scipy.integrate._quadpack_py.IntegrationWarning
    builtins.Warning(builtins.Exception)
        scipy.integrate._odepack_py.ODEintWarning
        scipy.integrate._quadrature.AccuracyWarning
    builtins.object
        scipy.integrate._ivp.base.DenseOutput
        scipy.integrate._ivp.base.OdeSolver
            scipy.integrate._ivp.bdf.BDF
            scipy.integrate._ivp.lsoda.LSODA
            scipy.integrate._ivp.radau.Radau
        scipy.integrate._ivp.common.OdeSolution
        scipy.integrate._ode.ode
            scipy.integrate._ode.complex_ode
    scipy.integrate._ivp.rk.RungeKutta(scipy.integrate._ivp.base.OdeSolver)
        scipy.integrate._ivp.rk.DOP853
        scipy.integrate._ivp.rk.RK23
        scipy.integrate._ivp.rk.RK45

    class AccuracyWarning(builtins.Warning)
     |  Method resolution order:
     |      AccuracyWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Warning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Warning:
     |
     |  __new__(*args, **kwargs) class method of builtins.Warning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class BDF(scipy.integrate._ivp.base.OdeSolver)
     |  BDF(fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, jac=None, jac_sparsity=None, vectorized=False, first_step=None, **extraneous)
     |
     |  Implicit method based on backward-differentiation formulas.
     |
     |  This is a variable order method with the order varying automatically from
     |  1 to 5. The general framework of the BDF algorithm is described in [1]_.
     |  This class implements a quasi-constant step size as explained in [2]_.
     |  The error estimation strategy for the constant-step BDF is derived in [3]_.
     |  An accuracy enhancement using modified formulas (NDF) [2]_ is also implemented.
     |
     |  Can be applied in the complex domain.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system: the time derivative of the state ``y``
     |      at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
     |      scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
     |      return an array of the same shape as ``y``. See `vectorized` for more
     |      information.
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  jac : {None, array_like, sparse_matrix, callable}, optional
     |      Jacobian matrix of the right-hand side of the system with respect to y,
     |      required by this method. The Jacobian matrix has shape (n, n) and its
     |      element (i, j) is equal to ``d f_i / d y_j``.
     |      There are three ways to define the Jacobian:
     |
     |          * If array_like or sparse_matrix, the Jacobian is assumed to
     |            be constant.
     |          * If callable, the Jacobian is assumed to depend on both
     |            t and y; it will be called as ``jac(t, y)`` as necessary.
     |            For the 'Radau' and 'BDF' methods, the return value might be a
     |            sparse matrix.
     |          * If None (default), the Jacobian will be approximated by
     |            finite differences.
     |
     |      It is generally recommended to provide the Jacobian rather than
     |      relying on a finite-difference approximation.
     |  jac_sparsity : {None, array_like, sparse matrix}, optional
     |      Defines a sparsity structure of the Jacobian matrix for a
     |      finite-difference approximation. Its shape must be (n, n). This argument
     |      is ignored if `jac` is not `None`. If the Jacobian has only few non-zero
     |      elements in *each* row, providing the sparsity structure will greatly
     |      speed up the computations [4]_. A zero entry means that a corresponding
     |      element in the Jacobian is always zero. If None (default), the Jacobian
     |      is assumed to be dense.
     |  vectorized : bool, optional
     |      Whether `fun` can be called in a vectorized fashion. Default is False.
     |
     |      If ``vectorized`` is False, `fun` will always be called with ``y`` of
     |      shape ``(n,)``, where ``n = len(y0)``.
     |
     |      If ``vectorized`` is True, `fun` may be called with ``y`` of shape
     |      ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
     |      such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
     |      the returned array is the time derivative of the state corresponding
     |      with a column of ``y``).
     |
     |      Setting ``vectorized=True`` allows for faster finite difference
     |      approximation of the Jacobian by this method, but may result in slower
     |      execution overall in some circumstances (e.g. small ``len(y0)``).
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number of evaluations of the right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian.
     |  nlu : int
     |      Number of LU decompositions.
     |
     |  References
     |  ----------
     |  .. [1] G. D. Byrne, A. C. Hindmarsh, "A Polyalgorithm for the Numerical
     |         Solution of Ordinary Differential Equations", ACM Transactions on
     |         Mathematical Software, Vol. 1, No. 1, pp. 71-96, March 1975.
     |  .. [2] L. F. Shampine, M. W. Reichelt, "THE MATLAB ODE SUITE", SIAM J. SCI.
     |         COMPUTE., Vol. 18, No. 1, pp. 1-22, January 1997.
     |  .. [3] E. Hairer, G. Wanner, "Solving Ordinary Differential Equations I:
     |         Nonstiff Problems", Sec. III.2.
     |  .. [4] A. Curtis, M. J. D. Powell, and J. Reid, "On the estimation of
     |         sparse Jacobian matrices", Journal of the Institute of Mathematics
     |         and its Applications, 13, pp. 117-120, 1974.
     |
     |  Method resolution order:
     |      BDF
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, jac=None, jac_sparsity=None, vectorized=False, first_step=None, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class DOP853(RungeKutta)
     |  DOP853(fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |
     |  Explicit Runge-Kutta method of order 8.
     |
     |  This is a Python implementation of "DOP853" algorithm originally written
     |  in Fortran [1]_, [2]_. Note that this is not a literal translation, but
     |  the algorithmic core and coefficients are the same.
     |
     |  Can be applied in the complex domain.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system. The calling signature is ``fun(t, y)``.
     |      Here, ``t`` is a scalar, and there are two options for the ndarray ``y``:
     |      It can either have shape (n,); then ``fun`` must return array_like with
     |      shape (n,). Alternatively it can have shape (n, k); then ``fun``
     |      must return an array_like with shape (n, k), i.e. each column
     |      corresponds to a single column in ``y``. The choice between the two
     |      options is determined by `vectorized` argument (see below).
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e. the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  vectorized : bool, optional
     |      Whether `fun` is implemented in a vectorized fashion. Default is False.
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number evaluations of the system's right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian. Is always 0 for this solver
     |      as it does not use the Jacobian.
     |  nlu : int
     |      Number of LU decompositions. Is always 0 for this solver.
     |
     |  References
     |  ----------
     |  .. [1] E. Hairer, S. P. Norsett G. Wanner, "Solving Ordinary Differential
     |         Equations I: Nonstiff Problems", Sec. II.
     |  .. [2] `Page with original Fortran code of DOP853
     |          <http://www.unige.ch/~hairer/software.html>`_.
     |
     |  Method resolution order:
     |      DOP853
     |      RungeKutta
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  A = array([[ 0.00000000e+00,  0.00000000e+00,  0.000...23605672e+01,  ...
     |
     |  A_EXTRA = array([[ 5.61675023e-02,  0.00000000e+00,  0.000...e+00, -9....
     |
     |  B = array([ 0.05429373,  0.        ,  0.        ,  0...7, -0.15216095,...
     |
     |  C = array([0.        , 0.05260015, 0.07890023, 0.118...8205, 0.6      ...
     |
     |  C_EXTRA = array([0.1       , 0.2       , 0.77777778])
     |
     |  D = array([[-8.42893828e+00,  0.00000000e+00,  0.000...e+01, -3.917726...
     |
     |  E3 = array([-0.18980075,  0.        ,  0.        ,  0...5,
     |          0.2...
     |
     |  E5 = array([ 0.01312004,  0.        ,  0.        ,  0...2,
     |          0.0...
     |
     |  __annotations__ = {}
     |
     |  error_estimator_order = 7
     |
     |  n_stages = 12
     |
     |  order = 8
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from RungeKutta:
     |
     |  E = NotImplemented
     |
     |  P = NotImplemented
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class DenseOutput(builtins.object)
     |  DenseOutput(t_old, t)
     |
     |  Base class for local interpolant over step made by an ODE solver.
     |
     |  It interpolates between `t_min` and `t_max` (see Attributes below).
     |  Evaluation outside this interval is not forbidden, but the accuracy is not
     |  guaranteed.
     |
     |  Attributes
     |  ----------
     |  t_min, t_max : float
     |      Time range of the interpolation.
     |
     |  Methods defined here:
     |
     |  __call__(self, t)
     |      Evaluate the interpolant.
     |
     |      Parameters
     |      ----------
     |      t : float or array_like with shape (n_points,)
     |          Points to evaluate the solution at.
     |
     |      Returns
     |      -------
     |      y : ndarray, shape (n,) or (n, n_points)
     |          Computed values. Shape depends on whether `t` was a scalar or a
     |          1-D array.
     |
     |  __init__(self, t_old, t)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class IntegrationWarning(builtins.UserWarning)
     |  Warning on issues during integration.
     |
     |  Method resolution order:
     |      IntegrationWarning
     |      builtins.UserWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.UserWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.UserWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.UserWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class LSODA(scipy.integrate._ivp.base.OdeSolver)
     |  LSODA(fun, t0, y0, t_bound, first_step=None, min_step=0.0, max_step=inf, rtol=0.001, atol=1e-06, jac=None, lband=None, uband=None, vectorized=False, **extraneous)
     |
     |  Adams/BDF method with automatic stiffness detection and switching.
     |
     |  This is a wrapper to the Fortran solver from ODEPACK [1]_. It switches
     |  automatically between the nonstiff Adams method and the stiff BDF method.
     |  The method was originally detailed in [2]_.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system: the time derivative of the state ``y``
     |      at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
     |      scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
     |      return an array of the same shape as ``y``. See `vectorized` for more
     |      information.
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  min_step : float, optional
     |      Minimum allowed step size. Default is 0.0, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  jac : None or callable, optional
     |      Jacobian matrix of the right-hand side of the system with respect to
     |      ``y``. The Jacobian matrix has shape (n, n) and its element (i, j) is
     |      equal to ``d f_i / d y_j``. The function will be called as
     |      ``jac(t, y)``. If None (default), the Jacobian will be
     |      approximated by finite differences. It is generally recommended to
     |      provide the Jacobian rather than relying on a finite-difference
     |      approximation.
     |  lband, uband : int or None
     |      Parameters defining the bandwidth of the Jacobian,
     |      i.e., ``jac[i, j] != 0 only for i - lband <= j <= i + uband``. Setting
     |      these requires your jac routine to return the Jacobian in the packed format:
     |      the returned array must have ``n`` columns and ``uband + lband + 1``
     |      rows in which Jacobian diagonals are written. Specifically
     |      ``jac_packed[uband + i - j , j] = jac[i, j]``. The same format is used
     |      in `scipy.linalg.solve_banded` (check for an illustration).
     |      These parameters can be also used with ``jac=None`` to reduce the
     |      number of Jacobian elements estimated by finite differences.
     |  vectorized : bool, optional
     |      Whether `fun` may be called in a vectorized fashion. False (default)
     |      is recommended for this solver.
     |
     |      If ``vectorized`` is False, `fun` will always be called with ``y`` of
     |      shape ``(n,)``, where ``n = len(y0)``.
     |
     |      If ``vectorized`` is True, `fun` may be called with ``y`` of shape
     |      ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
     |      such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
     |      the returned array is the time derivative of the state corresponding
     |      with a column of ``y``).
     |
     |      Setting ``vectorized=True`` allows for faster finite difference
     |      approximation of the Jacobian by methods 'Radau' and 'BDF', but
     |      will result in slower execution for this solver.
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  nfev : int
     |      Number of evaluations of the right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian.
     |
     |  References
     |  ----------
     |  .. [1] A. C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE
     |         Solvers," IMACS Transactions on Scientific Computation, Vol 1.,
     |         pp. 55-64, 1983.
     |  .. [2] L. Petzold, "Automatic selection of methods for solving stiff and
     |         nonstiff systems of ordinary differential equations", SIAM Journal
     |         on Scientific and Statistical Computing, Vol. 4, No. 1, pp. 136-148,
     |         1983.
     |
     |  Method resolution order:
     |      LSODA
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, t0, y0, t_bound, first_step=None, min_step=0.0, max_step=inf, rtol=0.001, atol=1e-06, jac=None, lband=None, uband=None, vectorized=False, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {}
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class ODEintWarning(builtins.Warning)
     |  Warning raised during the execution of `odeint`.
     |
     |  Method resolution order:
     |      ODEintWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Warning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Warning:
     |
     |  __new__(*args, **kwargs) class method of builtins.Warning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class OdeSolution(builtins.object)
     |  OdeSolution(ts, interpolants, alt_segment=False)
     |
     |  Continuous ODE solution.
     |
     |  It is organized as a collection of `DenseOutput` objects which represent
     |  local interpolants. It provides an algorithm to select a right interpolant
     |  for each given point.
     |
     |  The interpolants cover the range between `t_min` and `t_max` (see
     |  Attributes below). Evaluation outside this interval is not forbidden, but
     |  the accuracy is not guaranteed.
     |
     |  When evaluating at a breakpoint (one of the values in `ts`) a segment with
     |  the lower index is selected.
     |
     |  Parameters
     |  ----------
     |  ts : array_like, shape (n_segments + 1,)
     |      Time instants between which local interpolants are defined. Must
     |      be strictly increasing or decreasing (zero segment with two points is
     |      also allowed).
     |  interpolants : list of DenseOutput with n_segments elements
     |      Local interpolants. An i-th interpolant is assumed to be defined
     |      between ``ts[i]`` and ``ts[i + 1]``.
     |  alt_segment : boolean
     |      Requests the alternative interpolant segment selection scheme. At each
     |      solver integration point, two interpolant segments are available. The
     |      default (False) and alternative (True) behaviours select the segment
     |      for which the requested time corresponded to ``t`` and ``t_old``,
     |      respectively. This functionality is only relevant for testing the
     |      interpolants' accuracy: different integrators use different
     |      construction strategies.
     |
     |  Attributes
     |  ----------
     |  t_min, t_max : float
     |      Time range of the interpolation.
     |
     |  Methods defined here:
     |
     |  __call__(self, t)
     |      Evaluate the solution.
     |
     |      Parameters
     |      ----------
     |      t : float or array_like with shape (n_points,)
     |          Points to evaluate at.
     |
     |      Returns
     |      -------
     |      y : ndarray, shape (n_states,) or (n_states, n_points)
     |          Computed values. Shape depends on whether `t` is a scalar or a
     |          1-D array.
     |
     |  __init__(self, ts, interpolants, alt_segment=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class OdeSolver(builtins.object)
     |  OdeSolver(fun, t0, y0, t_bound, vectorized, support_complex=False)
     |
     |  Base class for ODE solvers.
     |
     |  In order to implement a new solver you need to follow the guidelines:
     |
     |      1. A constructor must accept parameters presented in the base class
     |         (listed below) along with any other parameters specific to a solver.
     |      2. A constructor must accept arbitrary extraneous arguments
     |         ``**extraneous``, but warn that these arguments are irrelevant
     |         using `common.warn_extraneous` function. Do not pass these
     |         arguments to the base class.
     |      3. A solver must implement a private method `_step_impl(self)` which
     |         propagates a solver one step further. It must return tuple
     |         ``(success, message)``, where ``success`` is a boolean indicating
     |         whether a step was successful, and ``message`` is a string
     |         containing description of a failure if a step failed or None
     |         otherwise.
     |      4. A solver must implement a private method `_dense_output_impl(self)`,
     |         which returns a `DenseOutput` object covering the last successful
     |         step.
     |      5. A solver must have attributes listed below in Attributes section.
     |         Note that ``t_old`` and ``step_size`` are updated automatically.
     |      6. Use `fun(self, t, y)` method for the system rhs evaluation, this
     |         way the number of function evaluations (`nfev`) will be tracked
     |         automatically.
     |      7. For convenience, a base class provides `fun_single(self, t, y)` and
     |         `fun_vectorized(self, t, y)` for evaluating the rhs in
     |         non-vectorized and vectorized fashions respectively (regardless of
     |         how `fun` from the constructor is implemented). These calls don't
     |         increment `nfev`.
     |      8. If a solver uses a Jacobian matrix and LU decompositions, it should
     |         track the number of Jacobian evaluations (`njev`) and the number of
     |         LU decompositions (`nlu`).
     |      9. By convention, the function evaluations used to compute a finite
     |         difference approximation of the Jacobian should not be counted in
     |         `nfev`, thus use `fun_single(self, t, y)` or
     |         `fun_vectorized(self, t, y)` when computing a finite difference
     |         approximation of the Jacobian.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system: the time derivative of the state ``y``
     |      at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
     |      scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
     |      return an array of the same shape as ``y``. See `vectorized` for more
     |      information.
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time --- the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  vectorized : bool
     |      Whether `fun` can be called in a vectorized fashion. Default is False.
     |
     |      If ``vectorized`` is False, `fun` will always be called with ``y`` of
     |      shape ``(n,)``, where ``n = len(y0)``.
     |
     |      If ``vectorized`` is True, `fun` may be called with ``y`` of shape
     |      ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
     |      such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
     |      the returned array is the time derivative of the state corresponding
     |      with a column of ``y``).
     |
     |      Setting ``vectorized=True`` allows for faster finite difference
     |      approximation of the Jacobian by methods 'Radau' and 'BDF', but
     |      will result in slower execution for other methods. It can also
     |      result in slower overall execution for 'Radau' and 'BDF' in some
     |      circumstances (e.g. small ``len(y0)``).
     |  support_complex : bool, optional
     |      Whether integration in a complex domain should be supported.
     |      Generally determined by a derived solver class capabilities.
     |      Default is False.
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number of the system's rhs evaluations.
     |  njev : int
     |      Number of the Jacobian evaluations.
     |  nlu : int
     |      Number of LU decompositions.
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, t0, y0, t_bound, vectorized, support_complex=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...
     |
     |  __annotations__ = {}

    class RK23(RungeKutta)
     |  RK23(fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |
     |  Explicit Runge-Kutta method of order 3(2).
     |
     |  This uses the Bogacki-Shampine pair of formulas [1]_. The error is controlled
     |  assuming accuracy of the second-order method, but steps are taken using the
     |  third-order accurate formula (local extrapolation is done). A cubic Hermite
     |  polynomial is used for the dense output.
     |
     |  Can be applied in the complex domain.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system: the time derivative of the state ``y``
     |      at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
     |      scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
     |      return an array of the same shape as ``y``. See `vectorized` for more
     |      information.
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  vectorized : bool, optional
     |      Whether `fun` may be called in a vectorized fashion. False (default)
     |      is recommended for this solver.
     |
     |      If ``vectorized`` is False, `fun` will always be called with ``y`` of
     |      shape ``(n,)``, where ``n = len(y0)``.
     |
     |      If ``vectorized`` is True, `fun` may be called with ``y`` of shape
     |      ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
     |      such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
     |      the returned array is the time derivative of the state corresponding
     |      with a column of ``y``).
     |
     |      Setting ``vectorized=True`` allows for faster finite difference
     |      approximation of the Jacobian by methods 'Radau' and 'BDF', but
     |      will result in slower execution for this solver.
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number evaluations of the system's right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian.
     |      Is always 0 for this solver as it does not use the Jacobian.
     |  nlu : int
     |      Number of LU decompositions. Is always 0 for this solver.
     |
     |  References
     |  ----------
     |  .. [1] P. Bogacki, L.F. Shampine, "A 3(2) Pair of Runge-Kutta Formulas",
     |         Appl. Math. Lett. Vol. 2, No. 4. pp. 321-325, 1989.
     |
     |  Method resolution order:
     |      RK23
     |      RungeKutta
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  A = array([[0.  , 0.  , 0.  ],
     |         [0.5 , 0.  , 0.  ],
     |         [0.  ...
     |
     |  B = array([0.22222222, 0.33333333, 0.44444444])
     |
     |  C = array([0.  , 0.5 , 0.75])
     |
     |  E = array([ 0.06944444, -0.08333333, -0.11111111,  0.125     ])
     |
     |  P = array([[ 1.        , -1.33333333,  0.55555556],
     |  ...
     |         [ 0.   ...
     |
     |  __annotations__ = {}
     |
     |  error_estimator_order = 2
     |
     |  n_stages = 3
     |
     |  order = 3
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from RungeKutta:
     |
     |  __init__(self, fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class RK45(RungeKutta)
     |  RK45(fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |
     |  Explicit Runge-Kutta method of order 5(4).
     |
     |  This uses the Dormand-Prince pair of formulas [1]_. The error is controlled
     |  assuming accuracy of the fourth-order method accuracy, but steps are taken
     |  using the fifth-order accurate formula (local extrapolation is done).
     |  A quartic interpolation polynomial is used for the dense output [2]_.
     |
     |  Can be applied in the complex domain.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system. The calling signature is ``fun(t, y)``.
     |      Here ``t`` is a scalar, and there are two options for the ndarray ``y``:
     |      It can either have shape (n,); then ``fun`` must return array_like with
     |      shape (n,). Alternatively it can have shape (n, k); then ``fun``
     |      must return an array_like with shape (n, k), i.e., each column
     |      corresponds to a single column in ``y``. The choice between the two
     |      options is determined by `vectorized` argument (see below).
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  vectorized : bool, optional
     |      Whether `fun` is implemented in a vectorized fashion. Default is False.
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number evaluations of the system's right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian.
     |      Is always 0 for this solver as it does not use the Jacobian.
     |  nlu : int
     |      Number of LU decompositions. Is always 0 for this solver.
     |
     |  References
     |  ----------
     |  .. [1] J. R. Dormand, P. J. Prince, "A family of embedded Runge-Kutta
     |         formulae", Journal of Computational and Applied Mathematics, Vol. 6,
     |         No. 1, pp. 19-26, 1980.
     |  .. [2] L. W. Shampine, "Some Practical Runge-Kutta Formulas", Mathematics
     |         of Computation,, Vol. 46, No. 173, pp. 135-150, 1986.
     |
     |  Method resolution order:
     |      RK45
     |      RungeKutta
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  A = array([[  0.        ,   0.        ,   0.        ...8.90642272,   0...
     |
     |  B = array([ 0.09114583,  0.        ,  0.4492363 ,  0.65104167, -0.3223...
     |
     |  C = array([0.        , 0.2       , 0.3       , 0.8       , 0.88888889,...
     |
     |  E = array([-0.00123264,  0.        ,  0.00425277, -0...7,  0.0508638 ,...
     |
     |  P = array([[ 1.        , -2.85358007,  3.07174346, -...       ,  1.382...
     |
     |  __annotations__ = {}
     |
     |  error_estimator_order = 4
     |
     |  n_stages = 6
     |
     |  order = 5
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from RungeKutta:
     |
     |  __init__(self, fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, vectorized=False, first_step=None, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class Radau(scipy.integrate._ivp.base.OdeSolver)
     |  Radau(fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, jac=None, jac_sparsity=None, vectorized=False, first_step=None, **extraneous)
     |
     |  Implicit Runge-Kutta method of Radau IIA family of order 5.
     |
     |  The implementation follows [1]_. The error is controlled with a
     |  third-order accurate embedded formula. A cubic polynomial which satisfies
     |  the collocation conditions is used for the dense output.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      Right-hand side of the system: the time derivative of the state ``y``
     |      at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
     |      scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. ``fun`` must
     |      return an array of the same shape as ``y``. See `vectorized` for more
     |      information.
     |  t0 : float
     |      Initial time.
     |  y0 : array_like, shape (n,)
     |      Initial state.
     |  t_bound : float
     |      Boundary time - the integration won't continue beyond it. It also
     |      determines the direction of the integration.
     |  first_step : float or None, optional
     |      Initial step size. Default is ``None`` which means that the algorithm
     |      should choose.
     |  max_step : float, optional
     |      Maximum allowed step size. Default is np.inf, i.e., the step size is not
     |      bounded and determined solely by the solver.
     |  rtol, atol : float and array_like, optional
     |      Relative and absolute tolerances. The solver keeps the local error
     |      estimates less than ``atol + rtol * abs(y)``. HHere `rtol` controls a
     |      relative accuracy (number of correct digits), while `atol` controls
     |      absolute accuracy (number of correct decimal places). To achieve the
     |      desired `rtol`, set `atol` to be smaller than the smallest value that
     |      can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
     |      allowable error. If `atol` is larger than ``rtol * abs(y)`` the
     |      number of correct digits is not guaranteed. Conversely, to achieve the
     |      desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
     |      than `atol`. If components of y have different scales, it might be
     |      beneficial to set different `atol` values for different components by
     |      passing array_like with shape (n,) for `atol`. Default values are
     |      1e-3 for `rtol` and 1e-6 for `atol`.
     |  jac : {None, array_like, sparse_matrix, callable}, optional
     |      Jacobian matrix of the right-hand side of the system with respect to
     |      y, required by this method. The Jacobian matrix has shape (n, n) and
     |      its element (i, j) is equal to ``d f_i / d y_j``.
     |      There are three ways to define the Jacobian:
     |
     |          * If array_like or sparse_matrix, the Jacobian is assumed to
     |            be constant.
     |          * If callable, the Jacobian is assumed to depend on both
     |            t and y; it will be called as ``jac(t, y)`` as necessary.
     |            For the 'Radau' and 'BDF' methods, the return value might be a
     |            sparse matrix.
     |          * If None (default), the Jacobian will be approximated by
     |            finite differences.
     |
     |      It is generally recommended to provide the Jacobian rather than
     |      relying on a finite-difference approximation.
     |  jac_sparsity : {None, array_like, sparse matrix}, optional
     |      Defines a sparsity structure of the Jacobian matrix for a
     |      finite-difference approximation. Its shape must be (n, n). This argument
     |      is ignored if `jac` is not `None`. If the Jacobian has only few non-zero
     |      elements in *each* row, providing the sparsity structure will greatly
     |      speed up the computations [2]_. A zero entry means that a corresponding
     |      element in the Jacobian is always zero. If None (default), the Jacobian
     |      is assumed to be dense.
     |  vectorized : bool, optional
     |      Whether `fun` can be called in a vectorized fashion. Default is False.
     |
     |      If ``vectorized`` is False, `fun` will always be called with ``y`` of
     |      shape ``(n,)``, where ``n = len(y0)``.
     |
     |      If ``vectorized`` is True, `fun` may be called with ``y`` of shape
     |      ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
     |      such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
     |      the returned array is the time derivative of the state corresponding
     |      with a column of ``y``).
     |
     |      Setting ``vectorized=True`` allows for faster finite difference
     |      approximation of the Jacobian by this method, but may result in slower
     |      execution overall in some circumstances (e.g. small ``len(y0)``).
     |
     |  Attributes
     |  ----------
     |  n : int
     |      Number of equations.
     |  status : string
     |      Current status of the solver: 'running', 'finished' or 'failed'.
     |  t_bound : float
     |      Boundary time.
     |  direction : float
     |      Integration direction: +1 or -1.
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current state.
     |  t_old : float
     |      Previous time. None if no steps were made yet.
     |  step_size : float
     |      Size of the last successful step. None if no steps were made yet.
     |  nfev : int
     |      Number of evaluations of the right-hand side.
     |  njev : int
     |      Number of evaluations of the Jacobian.
     |  nlu : int
     |      Number of LU decompositions.
     |
     |  References
     |  ----------
     |  .. [1] E. Hairer, G. Wanner, "Solving Ordinary Differential Equations II:
     |         Stiff and Differential-Algebraic Problems", Sec. IV.8.
     |  .. [2] A. Curtis, M. J. D. Powell, and J. Reid, "On the estimation of
     |         sparse Jacobian matrices", Journal of the Institute of Mathematics
     |         and its Applications, 13, pp. 117-120, 1974.
     |
     |  Method resolution order:
     |      Radau
     |      scipy.integrate._ivp.base.OdeSolver
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, t0, y0, t_bound, max_step=inf, rtol=0.001, atol=1e-06, jac=None, jac_sparsity=None, vectorized=False, first_step=None, **extraneous)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {}
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  dense_output(self)
     |      Compute a local interpolant over the last successful step.
     |
     |      Returns
     |      -------
     |      sol : `DenseOutput`
     |          Local interpolant over the last successful step.
     |
     |  step(self)
     |      Perform one integration step.
     |
     |      Returns
     |      -------
     |      message : string or None
     |          Report from the solver. Typically a reason for a failure if
     |          `self.status` is 'failed' after the step was taken or None
     |          otherwise.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  step_size
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.integrate._ivp.base.OdeSolver:
     |
     |  TOO_SMALL_STEP = 'Required step size is less than spacing between numb...

    class complex_ode(ode)
     |  complex_ode(f, jac=None)
     |
     |  A wrapper of ode for complex systems.
     |
     |  This functions similarly as `ode`, but re-maps a complex-valued
     |  equation system to a real-valued one before using the integrators.
     |
     |  Parameters
     |  ----------
     |  f : callable ``f(t, y, *f_args)``
     |      Rhs of the equation. t is a scalar, ``y.shape == (n,)``.
     |      ``f_args`` is set by calling ``set_f_params(*args)``.
     |  jac : callable ``jac(t, y, *jac_args)``
     |      Jacobian of the rhs, ``jac[i,j] = d f[i] / d y[j]``.
     |      ``jac_args`` is set by calling ``set_f_params(*args)``.
     |
     |  Attributes
     |  ----------
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current variable values.
     |
     |  Examples
     |  --------
     |  For usage examples, see `ode`.
     |
     |  Method resolution order:
     |      complex_ode
     |      ode
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, f, jac=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  integrate(self, t, step=False, relax=False)
     |      Find y=y(t), set y as an initial condition, and return y.
     |
     |      Parameters
     |      ----------
     |      t : float
     |          The endpoint of the integration step.
     |      step : bool
     |          If True, and if the integrator supports the step method,
     |          then perform a single integration step and return.
     |          This parameter is provided in order to expose internals of
     |          the implementation, and should not be changed from its default
     |          value in most cases.
     |      relax : bool
     |          If True and if the integrator supports the run_relax method,
     |          then integrate until t_1 >= t and return. ``relax`` is not
     |          referenced if ``step=True``.
     |          This parameter is provided in order to expose internals of
     |          the implementation, and should not be changed from its default
     |          value in most cases.
     |
     |      Returns
     |      -------
     |      y : float
     |          The integrated value at t
     |
     |  set_initial_value(self, y, t=0.0)
     |      Set initial conditions y(t) = y.
     |
     |  set_integrator(self, name, **integrator_params)
     |      Set integrator by name.
     |
     |      Parameters
     |      ----------
     |      name : str
     |          Name of the integrator
     |      **integrator_params
     |          Additional parameters for the integrator.
     |
     |  set_solout(self, solout)
     |      Set callable to be called at every successful integration step.
     |
     |      Parameters
     |      ----------
     |      solout : callable
     |          ``solout(t, y)`` is called at each internal integrator step,
     |          t is a scalar providing the current independent position
     |          y is the current solution ``y.shape == (n,)``
     |          solout should return -1 to stop integration
     |          otherwise it should return None or 0
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  y
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from ode:
     |
     |  get_return_code(self)
     |      Extracts the return code for the integration to enable better control
     |      if the integration fails.
     |
     |      In general, a return code > 0 implies success, while a return code < 0
     |      implies failure.
     |
     |      Notes
     |      -----
     |      This section describes possible return codes and their meaning, for available
     |      integrators that can be selected by `set_integrator` method.
     |
     |      "vode"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call. (Perhaps wrong MF.)
     |      -2           Excess accuracy requested. (Tolerances too small.)
     |      -3           Illegal input detected. (See printed message.)
     |      -4           Repeated error test failures. (Check all input.)
     |      -5           Repeated convergence failures. (Perhaps bad Jacobian
     |                   supplied or wrong choice of MF or tolerances.)
     |      -6           Error weight became zero during problem. (Solution
     |                   component i vanished, and ATOL or ATOL(i) = 0.)
     |      ===========  =======
     |
     |      "zvode"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call. (Perhaps wrong MF.)
     |      -2           Excess accuracy requested. (Tolerances too small.)
     |      -3           Illegal input detected. (See printed message.)
     |      -4           Repeated error test failures. (Check all input.)
     |      -5           Repeated convergence failures. (Perhaps bad Jacobian
     |                   supplied or wrong choice of MF or tolerances.)
     |      -6           Error weight became zero during problem. (Solution
     |                   component i vanished, and ATOL or ATOL(i) = 0.)
     |      ===========  =======
     |
     |      "dopri5"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      1            Integration successful.
     |      2            Integration successful (interrupted by solout).
     |      -1           Input is not consistent.
     |      -2           Larger nsteps is needed.
     |      -3           Step size becomes too small.
     |      -4           Problem is probably stiff (interrupted).
     |      ===========  =======
     |
     |      "dop853"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      1            Integration successful.
     |      2            Integration successful (interrupted by solout).
     |      -1           Input is not consistent.
     |      -2           Larger nsteps is needed.
     |      -3           Step size becomes too small.
     |      -4           Problem is probably stiff (interrupted).
     |      ===========  =======
     |
     |      "lsoda"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call (perhaps wrong Dfun type).
     |      -2           Excess accuracy requested (tolerances too small).
     |      -3           Illegal input detected (internal error).
     |      -4           Repeated error test failures (internal error).
     |      -5           Repeated convergence failures (perhaps bad Jacobian or tolerances).
     |      -6           Error weight became zero during problem.
     |      -7           Internal workspace insufficient to finish (internal error).
     |      ===========  =======
     |
     |  set_f_params(self, *args)
     |      Set extra parameters for user-supplied function f.
     |
     |  set_jac_params(self, *args)
     |      Set extra parameters for user-supplied function jac.
     |
     |  successful(self)
     |      Check if integration was successful.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from ode:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ode(builtins.object)
     |  ode(f, jac=None)
     |
     |  A generic interface class to numeric integrators.
     |
     |  Solve an equation system :math:`y'(t) = f(t,y)` with (optional) ``jac = df/dy``.
     |
     |  *Note*: The first two arguments of ``f(t, y, ...)`` are in the
     |  opposite order of the arguments in the system definition function used
     |  by `scipy.integrate.odeint`.
     |
     |  Parameters
     |  ----------
     |  f : callable ``f(t, y, *f_args)``
     |      Right-hand side of the differential equation. t is a scalar,
     |      ``y.shape == (n,)``.
     |      ``f_args`` is set by calling ``set_f_params(*args)``.
     |      `f` should return a scalar, array or list (not a tuple).
     |  jac : callable ``jac(t, y, *jac_args)``, optional
     |      Jacobian of the right-hand side, ``jac[i,j] = d f[i] / d y[j]``.
     |      ``jac_args`` is set by calling ``set_jac_params(*args)``.
     |
     |  Attributes
     |  ----------
     |  t : float
     |      Current time.
     |  y : ndarray
     |      Current variable values.
     |
     |  See also
     |  --------
     |  odeint : an integrator with a simpler interface based on lsoda from ODEPACK
     |  quad : for finding the area under a curve
     |
     |  Notes
     |  -----
     |  Available integrators are listed below. They can be selected using
     |  the `set_integrator` method.
     |
     |  "vode"
     |
     |      Real-valued Variable-coefficient Ordinary Differential Equation
     |      solver, with fixed-leading-coefficient implementation. It provides
     |      implicit Adams method (for non-stiff problems) and a method based on
     |      backward differentiation formulas (BDF) (for stiff problems).
     |
     |      Source: http://www.netlib.org/ode/vode.f
     |
     |      .. warning::
     |
     |         This integrator is not re-entrant. You cannot have two `ode`
     |         instances using the "vode" integrator at the same time.
     |
     |      This integrator accepts the following parameters in `set_integrator`
     |      method of the `ode` class:
     |
     |      - atol : float or sequence
     |        absolute tolerance for solution
     |      - rtol : float or sequence
     |        relative tolerance for solution
     |      - lband : None or int
     |      - uband : None or int
     |        Jacobian band width, jac[i,j] != 0 for i-lband <= j <= i+uband.
     |        Setting these requires your jac routine to return the jacobian
     |        in packed format, jac_packed[i-j+uband, j] = jac[i,j]. The
     |        dimension of the matrix must be (lband+uband+1, len(y)).
     |      - method: 'adams' or 'bdf'
     |        Which solver to use, Adams (non-stiff) or BDF (stiff)
     |      - with_jacobian : bool
     |        This option is only considered when the user has not supplied a
     |        Jacobian function and has not indicated (by setting either band)
     |        that the Jacobian is banded. In this case, `with_jacobian` specifies
     |        whether the iteration method of the ODE solver's correction step is
     |        chord iteration with an internally generated full Jacobian or
     |        functional iteration with no Jacobian.
     |      - nsteps : int
     |        Maximum number of (internally defined) steps allowed during one
     |        call to the solver.
     |      - first_step : float
     |      - min_step : float
     |      - max_step : float
     |        Limits for the step sizes used by the integrator.
     |      - order : int
     |        Maximum order used by the integrator,
     |        order <= 12 for Adams, <= 5 for BDF.
     |
     |  "zvode"
     |
     |      Complex-valued Variable-coefficient Ordinary Differential Equation
     |      solver, with fixed-leading-coefficient implementation. It provides
     |      implicit Adams method (for non-stiff problems) and a method based on
     |      backward differentiation formulas (BDF) (for stiff problems).
     |
     |      Source: http://www.netlib.org/ode/zvode.f
     |
     |      .. warning::
     |
     |         This integrator is not re-entrant. You cannot have two `ode`
     |         instances using the "zvode" integrator at the same time.
     |
     |      This integrator accepts the same parameters in `set_integrator`
     |      as the "vode" solver.
     |
     |      .. note::
     |
     |          When using ZVODE for a stiff system, it should only be used for
     |          the case in which the function f is analytic, that is, when each f(i)
     |          is an analytic function of each y(j). Analyticity means that the
     |          partial derivative df(i)/dy(j) is a unique complex number, and this
     |          fact is critical in the way ZVODE solves the dense or banded linear
     |          systems that arise in the stiff case. For a complex stiff ODE system
     |          in which f is not analytic, ZVODE is likely to have convergence
     |          failures, and for this problem one should instead use DVODE on the
     |          equivalent real system (in the real and imaginary parts of y).
     |
     |  "lsoda"
     |
     |      Real-valued Variable-coefficient Ordinary Differential Equation
     |      solver, with fixed-leading-coefficient implementation. It provides
     |      automatic method switching between implicit Adams method (for non-stiff
     |      problems) and a method based on backward differentiation formulas (BDF)
     |      (for stiff problems).
     |
     |      Source: http://www.netlib.org/odepack
     |
     |      .. warning::
     |
     |         This integrator is not re-entrant. You cannot have two `ode`
     |         instances using the "lsoda" integrator at the same time.
     |
     |      This integrator accepts the following parameters in `set_integrator`
     |      method of the `ode` class:
     |
     |      - atol : float or sequence
     |        absolute tolerance for solution
     |      - rtol : float or sequence
     |        relative tolerance for solution
     |      - lband : None or int
     |      - uband : None or int
     |        Jacobian band width, jac[i,j] != 0 for i-lband <= j <= i+uband.
     |        Setting these requires your jac routine to return the jacobian
     |        in packed format, jac_packed[i-j+uband, j] = jac[i,j].
     |      - with_jacobian : bool
     |        *Not used.*
     |      - nsteps : int
     |        Maximum number of (internally defined) steps allowed during one
     |        call to the solver.
     |      - first_step : float
     |      - min_step : float
     |      - max_step : float
     |        Limits for the step sizes used by the integrator.
     |      - max_order_ns : int
     |        Maximum order used in the nonstiff case (default 12).
     |      - max_order_s : int
     |        Maximum order used in the stiff case (default 5).
     |      - max_hnil : int
     |        Maximum number of messages reporting too small step size (t + h = t)
     |        (default 0)
     |      - ixpr : int
     |        Whether to generate extra printing at method switches (default False).
     |
     |  "dopri5"
     |
     |      This is an explicit runge-kutta method of order (4)5 due to Dormand &
     |      Prince (with stepsize control and dense output).
     |
     |      Authors:
     |
     |          E. Hairer and G. Wanner
     |          Universite de Geneve, Dept. de Mathematiques
     |          CH-1211 Geneve 24, Switzerland
     |          e-mail:  ernst.hairer@math.unige.ch, gerhard.wanner@math.unige.ch
     |
     |      This code is described in [HNW93]_.
     |
     |      This integrator accepts the following parameters in set_integrator()
     |      method of the ode class:
     |
     |      - atol : float or sequence
     |        absolute tolerance for solution
     |      - rtol : float or sequence
     |        relative tolerance for solution
     |      - nsteps : int
     |        Maximum number of (internally defined) steps allowed during one
     |        call to the solver.
     |      - first_step : float
     |      - max_step : float
     |      - safety : float
     |        Safety factor on new step selection (default 0.9)
     |      - ifactor : float
     |      - dfactor : float
     |        Maximum factor to increase/decrease step size by in one step
     |      - beta : float
     |        Beta parameter for stabilised step size control.
     |      - verbosity : int
     |        Switch for printing messages (< 0 for no messages).
     |
     |  "dop853"
     |
     |      This is an explicit runge-kutta method of order 8(5,3) due to Dormand
     |      & Prince (with stepsize control and dense output).
     |
     |      Options and references the same as "dopri5".
     |
     |  Examples
     |  --------
     |
     |  A problem to integrate and the corresponding jacobian:
     |
     |  >>> from scipy.integrate import ode
     |  >>>
     |  >>> y0, t0 = [1.0j, 2.0], 0
     |  >>>
     |  >>> def f(t, y, arg1):
     |  ...     return [1j*arg1*y[0] + y[1], -arg1*y[1]**2]
     |  >>> def jac(t, y, arg1):
     |  ...     return [[1j*arg1, 1], [0, -arg1*2*y[1]]]
     |
     |  The integration:
     |
     |  >>> r = ode(f, jac).set_integrator('zvode', method='bdf')
     |  >>> r.set_initial_value(y0, t0).set_f_params(2.0).set_jac_params(2.0)
     |  >>> t1 = 10
     |  >>> dt = 1
     |  >>> while r.successful() and r.t < t1:
     |  ...     print(r.t+dt, r.integrate(r.t+dt))
     |  1 [-0.71038232+0.23749653j  0.40000271+0.j        ]
     |  2.0 [0.19098503-0.52359246j 0.22222356+0.j        ]
     |  3.0 [0.47153208+0.52701229j 0.15384681+0.j        ]
     |  4.0 [-0.61905937+0.30726255j  0.11764744+0.j        ]
     |  5.0 [0.02340997-0.61418799j 0.09523835+0.j        ]
     |  6.0 [0.58643071+0.339819j 0.08000018+0.j      ]
     |  7.0 [-0.52070105+0.44525141j  0.06896565+0.j        ]
     |  8.0 [-0.15986733-0.61234476j  0.06060616+0.j        ]
     |  9.0 [0.64850462+0.15048982j 0.05405414+0.j        ]
     |  10.0 [-0.38404699+0.56382299j  0.04878055+0.j        ]
     |
     |  References
     |  ----------
     |  .. [HNW93] E. Hairer, S.P. Norsett and G. Wanner, Solving Ordinary
     |      Differential Equations i. Nonstiff Problems. 2nd edition.
     |      Springer Series in Computational Mathematics,
     |      Springer-Verlag (1993)
     |
     |  Methods defined here:
     |
     |  __init__(self, f, jac=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  get_return_code(self)
     |      Extracts the return code for the integration to enable better control
     |      if the integration fails.
     |
     |      In general, a return code > 0 implies success, while a return code < 0
     |      implies failure.
     |
     |      Notes
     |      -----
     |      This section describes possible return codes and their meaning, for available
     |      integrators that can be selected by `set_integrator` method.
     |
     |      "vode"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call. (Perhaps wrong MF.)
     |      -2           Excess accuracy requested. (Tolerances too small.)
     |      -3           Illegal input detected. (See printed message.)
     |      -4           Repeated error test failures. (Check all input.)
     |      -5           Repeated convergence failures. (Perhaps bad Jacobian
     |                   supplied or wrong choice of MF or tolerances.)
     |      -6           Error weight became zero during problem. (Solution
     |                   component i vanished, and ATOL or ATOL(i) = 0.)
     |      ===========  =======
     |
     |      "zvode"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call. (Perhaps wrong MF.)
     |      -2           Excess accuracy requested. (Tolerances too small.)
     |      -3           Illegal input detected. (See printed message.)
     |      -4           Repeated error test failures. (Check all input.)
     |      -5           Repeated convergence failures. (Perhaps bad Jacobian
     |                   supplied or wrong choice of MF or tolerances.)
     |      -6           Error weight became zero during problem. (Solution
     |                   component i vanished, and ATOL or ATOL(i) = 0.)
     |      ===========  =======
     |
     |      "dopri5"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      1            Integration successful.
     |      2            Integration successful (interrupted by solout).
     |      -1           Input is not consistent.
     |      -2           Larger nsteps is needed.
     |      -3           Step size becomes too small.
     |      -4           Problem is probably stiff (interrupted).
     |      ===========  =======
     |
     |      "dop853"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      1            Integration successful.
     |      2            Integration successful (interrupted by solout).
     |      -1           Input is not consistent.
     |      -2           Larger nsteps is needed.
     |      -3           Step size becomes too small.
     |      -4           Problem is probably stiff (interrupted).
     |      ===========  =======
     |
     |      "lsoda"
     |
     |      ===========  =======
     |      Return Code  Message
     |      ===========  =======
     |      2            Integration successful.
     |      -1           Excess work done on this call (perhaps wrong Dfun type).
     |      -2           Excess accuracy requested (tolerances too small).
     |      -3           Illegal input detected (internal error).
     |      -4           Repeated error test failures (internal error).
     |      -5           Repeated convergence failures (perhaps bad Jacobian or tolerances).
     |      -6           Error weight became zero during problem.
     |      -7           Internal workspace insufficient to finish (internal error).
     |      ===========  =======
     |
     |  integrate(self, t, step=False, relax=False)
     |      Find y=y(t), set y as an initial condition, and return y.
     |
     |      Parameters
     |      ----------
     |      t : float
     |          The endpoint of the integration step.
     |      step : bool
     |          If True, and if the integrator supports the step method,
     |          then perform a single integration step and return.
     |          This parameter is provided in order to expose internals of
     |          the implementation, and should not be changed from its default
     |          value in most cases.
     |      relax : bool
     |          If True and if the integrator supports the run_relax method,
     |          then integrate until t_1 >= t and return. ``relax`` is not
     |          referenced if ``step=True``.
     |          This parameter is provided in order to expose internals of
     |          the implementation, and should not be changed from its default
     |          value in most cases.
     |
     |      Returns
     |      -------
     |      y : float
     |          The integrated value at t
     |
     |  set_f_params(self, *args)
     |      Set extra parameters for user-supplied function f.
     |
     |  set_initial_value(self, y, t=0.0)
     |      Set initial conditions y(t) = y.
     |
     |  set_integrator(self, name, **integrator_params)
     |      Set integrator by name.
     |
     |      Parameters
     |      ----------
     |      name : str
     |          Name of the integrator.
     |      **integrator_params
     |          Additional parameters for the integrator.
     |
     |  set_jac_params(self, *args)
     |      Set extra parameters for user-supplied function jac.
     |
     |  set_solout(self, solout)
     |      Set callable to be called at every successful integration step.
     |
     |      Parameters
     |      ----------
     |      solout : callable
     |          ``solout(t, y)`` is called at each internal integrator step,
     |          t is a scalar providing the current independent position
     |          y is the current solution ``y.shape == (n,)``
     |          solout should return -1 to stop integration
     |          otherwise it should return None or 0
     |
     |  successful(self)
     |      Check if integration was successful.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  y
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    cumulative_simpson(y, *, x=None, dx=1.0, axis=-1, initial=None)
        Cumulatively integrate y(x) using the composite Simpson's 1/3 rule.
        The integral of the samples at every point is calculated by assuming a
        quadratic relationship between each point and the two adjacent points.

        Parameters
        ----------
        y : array_like
            Values to integrate. Requires at least one point along `axis`. If two or fewer
            points are provided along `axis`, Simpson's integration is not possible and the
            result is calculated with `cumulative_trapezoid`.
        x : array_like, optional
            The coordinate to integrate along. Must have the same shape as `y` or
            must be 1D with the same length as `y` along `axis`. `x` must also be
            strictly increasing along `axis`.
            If `x` is None (default), integration is performed using spacing `dx`
            between consecutive elements in `y`.
        dx : scalar or array_like, optional
            Spacing between elements of `y`. Only used if `x` is None. Can either
            be a float, or an array with the same shape as `y`, but of length one along
            `axis`. Default is 1.0.
        axis : int, optional
            Specifies the axis to integrate along. Default is -1 (last axis).
        initial : scalar or array_like, optional
            If given, insert this value at the beginning of the returned result,
            and add it to the rest of the result. Default is None, which means no
            value at ``x[0]`` is returned and `res` has one element less than `y`
            along the axis of integration. Can either be a float, or an array with
            the same shape as `y`, but of length one along `axis`.

        Returns
        -------
        res : ndarray
            The result of cumulative integration of `y` along `axis`.
            If `initial` is None, the shape is such that the axis of integration
            has one less value than `y`. If `initial` is given, the shape is equal
            to that of `y`.

        See Also
        --------
        numpy.cumsum
        cumulative_trapezoid : cumulative integration using the composite
            trapezoidal rule
        simpson : integrator for sampled data using the Composite Simpson's Rule

        Notes
        -----

        .. versionadded:: 1.12.0

        The composite Simpson's 1/3 method can be used to approximate the definite
        integral of a sampled input function :math:`y(x)` [1]_. The method assumes
        a quadratic relationship over the interval containing any three consecutive
        sampled points.

        Consider three consecutive points:
        :math:`(x_1, y_1), (x_2, y_2), (x_3, y_3)`.

        Assuming a quadratic relationship over the three points, the integral over
        the subinterval between :math:`x_1` and :math:`x_2` is given by formula
        (8) of [2]_:

        .. math::
            \int_{x_1}^{x_2} y(x) dx\ &= \frac{x_2-x_1}{6}\left[\
            \left\{3-\frac{x_2-x_1}{x_3-x_1}\right\} y_1 + \
            \left\{3 + \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} + \
            \frac{x_2-x_1}{x_3-x_1}\right\} y_2\\
            - \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} y_3\right]

        The integral between :math:`x_2` and :math:`x_3` is given by swapping
        appearances of :math:`x_1` and :math:`x_3`. The integral is estimated
        separately for each subinterval and then cumulatively summed to obtain
        the final result.

        For samples that are equally spaced, the result is exact if the function
        is a polynomial of order three or less [1]_ and the number of subintervals
        is even. Otherwise, the integral is exact for polynomials of order two or
        less.

        References
        ----------
        .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Simpson's_rule
        .. [2] Cartwright, Kenneth V. Simpson's Rule Cumulative Integration with
                MS Excel and Irregularly-spaced Data. Journal of Mathematical
                Sciences and Mathematics Education. 12 (2): 1-9

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-2, 2, num=20)
        >>> y = x**2
        >>> y_int = integrate.cumulative_simpson(y, x=x, initial=0)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, y_int, 'ro', x, x**3/3 - (x[0])**3/3, 'b-')
        >>> ax.grid()
        >>> plt.show()

        The output of `cumulative_simpson` is similar to that of iteratively
        calling `simpson` with successively higher upper limits of integration, but
        not identical.

        >>> def cumulative_simpson_reference(y, x):
        ...     return np.asarray([integrate.simpson(y[:i], x=x[:i])
        ...                        for i in range(2, len(y) + 1)])
        >>>
        >>> rng = np.random.default_rng(354673834679465)
        >>> x, y = rng.random(size=(2, 10))
        >>> x.sort()
        >>>
        >>> res = integrate.cumulative_simpson(y, x=x)
        >>> ref = cumulative_simpson_reference(y, x)
        >>> equal = np.abs(res - ref) < 1e-15
        >>> equal  # not equal when `simpson` has even number of subintervals
        array([False,  True, False,  True, False,  True, False,  True,  True])

        This is expected: because `cumulative_simpson` has access to more
        information than `simpson`, it can typically produce more accurate
        estimates of the underlying integral over subintervals.

    cumulative_trapezoid(y, x=None, dx=1.0, axis=-1, initial=None)
        Cumulatively integrate y(x) using the composite trapezoidal rule.

        Parameters
        ----------
        y : array_like
            Values to integrate.
        x : array_like, optional
            The coordinate to integrate along. If None (default), use spacing `dx`
            between consecutive elements in `y`.
        dx : float, optional
            Spacing between elements of `y`. Only used if `x` is None.
        axis : int, optional
            Specifies the axis to cumulate. Default is -1 (last axis).
        initial : scalar, optional
            If given, insert this value at the beginning of the returned result.
            0 or None are the only values accepted. Default is None, which means
            `res` has one element less than `y` along the axis of integration.

            .. deprecated:: 1.12.0
                The option for non-zero inputs for `initial` will be deprecated in
                SciPy 1.15.0. After this time, a ValueError will be raised if
                `initial` is not None or 0.

        Returns
        -------
        res : ndarray
            The result of cumulative integration of `y` along `axis`.
            If `initial` is None, the shape is such that the axis of integration
            has one less value than `y`. If `initial` is given, the shape is equal
            to that of `y`.

        See Also
        --------
        numpy.cumsum, numpy.cumprod
        cumulative_simpson : cumulative integration using Simpson's 1/3 rule
        quad : adaptive quadrature using QUADPACK
        fixed_quad : fixed-order Gaussian quadrature
        dblquad : double integrals
        tplquad : triple integrals
        romb : integrators for sampled data

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(-2, 2, num=20)
        >>> y = x
        >>> y_int = integrate.cumulative_trapezoid(y, x, initial=0)
        >>> plt.plot(x, y_int, 'ro', x, y[0] + 0.5 * x**2, 'b-')
        >>> plt.show()

    dblquad(func, a, b, gfun, hfun, args=(), epsabs=1.49e-08, epsrel=1.49e-08)
        Compute a double integral.

        Return the double (definite) integral of ``func(y, x)`` from ``x = a..b``
        and ``y = gfun(x)..hfun(x)``.

        Parameters
        ----------
        func : callable
            A Python function or method of at least two variables: y must be the
            first argument and x the second argument.
        a, b : float
            The limits of integration in x: `a` < `b`
        gfun : callable or float
            The lower boundary curve in y which is a function taking a single
            floating point argument (x) and returning a floating point result
            or a float indicating a constant boundary curve.
        hfun : callable or float
            The upper boundary curve in y (same requirements as `gfun`).
        args : sequence, optional
            Extra arguments to pass to `func`.
        epsabs : float, optional
            Absolute tolerance passed directly to the inner 1-D quadrature
            integration. Default is 1.49e-8. ``dblquad`` tries to obtain
            an accuracy of ``abs(i-result) <= max(epsabs, epsrel*abs(i))``
            where ``i`` = inner integral of ``func(y, x)`` from ``gfun(x)``
            to ``hfun(x)``, and ``result`` is the numerical approximation.
            See `epsrel` below.
        epsrel : float, optional
            Relative tolerance of the inner 1-D integrals. Default is 1.49e-8.
            If ``epsabs <= 0``, `epsrel` must be greater than both 5e-29
            and ``50 * (machine epsilon)``. See `epsabs` above.

        Returns
        -------
        y : float
            The resultant integral.
        abserr : float
            An estimate of the error.

        See Also
        --------
        quad : single integral
        tplquad : triple integral
        nquad : N-dimensional integrals
        fixed_quad : fixed-order Gaussian quadrature
        simpson : integrator for sampled data
        romb : integrator for sampled data
        scipy.special : for coefficients and roots of orthogonal polynomials


        Notes
        -----
        For valid results, the integral must converge; behavior for divergent
        integrals is not guaranteed.

        **Details of QUADPACK level routines**

        `quad` calls routines from the FORTRAN library QUADPACK. This section
        provides details on the conditions for each routine to be called and a
        short description of each routine. For each level of integration, ``qagse``
        is used for finite limits or ``qagie`` is used if either limit (or both!)
        are infinite. The following provides a short description from [1]_ for each
        routine.

        qagse
            is an integrator based on globally adaptive interval
            subdivision in connection with extrapolation, which will
            eliminate the effects of integrand singularities of
            several types.
        qagie
            handles integration over infinite intervals. The infinite range is
            mapped onto a finite interval and subsequently the same strategy as
            in ``QAGS`` is applied.

        References
        ----------

        .. [1] Piessens, Robert; de Doncker-Kapenga, Elise;
               Überhuber, Christoph W.; Kahaner, David (1983).
               QUADPACK: A subroutine package for automatic integration.
               Springer-Verlag.
               ISBN 978-3-540-12553-2.

        Examples
        --------
        Compute the double integral of ``x * y**2`` over the box
        ``x`` ranging from 0 to 2 and ``y`` ranging from 0 to 1.
        That is, :math:`\int^{x=2}_{x=0} \int^{y=1}_{y=0} x y^2 \,dy \,dx`.

        >>> import numpy as np
        >>> from scipy import integrate
        >>> f = lambda y, x: x*y**2
        >>> integrate.dblquad(f, 0, 2, 0, 1)
            (0.6666666666666667, 7.401486830834377e-15)

        Calculate :math:`\int^{x=\pi/4}_{x=0} \int^{y=\cos(x)}_{y=\sin(x)} 1
        \,dy \,dx`.

        >>> f = lambda y, x: 1
        >>> integrate.dblquad(f, 0, np.pi/4, np.sin, np.cos)
            (0.41421356237309503, 1.1083280054755938e-14)

        Calculate :math:`\int^{x=1}_{x=0} \int^{y=2-x}_{y=x} a x y \,dy \,dx`
        for :math:`a=1, 3`.

        >>> f = lambda y, x, a: a*x*y
        >>> integrate.dblquad(f, 0, 1, lambda x: x, lambda x: 2-x, args=(1,))
            (0.33333333333333337, 5.551115123125783e-15)
        >>> integrate.dblquad(f, 0, 1, lambda x: x, lambda x: 2-x, args=(3,))
            (0.9999999999999999, 1.6653345369377348e-14)

        Compute the two-dimensional Gaussian Integral, which is the integral of the
        Gaussian function :math:`f(x,y) = e^{-(x^{2} + y^{2})}`, over
        :math:`(-\infty,+\infty)`. That is, compute the integral
        :math:`\iint^{+\infty}_{-\infty} e^{-(x^{2} + y^{2})} \,dy\,dx`.

        >>> f = lambda x, y: np.exp(-(x ** 2 + y ** 2))
        >>> integrate.dblquad(f, -np.inf, np.inf, -np.inf, np.inf)
            (3.141592653589777, 2.5173086737433208e-08)

    fixed_quad(func, a, b, args=(), n=5)
        Compute a definite integral using fixed-order Gaussian quadrature.

        Integrate `func` from `a` to `b` using Gaussian quadrature of
        order `n`.

        Parameters
        ----------
        func : callable
            A Python function or method to integrate (must accept vector inputs).
            If integrating a vector-valued function, the returned array must have
            shape ``(..., len(x))``.
        a : float
            Lower limit of integration.
        b : float
            Upper limit of integration.
        args : tuple, optional
            Extra arguments to pass to function, if any.
        n : int, optional
            Order of quadrature integration. Default is 5.

        Returns
        -------
        val : float
            Gaussian quadrature approximation to the integral
        none : None
            Statically returned value of None

        See Also
        --------
        quad : adaptive quadrature using QUADPACK
        dblquad : double integrals
        tplquad : triple integrals
        romb : integrators for sampled data
        simpson : integrators for sampled data
        cumulative_trapezoid : cumulative integration for sampled data

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> f = lambda x: x**8
        >>> integrate.fixed_quad(f, 0.0, 1.0, n=4)
        (0.1110884353741496, None)
        >>> integrate.fixed_quad(f, 0.0, 1.0, n=5)
        (0.11111111111111102, None)
        >>> print(1/9.0)  # analytical result
        0.1111111111111111

        >>> integrate.fixed_quad(np.cos, 0.0, np.pi/2, n=4)
        (0.9999999771971152, None)
        >>> integrate.fixed_quad(np.cos, 0.0, np.pi/2, n=5)
        (1.000000000039565, None)
        >>> np.sin(np.pi/2)-np.sin(0)  # analytical result
        1.0

    newton_cotes(rn, equal=0)
        Return weights and error coefficient for Newton-Cotes integration.

        Suppose we have (N+1) samples of f at the positions
        x_0, x_1, ..., x_N. Then an N-point Newton-Cotes formula for the
        integral between x_0 and x_N is:

        :math:`\int_{x_0}^{x_N} f(x)dx = \Delta x \sum_{i=0}^{N} a_i f(x_i)
        + B_N (\Delta x)^{N+2} f^{N+1} (\xi)`

        where :math:`\xi \in [x_0,x_N]`
        and :math:`\Delta x = \frac{x_N-x_0}{N}` is the average samples spacing.

        If the samples are equally-spaced and N is even, then the error
        term is :math:`B_N (\Delta x)^{N+3} f^{N+2}(\xi)`.

        Parameters
        ----------
        rn : int
            The integer order for equally-spaced data or the relative positions of
            the samples with the first sample at 0 and the last at N, where N+1 is
            the length of `rn`. N is the order of the Newton-Cotes integration.
        equal : int, optional
            Set to 1 to enforce equally spaced data.

        Returns
        -------
        an : ndarray
            1-D array of weights to apply to the function at the provided sample
            positions.
        B : float
            Error coefficient.

        Notes
        -----
        Normally, the Newton-Cotes rules are used on smaller integration
        regions and a composite rule is used to return the total integral.

        Examples
        --------
        Compute the integral of sin(x) in [0, :math:`\pi`]:

        >>> from scipy.integrate import newton_cotes
        >>> import numpy as np
        >>> def f(x):
        ...     return np.sin(x)
        >>> a = 0
        >>> b = np.pi
        >>> exact = 2
        >>> for N in [2, 4, 6, 8, 10]:
        ...     x = np.linspace(a, b, N + 1)
        ...     an, B = newton_cotes(N, 1)
        ...     dx = (b - a) / N
        ...     quad = dx * np.sum(an * f(x))
        ...     error = abs(quad - exact)
        ...     print('{:2d}  {:10.9f}  {:.5e}'.format(N, quad, error))
        ...
         2   2.094395102   9.43951e-02
         4   1.998570732   1.42927e-03
         6   2.000017814   1.78136e-05
         8   1.999999835   1.64725e-07
        10   2.000000001   1.14677e-09

    nquad(func, ranges, args=None, opts=None, full_output=False)
        Integration over multiple variables.

        Wraps `quad` to enable integration over multiple variables.
        Various options allow improved integration of discontinuous functions, as
        well as the use of weighted integration, and generally finer control of the
        integration process.

        Parameters
        ----------
        func : {callable, scipy.LowLevelCallable}
            The function to be integrated. Has arguments of ``x0, ... xn``,
            ``t0, ... tm``, where integration is carried out over ``x0, ... xn``,
            which must be floats.  Where ``t0, ... tm`` are extra arguments
            passed in args.
            Function signature should be ``func(x0, x1, ..., xn, t0, t1, ..., tm)``.
            Integration is carried out in order.  That is, integration over ``x0``
            is the innermost integral, and ``xn`` is the outermost.

            If the user desires improved integration performance, then `f` may
            be a `scipy.LowLevelCallable` with one of the signatures::

                double func(int n, double *xx)
                double func(int n, double *xx, void *user_data)

            where ``n`` is the number of variables and args.  The ``xx`` array
            contains the coordinates and extra arguments. ``user_data`` is the data
            contained in the `scipy.LowLevelCallable`.
        ranges : iterable object
            Each element of ranges may be either a sequence  of 2 numbers, or else
            a callable that returns such a sequence. ``ranges[0]`` corresponds to
            integration over x0, and so on. If an element of ranges is a callable,
            then it will be called with all of the integration arguments available,
            as well as any parametric arguments. e.g., if
            ``func = f(x0, x1, x2, t0, t1)``, then ``ranges[0]`` may be defined as
            either ``(a, b)`` or else as ``(a, b) = range0(x1, x2, t0, t1)``.
        args : iterable object, optional
            Additional arguments ``t0, ... tn``, required by ``func``, ``ranges``,
            and ``opts``.
        opts : iterable object or dict, optional
            Options to be passed to `quad`. May be empty, a dict, or
            a sequence of dicts or functions that return a dict. If empty, the
            default options from scipy.integrate.quad are used. If a dict, the same
            options are used for all levels of integraion. If a sequence, then each
            element of the sequence corresponds to a particular integration. e.g.,
            ``opts[0]`` corresponds to integration over ``x0``, and so on. If a
            callable, the signature must be the same as for ``ranges``. The
            available options together with their default values are:

              - epsabs = 1.49e-08
              - epsrel = 1.49e-08
              - limit  = 50
              - points = None
              - weight = None
              - wvar   = None
              - wopts  = None

            For more information on these options, see `quad`.

        full_output : bool, optional
            Partial implementation of ``full_output`` from scipy.integrate.quad.
            The number of integrand function evaluations ``neval`` can be obtained
            by setting ``full_output=True`` when calling nquad.

        Returns
        -------
        result : float
            The result of the integration.
        abserr : float
            The maximum of the estimates of the absolute error in the various
            integration results.
        out_dict : dict, optional
            A dict containing additional information on the integration.

        See Also
        --------
        quad : 1-D numerical integration
        dblquad, tplquad : double and triple integrals
        fixed_quad : fixed-order Gaussian quadrature

        Notes
        -----
        For valid results, the integral must converge; behavior for divergent
        integrals is not guaranteed.

        **Details of QUADPACK level routines**

        `nquad` calls routines from the FORTRAN library QUADPACK. This section
        provides details on the conditions for each routine to be called and a
        short description of each routine. The routine called depends on
        `weight`, `points` and the integration limits `a` and `b`.

        ================  ==============  ==========  =====================
        QUADPACK routine  `weight`        `points`    infinite bounds
        ================  ==============  ==========  =====================
        qagse             None            No          No
        qagie             None            No          Yes
        qagpe             None            Yes         No
        qawoe             'sin', 'cos'    No          No
        qawfe             'sin', 'cos'    No          either `a` or `b`
        qawse             'alg*'          No          No
        qawce             'cauchy'        No          No
        ================  ==============  ==========  =====================

        The following provides a short description from [1]_ for each
        routine.

        qagse
            is an integrator based on globally adaptive interval
            subdivision in connection with extrapolation, which will
            eliminate the effects of integrand singularities of
            several types.
        qagie
            handles integration over infinite intervals. The infinite range is
            mapped onto a finite interval and subsequently the same strategy as
            in ``QAGS`` is applied.
        qagpe
            serves the same purposes as QAGS, but also allows the
            user to provide explicit information about the location
            and type of trouble-spots i.e. the abscissae of internal
            singularities, discontinuities and other difficulties of
            the integrand function.
        qawoe
            is an integrator for the evaluation of
            :math:`\int^b_a \cos(\omega x)f(x)dx` or
            :math:`\int^b_a \sin(\omega x)f(x)dx`
            over a finite interval [a,b], where :math:`\omega` and :math:`f`
            are specified by the user. The rule evaluation component is based
            on the modified Clenshaw-Curtis technique

            An adaptive subdivision scheme is used in connection
            with an extrapolation procedure, which is a modification
            of that in ``QAGS`` and allows the algorithm to deal with
            singularities in :math:`f(x)`.
        qawfe
            calculates the Fourier transform
            :math:`\int^\infty_a \cos(\omega x)f(x)dx` or
            :math:`\int^\infty_a \sin(\omega x)f(x)dx`
            for user-provided :math:`\omega` and :math:`f`. The procedure of
            ``QAWO`` is applied on successive finite intervals, and convergence
            acceleration by means of the :math:`\varepsilon`-algorithm is applied
            to the series of integral approximations.
        qawse
            approximate :math:`\int^b_a w(x)f(x)dx`, with :math:`a < b` where
            :math:`w(x) = (x-a)^{\alpha}(b-x)^{\beta}v(x)` with
            :math:`\alpha,\beta > -1`, where :math:`v(x)` may be one of the
            following functions: :math:`1`, :math:`\log(x-a)`, :math:`\log(b-x)`,
            :math:`\log(x-a)\log(b-x)`.

            The user specifies :math:`\alpha`, :math:`\beta` and the type of the
            function :math:`v`. A globally adaptive subdivision strategy is
            applied, with modified Clenshaw-Curtis integration on those
            subintervals which contain `a` or `b`.
        qawce
            compute :math:`\int^b_a f(x) / (x-c)dx` where the integral must be
            interpreted as a Cauchy principal value integral, for user specified
            :math:`c` and :math:`f`. The strategy is globally adaptive. Modified
            Clenshaw-Curtis integration is used on those intervals containing the
            point :math:`x = c`.

        References
        ----------

        .. [1] Piessens, Robert; de Doncker-Kapenga, Elise;
               Überhuber, Christoph W.; Kahaner, David (1983).
               QUADPACK: A subroutine package for automatic integration.
               Springer-Verlag.
               ISBN 978-3-540-12553-2.

        Examples
        --------
        Calculate

        .. math::

            \int^{1}_{-0.15} \int^{0.8}_{0.13} \int^{1}_{-1} \int^{1}_{0}
            f(x_0, x_1, x_2, x_3) \,dx_0 \,dx_1 \,dx_2 \,dx_3 ,

        where

        .. math::

            f(x_0, x_1, x_2, x_3) = \begin{cases}
              x_0^2+x_1 x_2-x_3^3+ \sin{x_0}+1 & (x_0-0.2 x_3-0.5-0.25 x_1 > 0) \\
              x_0^2+x_1 x_2-x_3^3+ \sin{x_0}+0 & (x_0-0.2 x_3-0.5-0.25 x_1 \leq 0)
            \end{cases} .

        >>> import numpy as np
        >>> from scipy import integrate
        >>> func = lambda x0,x1,x2,x3 : x0**2 + x1*x2 - x3**3 + np.sin(x0) + (
        ...                                 1 if (x0-.2*x3-.5-.25*x1>0) else 0)
        >>> def opts0(*args, **kwargs):
        ...     return {'points':[0.2*args[2] + 0.5 + 0.25*args[0]]}
        >>> integrate.nquad(func, [[0,1], [-1,1], [.13,.8], [-.15,1]],
        ...                 opts=[opts0,{},{},{}], full_output=True)
        (1.5267454070738633, 2.9437360001402324e-14, {'neval': 388962})

        Calculate

        .. math::

            \int^{t_0+t_1+1}_{t_0+t_1-1}
            \int^{x_2+t_0^2 t_1^3+1}_{x_2+t_0^2 t_1^3-1}
            \int^{t_0 x_1+t_1 x_2+1}_{t_0 x_1+t_1 x_2-1}
            f(x_0,x_1, x_2,t_0,t_1)
            \,dx_0 \,dx_1 \,dx_2,

        where

        .. math::

            f(x_0, x_1, x_2, t_0, t_1) = \begin{cases}
              x_0 x_2^2 + \sin{x_1}+2 & (x_0+t_1 x_1-t_0 > 0) \\
              x_0 x_2^2 +\sin{x_1}+1 & (x_0+t_1 x_1-t_0 \leq 0)
            \end{cases}

        and :math:`(t_0, t_1) = (0, 1)` .

        >>> def func2(x0, x1, x2, t0, t1):
        ...     return x0*x2**2 + np.sin(x1) + 1 + (1 if x0+t1*x1-t0>0 else 0)
        >>> def lim0(x1, x2, t0, t1):
        ...     return [t0*x1 + t1*x2 - 1, t0*x1 + t1*x2 + 1]
        >>> def lim1(x2, t0, t1):
        ...     return [x2 + t0**2*t1**3 - 1, x2 + t0**2*t1**3 + 1]
        >>> def lim2(t0, t1):
        ...     return [t0 + t1 - 1, t0 + t1 + 1]
        >>> def opts0(x1, x2, t0, t1):
        ...     return {'points' : [t0 - t1*x1]}
        >>> def opts1(x2, t0, t1):
        ...     return {}
        >>> def opts2(t0, t1):
        ...     return {}
        >>> integrate.nquad(func2, [lim0, lim1, lim2], args=(0,1),
        ...                 opts=[opts0, opts1, opts2])
        (36.099919226771625, 1.8546948553373528e-07)

    odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0, tfirst=False)
        Integrate a system of ordinary differential equations.

        .. note:: For new code, use `scipy.integrate.solve_ivp` to solve a
                  differential equation.

        Solve a system of ordinary differential equations using lsoda from the
        FORTRAN library odepack.

        Solves the initial value problem for stiff or non-stiff systems
        of first order ode-s::

            dy/dt = func(y, t, ...)  [or func(t, y, ...)]

        where y can be a vector.

        .. note:: By default, the required order of the first two arguments of
                  `func` are in the opposite order of the arguments in the system
                  definition function used by the `scipy.integrate.ode` class and
                  the function `scipy.integrate.solve_ivp`. To use a function with
                  the signature ``func(t, y, ...)``, the argument `tfirst` must be
                  set to ``True``.

        Parameters
        ----------
        func : callable(y, t, ...) or callable(t, y, ...)
            Computes the derivative of y at t.
            If the signature is ``callable(t, y, ...)``, then the argument
            `tfirst` must be set ``True``.
            `func` must not modify the data in `y`, as it is a
            view of the data used internally by the ODE solver.
        y0 : array
            Initial condition on y (can be a vector).
        t : array
            A sequence of time points for which to solve for y. The initial
            value point should be the first element of this sequence.
            This sequence must be monotonically increasing or monotonically
            decreasing; repeated values are allowed.
        args : tuple, optional
            Extra arguments to pass to function.
        Dfun : callable(y, t, ...) or callable(t, y, ...)
            Gradient (Jacobian) of `func`.
            If the signature is ``callable(t, y, ...)``, then the argument
            `tfirst` must be set ``True``.
            `Dfun` must not modify the data in `y`, as it is a
            view of the data used internally by the ODE solver.
        col_deriv : bool, optional
            True if `Dfun` defines derivatives down columns (faster),
            otherwise `Dfun` should define derivatives across rows.
        full_output : bool, optional
            True if to return a dictionary of optional outputs as the second output
        printmessg : bool, optional
            Whether to print the convergence message
        tfirst : bool, optional
            If True, the first two arguments of `func` (and `Dfun`, if given)
            must ``t, y`` instead of the default ``y, t``.

            .. versionadded:: 1.1.0

        Returns
        -------
        y : array, shape (len(t), len(y0))
            Array containing the value of y for each desired time in t,
            with the initial value `y0` in the first row.
        infodict : dict, only returned if full_output == True
            Dictionary containing additional output information

            =======  ============================================================
            key      meaning
            =======  ============================================================
            'hu'     vector of step sizes successfully used for each time step
            'tcur'   vector with the value of t reached for each time step
                     (will always be at least as large as the input times)
            'tolsf'  vector of tolerance scale factors, greater than 1.0,
                     computed when a request for too much accuracy was detected
            'tsw'    value of t at the time of the last method switch
                     (given for each time step)
            'nst'    cumulative number of time steps
            'nfe'    cumulative number of function evaluations for each time step
            'nje'    cumulative number of jacobian evaluations for each time step
            'nqu'    a vector of method orders for each successful step
            'imxer'  index of the component of largest magnitude in the
                     weighted local error vector (e / ewt) on an error return, -1
                     otherwise
            'lenrw'  the length of the double work array required
            'leniw'  the length of integer work array required
            'mused'  a vector of method indicators for each successful time step:
                     1: adams (nonstiff), 2: bdf (stiff)
            =======  ============================================================

        Other Parameters
        ----------------
        ml, mu : int, optional
            If either of these are not None or non-negative, then the
            Jacobian is assumed to be banded. These give the number of
            lower and upper non-zero diagonals in this banded matrix.
            For the banded case, `Dfun` should return a matrix whose
            rows contain the non-zero bands (starting with the lowest diagonal).
            Thus, the return matrix `jac` from `Dfun` should have shape
            ``(ml + mu + 1, len(y0))`` when ``ml >=0`` or ``mu >=0``.
            The data in `jac` must be stored such that ``jac[i - j + mu, j]``
            holds the derivative of the ``i``\ th equation with respect to the
            ``j``\ th state variable.  If `col_deriv` is True, the transpose of
            this `jac` must be returned.
        rtol, atol : float, optional
            The input parameters `rtol` and `atol` determine the error
            control performed by the solver.  The solver will control the
            vector, e, of estimated local errors in y, according to an
            inequality of the form ``max-norm of (e / ewt) <= 1``,
            where ewt is a vector of positive error weights computed as
            ``ewt = rtol * abs(y) + atol``.
            rtol and atol can be either vectors the same length as y or scalars.
            Defaults to 1.49012e-8.
        tcrit : ndarray, optional
            Vector of critical points (e.g., singularities) where integration
            care should be taken.
        h0 : float, (0: solver-determined), optional
            The step size to be attempted on the first step.
        hmax : float, (0: solver-determined), optional
            The maximum absolute step size allowed.
        hmin : float, (0: solver-determined), optional
            The minimum absolute step size allowed.
        ixpr : bool, optional
            Whether to generate extra printing at method switches.
        mxstep : int, (0: solver-determined), optional
            Maximum number of (internally defined) steps allowed for each
            integration point in t.
        mxhnil : int, (0: solver-determined), optional
            Maximum number of messages printed.
        mxordn : int, (0: solver-determined), optional
            Maximum order to be allowed for the non-stiff (Adams) method.
        mxords : int, (0: solver-determined), optional
            Maximum order to be allowed for the stiff (BDF) method.

        See Also
        --------
        solve_ivp : solve an initial value problem for a system of ODEs
        ode : a more object-oriented integrator based on VODE
        quad : for finding the area under a curve

        Examples
        --------
        The second order differential equation for the angle `theta` of a
        pendulum acted on by gravity with friction can be written::

            theta''(t) + b*theta'(t) + c*sin(theta(t)) = 0

        where `b` and `c` are positive constants, and a prime (') denotes a
        derivative. To solve this equation with `odeint`, we must first convert
        it to a system of first order equations. By defining the angular
        velocity ``omega(t) = theta'(t)``, we obtain the system::

            theta'(t) = omega(t)
            omega'(t) = -b*omega(t) - c*sin(theta(t))

        Let `y` be the vector [`theta`, `omega`]. We implement this system
        in Python as:

        >>> import numpy as np
        >>> def pend(y, t, b, c):
        ...     theta, omega = y
        ...     dydt = [omega, -b*omega - c*np.sin(theta)]
        ...     return dydt
        ...

        We assume the constants are `b` = 0.25 and `c` = 5.0:

        >>> b = 0.25
        >>> c = 5.0

        For initial conditions, we assume the pendulum is nearly vertical
        with `theta(0)` = `pi` - 0.1, and is initially at rest, so
        `omega(0)` = 0.  Then the vector of initial conditions is

        >>> y0 = [np.pi - 0.1, 0.0]

        We will generate a solution at 101 evenly spaced samples in the interval
        0 <= `t` <= 10.  So our array of times is:

        >>> t = np.linspace(0, 10, 101)

        Call `odeint` to generate the solution. To pass the parameters
        `b` and `c` to `pend`, we give them to `odeint` using the `args`
        argument.

        >>> from scipy.integrate import odeint
        >>> sol = odeint(pend, y0, t, args=(b, c))

        The solution is an array with shape (101, 2). The first column
        is `theta(t)`, and the second is `omega(t)`. The following code
        plots both components.

        >>> import matplotlib.pyplot as plt
        >>> plt.plot(t, sol[:, 0], 'b', label='theta(t)')
        >>> plt.plot(t, sol[:, 1], 'g', label='omega(t)')
        >>> plt.legend(loc='best')
        >>> plt.xlabel('t')
        >>> plt.grid()
        >>> plt.show()

    qmc_quad(func, a, b, *, n_estimates=8, n_points=1024, qrng=None, log=False)
        Compute an integral in N-dimensions using Quasi-Monte Carlo quadrature.

        Parameters
        ----------
        func : callable
            The integrand. Must accept a single argument ``x``, an array which
            specifies the point(s) at which to evaluate the scalar-valued
            integrand, and return the value(s) of the integrand.
            For efficiency, the function should be vectorized to accept an array of
            shape ``(d, n_points)``, where ``d`` is the number of variables (i.e.
            the dimensionality of the function domain) and `n_points` is the number
            of quadrature points, and return an array of shape ``(n_points,)``,
            the integrand at each quadrature point.
        a, b : array-like
            One-dimensional arrays specifying the lower and upper integration
            limits, respectively, of each of the ``d`` variables.
        n_estimates, n_points : int, optional
            `n_estimates` (default: 8) statistically independent QMC samples, each
            of `n_points` (default: 1024) points, will be generated by `qrng`.
            The total number of points at which the integrand `func` will be
            evaluated is ``n_points * n_estimates``. See Notes for details.
        qrng : `~scipy.stats.qmc.QMCEngine`, optional
            An instance of the QMCEngine from which to sample QMC points.
            The QMCEngine must be initialized to a number of dimensions ``d``
            corresponding with the number of variables ``x1, ..., xd`` passed to
            `func`.
            The provided QMCEngine is used to produce the first integral estimate.
            If `n_estimates` is greater than one, additional QMCEngines are
            spawned from the first (with scrambling enabled, if it is an option.)
            If a QMCEngine is not provided, the default `scipy.stats.qmc.Halton`
            will be initialized with the number of dimensions determine from
            the length of `a`.
        log : boolean, default: False
            When set to True, `func` returns the log of the integrand, and
            the result object contains the log of the integral.

        Returns
        -------
        result : object
            A result object with attributes:

            integral : float
                The estimate of the integral.
            standard_error :
                The error estimate. See Notes for interpretation.

        Notes
        -----
        Values of the integrand at each of the `n_points` points of a QMC sample
        are used to produce an estimate of the integral. This estimate is drawn
        from a population of possible estimates of the integral, the value of
        which we obtain depends on the particular points at which the integral
        was evaluated. We perform this process `n_estimates` times, each time
        evaluating the integrand at different scrambled QMC points, effectively
        drawing i.i.d. random samples from the population of integral estimates.
        The sample mean :math:`m` of these integral estimates is an
        unbiased estimator of the true value of the integral, and the standard
        error of the mean :math:`s` of these estimates may be used to generate
        confidence intervals using the t distribution with ``n_estimates - 1``
        degrees of freedom. Perhaps counter-intuitively, increasing `n_points`
        while keeping the total number of function evaluation points
        ``n_points * n_estimates`` fixed tends to reduce the actual error, whereas
        increasing `n_estimates` tends to decrease the error estimate.

        Examples
        --------
        QMC quadrature is particularly useful for computing integrals in higher
        dimensions. An example integrand is the probability density function
        of a multivariate normal distribution.

        >>> import numpy as np
        >>> from scipy import stats
        >>> dim = 8
        >>> mean = np.zeros(dim)
        >>> cov = np.eye(dim)
        >>> def func(x):
        ...     # `multivariate_normal` expects the _last_ axis to correspond with
        ...     # the dimensionality of the space, so `x` must be transposed
        ...     return stats.multivariate_normal.pdf(x.T, mean, cov)

        To compute the integral over the unit hypercube:

        >>> from scipy.integrate import qmc_quad
        >>> a = np.zeros(dim)
        >>> b = np.ones(dim)
        >>> rng = np.random.default_rng()
        >>> qrng = stats.qmc.Halton(d=dim, seed=rng)
        >>> n_estimates = 8
        >>> res = qmc_quad(func, a, b, n_estimates=n_estimates, qrng=qrng)
        >>> res.integral, res.standard_error
        (0.00018429555666024108, 1.0389431116001344e-07)

        A two-sided, 99% confidence interval for the integral may be estimated
        as:

        >>> t = stats.t(df=n_estimates-1, loc=res.integral,
        ...             scale=res.standard_error)
        >>> t.interval(0.99)
        (0.0001839319802536469, 0.00018465913306683527)

        Indeed, the value reported by `scipy.stats.multivariate_normal` is
        within this range.

        >>> stats.multivariate_normal.cdf(b, mean, cov, lower_limit=a)
        0.00018430867675187443

    quad(func, a, b, args=(), full_output=0, epsabs=1.49e-08, epsrel=1.49e-08, limit=50, points=None, weight=None, wvar=None, wopts=None, maxp1=50, limlst=50, complex_func=False)
        Compute a definite integral.

        Integrate func from `a` to `b` (possibly infinite interval) using a
        technique from the Fortran library QUADPACK.

        Parameters
        ----------
        func : {function, scipy.LowLevelCallable}
            A Python function or method to integrate. If `func` takes many
            arguments, it is integrated along the axis corresponding to the
            first argument.

            If the user desires improved integration performance, then `f` may
            be a `scipy.LowLevelCallable` with one of the signatures::

                double func(double x)
                double func(double x, void *user_data)
                double func(int n, double *xx)
                double func(int n, double *xx, void *user_data)

            The ``user_data`` is the data contained in the `scipy.LowLevelCallable`.
            In the call forms with ``xx``,  ``n`` is the length of the ``xx``
            array which contains ``xx[0] == x`` and the rest of the items are
            numbers contained in the ``args`` argument of quad.

            In addition, certain ctypes call signatures are supported for
            backward compatibility, but those should not be used in new code.
        a : float
            Lower limit of integration (use -numpy.inf for -infinity).
        b : float
            Upper limit of integration (use numpy.inf for +infinity).
        args : tuple, optional
            Extra arguments to pass to `func`.
        full_output : int, optional
            Non-zero to return a dictionary of integration information.
            If non-zero, warning messages are also suppressed and the
            message is appended to the output tuple.
        complex_func : bool, optional
            Indicate if the function's (`func`) return type is real
            (``complex_func=False``: default) or complex (``complex_func=True``).
            In both cases, the function's argument is real.
            If full_output is also non-zero, the `infodict`, `message`, and
            `explain` for the real and complex components are returned in
            a dictionary with keys "real output" and "imag output".

        Returns
        -------
        y : float
            The integral of func from `a` to `b`.
        abserr : float
            An estimate of the absolute error in the result.
        infodict : dict
            A dictionary containing additional information.
        message
            A convergence message.
        explain
            Appended only with 'cos' or 'sin' weighting and infinite
            integration limits, it contains an explanation of the codes in
            infodict['ierlst']

        Other Parameters
        ----------------
        epsabs : float or int, optional
            Absolute error tolerance. Default is 1.49e-8. `quad` tries to obtain
            an accuracy of ``abs(i-result) <= max(epsabs, epsrel*abs(i))``
            where ``i`` = integral of `func` from `a` to `b`, and ``result`` is the
            numerical approximation. See `epsrel` below.
        epsrel : float or int, optional
            Relative error tolerance. Default is 1.49e-8.
            If ``epsabs <= 0``, `epsrel` must be greater than both 5e-29
            and ``50 * (machine epsilon)``. See `epsabs` above.
        limit : float or int, optional
            An upper bound on the number of subintervals used in the adaptive
            algorithm.
        points : (sequence of floats,ints), optional
            A sequence of break points in the bounded integration interval
            where local difficulties of the integrand may occur (e.g.,
            singularities, discontinuities). The sequence does not have
            to be sorted. Note that this option cannot be used in conjunction
            with ``weight``.
        weight : float or int, optional
            String indicating weighting function. Full explanation for this
            and the remaining arguments can be found below.
        wvar : optional
            Variables for use with weighting functions.
        wopts : optional
            Optional input for reusing Chebyshev moments.
        maxp1 : float or int, optional
            An upper bound on the number of Chebyshev moments.
        limlst : int, optional
            Upper bound on the number of cycles (>=3) for use with a sinusoidal
            weighting and an infinite end-point.

        See Also
        --------
        dblquad : double integral
        tplquad : triple integral
        nquad : n-dimensional integrals (uses `quad` recursively)
        fixed_quad : fixed-order Gaussian quadrature
        simpson : integrator for sampled data
        romb : integrator for sampled data
        scipy.special : for coefficients and roots of orthogonal polynomials

        Notes
        -----
        For valid results, the integral must converge; behavior for divergent
        integrals is not guaranteed.

        **Extra information for quad() inputs and outputs**

        If full_output is non-zero, then the third output argument
        (infodict) is a dictionary with entries as tabulated below. For
        infinite limits, the range is transformed to (0,1) and the
        optional outputs are given with respect to this transformed range.
        Let M be the input argument limit and let K be infodict['last'].
        The entries are:

        'neval'
            The number of function evaluations.
        'last'
            The number, K, of subintervals produced in the subdivision process.
        'alist'
            A rank-1 array of length M, the first K elements of which are the
            left end points of the subintervals in the partition of the
            integration range.
        'blist'
            A rank-1 array of length M, the first K elements of which are the
            right end points of the subintervals.
        'rlist'
            A rank-1 array of length M, the first K elements of which are the
            integral approximations on the subintervals.
        'elist'
            A rank-1 array of length M, the first K elements of which are the
            moduli of the absolute error estimates on the subintervals.
        'iord'
            A rank-1 integer array of length M, the first L elements of
            which are pointers to the error estimates over the subintervals
            with ``L=K`` if ``K<=M/2+2`` or ``L=M+1-K`` otherwise. Let I be the
            sequence ``infodict['iord']`` and let E be the sequence
            ``infodict['elist']``.  Then ``E[I[1]], ..., E[I[L]]`` forms a
            decreasing sequence.

        If the input argument points is provided (i.e., it is not None),
        the following additional outputs are placed in the output
        dictionary. Assume the points sequence is of length P.

        'pts'
            A rank-1 array of length P+2 containing the integration limits
            and the break points of the intervals in ascending order.
            This is an array giving the subintervals over which integration
            will occur.
        'level'
            A rank-1 integer array of length M (=limit), containing the
            subdivision levels of the subintervals, i.e., if (aa,bb) is a
            subinterval of ``(pts[1], pts[2])`` where ``pts[0]`` and ``pts[2]``
            are adjacent elements of ``infodict['pts']``, then (aa,bb) has level l
            if ``|bb-aa| = |pts[2]-pts[1]| * 2**(-l)``.
        'ndin'
            A rank-1 integer array of length P+2. After the first integration
            over the intervals (pts[1], pts[2]), the error estimates over some
            of the intervals may have been increased artificially in order to
            put their subdivision forward. This array has ones in slots
            corresponding to the subintervals for which this happens.

        **Weighting the integrand**

        The input variables, *weight* and *wvar*, are used to weight the
        integrand by a select list of functions. Different integration
        methods are used to compute the integral with these weighting
        functions, and these do not support specifying break points. The
        possible values of weight and the corresponding weighting functions are.

        ==========  ===================================   =====================
        ``weight``  Weight function used                  ``wvar``
        ==========  ===================================   =====================
        'cos'       cos(w*x)                              wvar = w
        'sin'       sin(w*x)                              wvar = w
        'alg'       g(x) = ((x-a)**alpha)*((b-x)**beta)   wvar = (alpha, beta)
        'alg-loga'  g(x)*log(x-a)                         wvar = (alpha, beta)
        'alg-logb'  g(x)*log(b-x)                         wvar = (alpha, beta)
        'alg-log'   g(x)*log(x-a)*log(b-x)                wvar = (alpha, beta)
        'cauchy'    1/(x-c)                               wvar = c
        ==========  ===================================   =====================

        wvar holds the parameter w, (alpha, beta), or c depending on the weight
        selected. In these expressions, a and b are the integration limits.

        For the 'cos' and 'sin' weighting, additional inputs and outputs are
        available.

        For finite integration limits, the integration is performed using a
        Clenshaw-Curtis method which uses Chebyshev moments. For repeated
        calculations, these moments are saved in the output dictionary:

        'momcom'
            The maximum level of Chebyshev moments that have been computed,
            i.e., if ``M_c`` is ``infodict['momcom']`` then the moments have been
            computed for intervals of length ``|b-a| * 2**(-l)``,
            ``l=0,1,...,M_c``.
        'nnlog'
            A rank-1 integer array of length M(=limit), containing the
            subdivision levels of the subintervals, i.e., an element of this
            array is equal to l if the corresponding subinterval is
            ``|b-a|* 2**(-l)``.
        'chebmo'
            A rank-2 array of shape (25, maxp1) containing the computed
            Chebyshev moments. These can be passed on to an integration
            over the same interval by passing this array as the second
            element of the sequence wopts and passing infodict['momcom'] as
            the first element.

        If one of the integration limits is infinite, then a Fourier integral is
        computed (assuming w neq 0). If full_output is 1 and a numerical error
        is encountered, besides the error message attached to the output tuple,
        a dictionary is also appended to the output tuple which translates the
        error codes in the array ``info['ierlst']`` to English messages. The
        output information dictionary contains the following entries instead of
        'last', 'alist', 'blist', 'rlist', and 'elist':

        'lst'
            The number of subintervals needed for the integration (call it ``K_f``).
        'rslst'
            A rank-1 array of length M_f=limlst, whose first ``K_f`` elements
            contain the integral contribution over the interval
            ``(a+(k-1)c, a+kc)`` where ``c = (2*floor(|w|) + 1) * pi / |w|``
            and ``k=1,2,...,K_f``.
        'erlst'
            A rank-1 array of length ``M_f`` containing the error estimate
            corresponding to the interval in the same position in
            ``infodict['rslist']``.
        'ierlst'
            A rank-1 integer array of length ``M_f`` containing an error flag
            corresponding to the interval in the same position in
            ``infodict['rslist']``.  See the explanation dictionary (last entry
            in the output tuple) for the meaning of the codes.


        **Details of QUADPACK level routines**

        `quad` calls routines from the FORTRAN library QUADPACK. This section
        provides details on the conditions for each routine to be called and a
        short description of each routine. The routine called depends on
        `weight`, `points` and the integration limits `a` and `b`.

        ================  ==============  ==========  =====================
        QUADPACK routine  `weight`        `points`    infinite bounds
        ================  ==============  ==========  =====================
        qagse             None            No          No
        qagie             None            No          Yes
        qagpe             None            Yes         No
        qawoe             'sin', 'cos'    No          No
        qawfe             'sin', 'cos'    No          either `a` or `b`
        qawse             'alg*'          No          No
        qawce             'cauchy'        No          No
        ================  ==============  ==========  =====================

        The following provides a short description from [1]_ for each
        routine.

        qagse
            is an integrator based on globally adaptive interval
            subdivision in connection with extrapolation, which will
            eliminate the effects of integrand singularities of
            several types.
        qagie
            handles integration over infinite intervals. The infinite range is
            mapped onto a finite interval and subsequently the same strategy as
            in ``QAGS`` is applied.
        qagpe
            serves the same purposes as QAGS, but also allows the
            user to provide explicit information about the location
            and type of trouble-spots i.e. the abscissae of internal
            singularities, discontinuities and other difficulties of
            the integrand function.
        qawoe
            is an integrator for the evaluation of
            :math:`\int^b_a \cos(\omega x)f(x)dx` or
            :math:`\int^b_a \sin(\omega x)f(x)dx`
            over a finite interval [a,b], where :math:`\omega` and :math:`f`
            are specified by the user. The rule evaluation component is based
            on the modified Clenshaw-Curtis technique

            An adaptive subdivision scheme is used in connection
            with an extrapolation procedure, which is a modification
            of that in ``QAGS`` and allows the algorithm to deal with
            singularities in :math:`f(x)`.
        qawfe
            calculates the Fourier transform
            :math:`\int^\infty_a \cos(\omega x)f(x)dx` or
            :math:`\int^\infty_a \sin(\omega x)f(x)dx`
            for user-provided :math:`\omega` and :math:`f`. The procedure of
            ``QAWO`` is applied on successive finite intervals, and convergence
            acceleration by means of the :math:`\varepsilon`-algorithm is applied
            to the series of integral approximations.
        qawse
            approximate :math:`\int^b_a w(x)f(x)dx`, with :math:`a < b` where
            :math:`w(x) = (x-a)^{\alpha}(b-x)^{\beta}v(x)` with
            :math:`\alpha,\beta > -1`, where :math:`v(x)` may be one of the
            following functions: :math:`1`, :math:`\log(x-a)`, :math:`\log(b-x)`,
            :math:`\log(x-a)\log(b-x)`.

            The user specifies :math:`\alpha`, :math:`\beta` and the type of the
            function :math:`v`. A globally adaptive subdivision strategy is
            applied, with modified Clenshaw-Curtis integration on those
            subintervals which contain `a` or `b`.
        qawce
            compute :math:`\int^b_a f(x) / (x-c)dx` where the integral must be
            interpreted as a Cauchy principal value integral, for user specified
            :math:`c` and :math:`f`. The strategy is globally adaptive. Modified
            Clenshaw-Curtis integration is used on those intervals containing the
            point :math:`x = c`.

        **Integration of Complex Function of a Real Variable**

        A complex valued function, :math:`f`, of a real variable can be written as
        :math:`f = g + ih`.  Similarly, the integral of :math:`f` can be
        written as

        .. math::
            \int_a^b f(x) dx = \int_a^b g(x) dx + i\int_a^b h(x) dx

        assuming that the integrals of :math:`g` and :math:`h` exist
        over the interval :math:`[a,b]` [2]_. Therefore, ``quad`` integrates
        complex-valued functions by integrating the real and imaginary components
        separately.


        References
        ----------

        .. [1] Piessens, Robert; de Doncker-Kapenga, Elise;
               Überhuber, Christoph W.; Kahaner, David (1983).
               QUADPACK: A subroutine package for automatic integration.
               Springer-Verlag.
               ISBN 978-3-540-12553-2.

        .. [2] McCullough, Thomas; Phillips, Keith (1973).
               Foundations of Analysis in the Complex Plane.
               Holt Rinehart Winston.
               ISBN 0-03-086370-8

        Examples
        --------
        Calculate :math:`\int^4_0 x^2 dx` and compare with an analytic result

        >>> from scipy import integrate
        >>> import numpy as np
        >>> x2 = lambda x: x**2
        >>> integrate.quad(x2, 0, 4)
        (21.333333333333332, 2.3684757858670003e-13)
        >>> print(4**3 / 3.)  # analytical result
        21.3333333333

        Calculate :math:`\int^\infty_0 e^{-x} dx`

        >>> invexp = lambda x: np.exp(-x)
        >>> integrate.quad(invexp, 0, np.inf)
        (1.0, 5.842605999138044e-11)

        Calculate :math:`\int^1_0 a x \,dx` for :math:`a = 1, 3`

        >>> f = lambda x, a: a*x
        >>> y, err = integrate.quad(f, 0, 1, args=(1,))
        >>> y
        0.5
        >>> y, err = integrate.quad(f, 0, 1, args=(3,))
        >>> y
        1.5

        Calculate :math:`\int^1_0 x^2 + y^2 dx` with ctypes, holding
        y parameter as 1::

            testlib.c =>
                double func(int n, double args[n]){
                    return args[0]*args[0] + args[1]*args[1];}
            compile to library testlib.*

        ::

           from scipy import integrate
           import ctypes
           lib = ctypes.CDLL('/home/.../testlib.*') #use absolute path
           lib.func.restype = ctypes.c_double
           lib.func.argtypes = (ctypes.c_int,ctypes.c_double)
           integrate.quad(lib.func,0,1,(1))
           #(1.3333333333333333, 1.4802973661668752e-14)
           print((1.0**3/3.0 + 1.0) - (0.0**3/3.0 + 0.0)) #Analytic result
           # 1.3333333333333333

        Be aware that pulse shapes and other sharp features as compared to the
        size of the integration interval may not be integrated correctly using
        this method. A simplified example of this limitation is integrating a
        y-axis reflected step function with many zero values within the integrals
        bounds.

        >>> y = lambda x: 1 if x<=0 else 0
        >>> integrate.quad(y, -1, 1)
        (1.0, 1.1102230246251565e-14)
        >>> integrate.quad(y, -1, 100)
        (1.0000000002199108, 1.0189464580163188e-08)
        >>> integrate.quad(y, -1, 10000)
        (0.0, 0.0)

    quad_vec(f, a, b, epsabs=1e-200, epsrel=1e-08, norm='2', cache_size=100000000.0, limit=10000, workers=1, points=None, quadrature=None, full_output=False, *, args=())
        Adaptive integration of a vector-valued function.

        Parameters
        ----------
        f : callable
            Vector-valued function f(x) to integrate.
        a : float
            Initial point.
        b : float
            Final point.
        epsabs : float, optional
            Absolute tolerance.
        epsrel : float, optional
            Relative tolerance.
        norm : {'max', '2'}, optional
            Vector norm to use for error estimation.
        cache_size : int, optional
            Number of bytes to use for memoization.
        limit : float or int, optional
            An upper bound on the number of subintervals used in the adaptive
            algorithm.
        workers : int or map-like callable, optional
            If `workers` is an integer, part of the computation is done in
            parallel subdivided to this many tasks (using
            :class:`python:multiprocessing.pool.Pool`).
            Supply `-1` to use all cores available to the Process.
            Alternatively, supply a map-like callable, such as
            :meth:`python:multiprocessing.pool.Pool.map` for evaluating the
            population in parallel.
            This evaluation is carried out as ``workers(func, iterable)``.
        points : list, optional
            List of additional breakpoints.
        quadrature : {'gk21', 'gk15', 'trapezoid'}, optional
            Quadrature rule to use on subintervals.
            Options: 'gk21' (Gauss-Kronrod 21-point rule),
            'gk15' (Gauss-Kronrod 15-point rule),
            'trapezoid' (composite trapezoid rule).
            Default: 'gk21' for finite intervals and 'gk15' for (semi-)infinite
        full_output : bool, optional
            Return an additional ``info`` dictionary.
        args : tuple, optional
            Extra arguments to pass to function, if any.

            .. versionadded:: 1.8.0

        Returns
        -------
        res : {float, array-like}
            Estimate for the result
        err : float
            Error estimate for the result in the given norm
        info : dict
            Returned only when ``full_output=True``.
            Info dictionary. Is an object with the attributes:

                success : bool
                    Whether integration reached target precision.
                status : int
                    Indicator for convergence, success (0),
                    failure (1), and failure due to rounding error (2).
                neval : int
                    Number of function evaluations.
                intervals : ndarray, shape (num_intervals, 2)
                    Start and end points of subdivision intervals.
                integrals : ndarray, shape (num_intervals, ...)
                    Integral for each interval.
                    Note that at most ``cache_size`` values are recorded,
                    and the array may contains *nan* for missing items.
                errors : ndarray, shape (num_intervals,)
                    Estimated integration error for each interval.

        Notes
        -----
        The algorithm mainly follows the implementation of QUADPACK's
        DQAG* algorithms, implementing global error control and adaptive
        subdivision.

        The algorithm here has some differences to the QUADPACK approach:

        Instead of subdividing one interval at a time, the algorithm
        subdivides N intervals with largest errors at once. This enables
        (partial) parallelization of the integration.

        The logic of subdividing "next largest" intervals first is then
        not implemented, and we rely on the above extension to avoid
        concentrating on "small" intervals only.

        The Wynn epsilon table extrapolation is not used (QUADPACK uses it
        for infinite intervals). This is because the algorithm here is
        supposed to work on vector-valued functions, in an user-specified
        norm, and the extension of the epsilon algorithm to this case does
        not appear to be widely agreed. For max-norm, using elementwise
        Wynn epsilon could be possible, but we do not do this here with
        the hope that the epsilon extrapolation is mainly useful in
        special cases.

        References
        ----------
        [1] R. Piessens, E. de Doncker, QUADPACK (1983).

        Examples
        --------
        We can compute integrations of a vector-valued function:

        >>> from scipy.integrate import quad_vec
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> alpha = np.linspace(0.0, 2.0, num=30)
        >>> f = lambda x: x**alpha
        >>> x0, x1 = 0, 2
        >>> y, err = quad_vec(f, x0, x1)
        >>> plt.plot(alpha, y)
        >>> plt.xlabel(r"$\alpha$")
        >>> plt.ylabel(r"$\int_{0}^{2} x^\alpha dx$")
        >>> plt.show()

    quadrature(func, a, b, args=(), tol=1.49e-08, rtol=1.49e-08, maxiter=50, vec_func=True, miniter=1)
        Compute a definite integral using fixed-tolerance Gaussian quadrature.

        .. deprecated:: 1.12.0

              This function is deprecated as of SciPy 1.12.0 and will be removed
              in SciPy 1.15.0. Please use `scipy.integrate.quad` instead.

        Integrate `func` from `a` to `b` using Gaussian quadrature
        with absolute tolerance `tol`.

        Parameters
        ----------
        func : function
            A Python function or method to integrate.
        a : float
            Lower limit of integration.
        b : float
            Upper limit of integration.
        args : tuple, optional
            Extra arguments to pass to function.
        tol, rtol : float, optional
            Iteration stops when error between last two iterates is less than
            `tol` OR the relative change is less than `rtol`.
        maxiter : int, optional
            Maximum order of Gaussian quadrature.
        vec_func : bool, optional
            True or False if func handles arrays as arguments (is
            a "vector" function). Default is True.
        miniter : int, optional
            Minimum order of Gaussian quadrature.

        Returns
        -------
        val : float
            Gaussian quadrature approximation (within tolerance) to integral.
        err : float
            Difference between last two estimates of the integral.

        See Also
        --------
        fixed_quad : fixed-order Gaussian quadrature
        quad : adaptive quadrature using QUADPACK
        dblquad : double integrals
        tplquad : triple integrals
        romb : integrator for sampled data
        simpson : integrator for sampled data
        cumulative_trapezoid : cumulative integration for sampled data

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> f = lambda x: x**8
        >>> integrate.quadrature(f, 0.0, 1.0)
        (0.11111111111111106, 4.163336342344337e-17)
        >>> print(1/9.0)  # analytical result
        0.1111111111111111

        >>> integrate.quadrature(np.cos, 0.0, np.pi/2)
        (0.9999999999999536, 3.9611425250996035e-11)
        >>> np.sin(np.pi/2)-np.sin(0)  # analytical result
        1.0

    romb(y, dx=1.0, axis=-1, show=False)
        Romberg integration using samples of a function.

        Parameters
        ----------
        y : array_like
            A vector of ``2**k + 1`` equally-spaced samples of a function.
        dx : float, optional
            The sample spacing. Default is 1.
        axis : int, optional
            The axis along which to integrate. Default is -1 (last axis).
        show : bool, optional
            When `y` is a single 1-D array, then if this argument is True
            print the table showing Richardson extrapolation from the
            samples. Default is False.

        Returns
        -------
        romb : ndarray
            The integrated result for `axis`.

        See Also
        --------
        quad : adaptive quadrature using QUADPACK
        fixed_quad : fixed-order Gaussian quadrature
        dblquad : double integrals
        tplquad : triple integrals
        simpson : integrators for sampled data
        cumulative_trapezoid : cumulative integration for sampled data

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> x = np.arange(10, 14.25, 0.25)
        >>> y = np.arange(3, 12)

        >>> integrate.romb(y)
        56.0

        >>> y = np.sin(np.power(x, 2.5))
        >>> integrate.romb(y)
        -0.742561336672229

        >>> integrate.romb(y, show=True)
        Richardson Extrapolation Table for Romberg Integration
        ======================================================
        -0.81576
         4.63862  6.45674
        -1.10581 -3.02062 -3.65245
        -2.57379 -3.06311 -3.06595 -3.05664
        -1.34093 -0.92997 -0.78776 -0.75160 -0.74256
        ======================================================
        -0.742561336672229  # may vary

    romberg(function, a, b, args=(), tol=1.48e-08, rtol=1.48e-08, show=False, divmax=10, vec_func=False)
        Romberg integration of a callable function or method.

        .. deprecated:: 1.12.0

              This function is deprecated as of SciPy 1.12.0 and will be removed
              in SciPy 1.15.0. Please use `scipy.integrate.quad` instead.

        Returns the integral of `function` (a function of one variable)
        over the interval (`a`, `b`).

        If `show` is 1, the triangular array of the intermediate results
        will be printed. If `vec_func` is True (default is False), then
        `function` is assumed to support vector arguments.

        Parameters
        ----------
        function : callable
            Function to be integrated.
        a : float
            Lower limit of integration.
        b : float
            Upper limit of integration.

        Returns
        -------
        results : float
            Result of the integration.

        Other Parameters
        ----------------
        args : tuple, optional
            Extra arguments to pass to function. Each element of `args` will
            be passed as a single argument to `func`. Default is to pass no
            extra arguments.
        tol, rtol : float, optional
            The desired absolute and relative tolerances. Defaults are 1.48e-8.
        show : bool, optional
            Whether to print the results. Default is False.
        divmax : int, optional
            Maximum order of extrapolation. Default is 10.
        vec_func : bool, optional
            Whether `func` handles arrays as arguments (i.e., whether it is a
            "vector" function). Default is False.

        See Also
        --------
        fixed_quad : Fixed-order Gaussian quadrature.
        quad : Adaptive quadrature using QUADPACK.
        dblquad : Double integrals.
        tplquad : Triple integrals.
        romb : Integrators for sampled data.
        simpson : Integrators for sampled data.
        cumulative_trapezoid : Cumulative integration for sampled data.

        References
        ----------
        .. [1] 'Romberg's method' https://en.wikipedia.org/wiki/Romberg%27s_method

        Examples
        --------
        Integrate a gaussian from 0 to 1 and compare to the error function.

        >>> from scipy import integrate
        >>> from scipy.special import erf
        >>> import numpy as np
        >>> gaussian = lambda x: 1/np.sqrt(np.pi) * np.exp(-x**2)
        >>> result = integrate.romberg(gaussian, 0, 1, show=True)
        Romberg integration of <function vfunc at ...> from [0, 1]

        ::

           Steps  StepSize  Results
               1  1.000000  0.385872
               2  0.500000  0.412631  0.421551
               4  0.250000  0.419184  0.421368  0.421356
               8  0.125000  0.420810  0.421352  0.421350  0.421350
              16  0.062500  0.421215  0.421350  0.421350  0.421350  0.421350
              32  0.031250  0.421317  0.421350  0.421350  0.421350  0.421350  0.421350

        The final result is 0.421350396475 after 33 function evaluations.

        >>> print("%g %g" % (2*result, erf(1)))
        0.842701 0.842701

    simpson(y, *, x=None, dx=1.0, axis=-1)
        Integrate y(x) using samples along the given axis and the composite
        Simpson's rule. If x is None, spacing of dx is assumed.

        If there are an even number of samples, N, then there are an odd
        number of intervals (N-1), but Simpson's rule requires an even number
        of intervals. The parameter 'even' controls how this is handled.

        Parameters
        ----------
        y : array_like
            Array to be integrated.
        x : array_like, optional
            If given, the points at which `y` is sampled.
        dx : float, optional
            Spacing of integration points along axis of `x`. Only used when
            `x` is None. Default is 1.
        axis : int, optional
            Axis along which to integrate. Default is the last axis.

        Returns
        -------
        float
            The estimated integral computed with the composite Simpson's rule.

        See Also
        --------
        quad : adaptive quadrature using QUADPACK
        fixed_quad : fixed-order Gaussian quadrature
        dblquad : double integrals
        tplquad : triple integrals
        romb : integrators for sampled data
        cumulative_trapezoid : cumulative integration for sampled data
        cumulative_simpson : cumulative integration using Simpson's 1/3 rule

        Notes
        -----
        For an odd number of samples that are equally spaced the result is
        exact if the function is a polynomial of order 3 or less. If
        the samples are not equally spaced, then the result is exact only
        if the function is a polynomial of order 2 or less.

        References
        ----------
        .. [1] Cartwright, Kenneth V. Simpson's Rule Cumulative Integration with
               MS Excel and Irregularly-spaced Data. Journal of Mathematical
               Sciences and Mathematics Education. 12 (2): 1-9

        Examples
        --------
        >>> from scipy import integrate
        >>> import numpy as np
        >>> x = np.arange(0, 10)
        >>> y = np.arange(0, 10)

        >>> integrate.simpson(y, x=x)
        40.5

        >>> y = np.power(x, 3)
        >>> integrate.simpson(y, x=x)
        1640.5
        >>> integrate.quad(lambda x: x**3, 0, 9)[0]
        1640.25

    solve_bvp(fun, bc, x, y, p=None, S=None, fun_jac=None, bc_jac=None, tol=0.001, max_nodes=1000, verbose=0, bc_tol=None)
        Solve a boundary value problem for a system of ODEs.

        This function numerically solves a first order system of ODEs subject to
        two-point boundary conditions::

            dy / dx = f(x, y, p) + S * y / (x - a), a <= x <= b
            bc(y(a), y(b), p) = 0

        Here x is a 1-D independent variable, y(x) is an N-D
        vector-valued function and p is a k-D vector of unknown
        parameters which is to be found along with y(x). For the problem to be
        determined, there must be n + k boundary conditions, i.e., bc must be an
        (n + k)-D function.

        The last singular term on the right-hand side of the system is optional.
        It is defined by an n-by-n matrix S, such that the solution must satisfy
        S y(a) = 0. This condition will be forced during iterations, so it must not
        contradict boundary conditions. See [2]_ for the explanation how this term
        is handled when solving BVPs numerically.

        Problems in a complex domain can be solved as well. In this case, y and p
        are considered to be complex, and f and bc are assumed to be complex-valued
        functions, but x stays real. Note that f and bc must be complex
        differentiable (satisfy Cauchy-Riemann equations [4]_), otherwise you
        should rewrite your problem for real and imaginary parts separately. To
        solve a problem in a complex domain, pass an initial guess for y with a
        complex data type (see below).

        Parameters
        ----------
        fun : callable
            Right-hand side of the system. The calling signature is ``fun(x, y)``,
            or ``fun(x, y, p)`` if parameters are present. All arguments are
            ndarray: ``x`` with shape (m,), ``y`` with shape (n, m), meaning that
            ``y[:, i]`` corresponds to ``x[i]``, and ``p`` with shape (k,). The
            return value must be an array with shape (n, m) and with the same
            layout as ``y``.
        bc : callable
            Function evaluating residuals of the boundary conditions. The calling
            signature is ``bc(ya, yb)``, or ``bc(ya, yb, p)`` if parameters are
            present. All arguments are ndarray: ``ya`` and ``yb`` with shape (n,),
            and ``p`` with shape (k,). The return value must be an array with
            shape (n + k,).
        x : array_like, shape (m,)
            Initial mesh. Must be a strictly increasing sequence of real numbers
            with ``x[0]=a`` and ``x[-1]=b``.
        y : array_like, shape (n, m)
            Initial guess for the function values at the mesh nodes, ith column
            corresponds to ``x[i]``. For problems in a complex domain pass `y`
            with a complex data type (even if the initial guess is purely real).
        p : array_like with shape (k,) or None, optional
            Initial guess for the unknown parameters. If None (default), it is
            assumed that the problem doesn't depend on any parameters.
        S : array_like with shape (n, n) or None
            Matrix defining the singular term. If None (default), the problem is
            solved without the singular term.
        fun_jac : callable or None, optional
            Function computing derivatives of f with respect to y and p. The
            calling signature is ``fun_jac(x, y)``, or ``fun_jac(x, y, p)`` if
            parameters are present. The return must contain 1 or 2 elements in the
            following order:

                * df_dy : array_like with shape (n, n, m), where an element
                  (i, j, q) equals to d f_i(x_q, y_q, p) / d (y_q)_j.
                * df_dp : array_like with shape (n, k, m), where an element
                  (i, j, q) equals to d f_i(x_q, y_q, p) / d p_j.

            Here q numbers nodes at which x and y are defined, whereas i and j
            number vector components. If the problem is solved without unknown
            parameters, df_dp should not be returned.

            If `fun_jac` is None (default), the derivatives will be estimated
            by the forward finite differences.
        bc_jac : callable or None, optional
            Function computing derivatives of bc with respect to ya, yb, and p.
            The calling signature is ``bc_jac(ya, yb)``, or ``bc_jac(ya, yb, p)``
            if parameters are present. The return must contain 2 or 3 elements in
            the following order:

                * dbc_dya : array_like with shape (n, n), where an element (i, j)
                  equals to d bc_i(ya, yb, p) / d ya_j.
                * dbc_dyb : array_like with shape (n, n), where an element (i, j)
                  equals to d bc_i(ya, yb, p) / d yb_j.
                * dbc_dp : array_like with shape (n, k), where an element (i, j)
                  equals to d bc_i(ya, yb, p) / d p_j.

            If the problem is solved without unknown parameters, dbc_dp should not
            be returned.

            If `bc_jac` is None (default), the derivatives will be estimated by
            the forward finite differences.
        tol : float, optional
            Desired tolerance of the solution. If we define ``r = y' - f(x, y)``,
            where y is the found solution, then the solver tries to achieve on each
            mesh interval ``norm(r / (1 + abs(f)) < tol``, where ``norm`` is
            estimated in a root mean squared sense (using a numerical quadrature
            formula). Default is 1e-3.
        max_nodes : int, optional
            Maximum allowed number of the mesh nodes. If exceeded, the algorithm
            terminates. Default is 1000.
        verbose : {0, 1, 2}, optional
            Level of algorithm's verbosity:

                * 0 (default) : work silently.
                * 1 : display a termination report.
                * 2 : display progress during iterations.
        bc_tol : float, optional
            Desired absolute tolerance for the boundary condition residuals: `bc`
            value should satisfy ``abs(bc) < bc_tol`` component-wise.
            Equals to `tol` by default. Up to 10 iterations are allowed to achieve this
            tolerance.

        Returns
        -------
        Bunch object with the following fields defined:
        sol : PPoly
            Found solution for y as `scipy.interpolate.PPoly` instance, a C1
            continuous cubic spline.
        p : ndarray or None, shape (k,)
            Found parameters. None, if the parameters were not present in the
            problem.
        x : ndarray, shape (m,)
            Nodes of the final mesh.
        y : ndarray, shape (n, m)
            Solution values at the mesh nodes.
        yp : ndarray, shape (n, m)
            Solution derivatives at the mesh nodes.
        rms_residuals : ndarray, shape (m - 1,)
            RMS values of the relative residuals over each mesh interval (see the
            description of `tol` parameter).
        niter : int
            Number of completed iterations.
        status : int
            Reason for algorithm termination:

                * 0: The algorithm converged to the desired accuracy.
                * 1: The maximum number of mesh nodes is exceeded.
                * 2: A singular Jacobian encountered when solving the collocation
                  system.

        message : string
            Verbal description of the termination reason.
        success : bool
            True if the algorithm converged to the desired accuracy (``status=0``).

        Notes
        -----
        This function implements a 4th order collocation algorithm with the
        control of residuals similar to [1]_. A collocation system is solved
        by a damped Newton method with an affine-invariant criterion function as
        described in [3]_.

        Note that in [1]_  integral residuals are defined without normalization
        by interval lengths. So, their definition is different by a multiplier of
        h**0.5 (h is an interval length) from the definition used here.

        .. versionadded:: 0.18.0

        References
        ----------
        .. [1] J. Kierzenka, L. F. Shampine, "A BVP Solver Based on Residual
               Control and the Maltab PSE", ACM Trans. Math. Softw., Vol. 27,
               Number 3, pp. 299-316, 2001.
        .. [2] L.F. Shampine, P. H. Muir and H. Xu, "A User-Friendly Fortran BVP
               Solver".
        .. [3] U. Ascher, R. Mattheij and R. Russell "Numerical Solution of
               Boundary Value Problems for Ordinary Differential Equations".
        .. [4] `Cauchy-Riemann equations
                <https://en.wikipedia.org/wiki/Cauchy-Riemann_equations>`_ on
                Wikipedia.

        Examples
        --------
        In the first example, we solve Bratu's problem::

            y'' + k * exp(y) = 0
            y(0) = y(1) = 0

        for k = 1.

        We rewrite the equation as a first-order system and implement its
        right-hand side evaluation::

            y1' = y2
            y2' = -exp(y1)

        >>> import numpy as np
        >>> def fun(x, y):
        ...     return np.vstack((y[1], -np.exp(y[0])))

        Implement evaluation of the boundary condition residuals:

        >>> def bc(ya, yb):
        ...     return np.array([ya[0], yb[0]])

        Define the initial mesh with 5 nodes:

        >>> x = np.linspace(0, 1, 5)

        This problem is known to have two solutions. To obtain both of them, we
        use two different initial guesses for y. We denote them by subscripts
        a and b.

        >>> y_a = np.zeros((2, x.size))
        >>> y_b = np.zeros((2, x.size))
        >>> y_b[0] = 3

        Now we are ready to run the solver.

        >>> from scipy.integrate import solve_bvp
        >>> res_a = solve_bvp(fun, bc, x, y_a)
        >>> res_b = solve_bvp(fun, bc, x, y_b)

        Let's plot the two found solutions. We take an advantage of having the
        solution in a spline form to produce a smooth plot.

        >>> x_plot = np.linspace(0, 1, 100)
        >>> y_plot_a = res_a.sol(x_plot)[0]
        >>> y_plot_b = res_b.sol(x_plot)[0]
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(x_plot, y_plot_a, label='y_a')
        >>> plt.plot(x_plot, y_plot_b, label='y_b')
        >>> plt.legend()
        >>> plt.xlabel("x")
        >>> plt.ylabel("y")
        >>> plt.show()

        We see that the two solutions have similar shape, but differ in scale
        significantly.

        In the second example, we solve a simple Sturm-Liouville problem::

            y'' + k**2 * y = 0
            y(0) = y(1) = 0

        It is known that a non-trivial solution y = A * sin(k * x) is possible for
        k = pi * n, where n is an integer. To establish the normalization constant
        A = 1 we add a boundary condition::

            y'(0) = k

        Again, we rewrite our equation as a first-order system and implement its
        right-hand side evaluation::

            y1' = y2
            y2' = -k**2 * y1

        >>> def fun(x, y, p):
        ...     k = p[0]
        ...     return np.vstack((y[1], -k**2 * y[0]))

        Note that parameters p are passed as a vector (with one element in our
        case).

        Implement the boundary conditions:

        >>> def bc(ya, yb, p):
        ...     k = p[0]
        ...     return np.array([ya[0], yb[0], ya[1] - k])

        Set up the initial mesh and guess for y. We aim to find the solution for
        k = 2 * pi, to achieve that we set values of y to approximately follow
        sin(2 * pi * x):

        >>> x = np.linspace(0, 1, 5)
        >>> y = np.zeros((2, x.size))
        >>> y[0, 1] = 1
        >>> y[0, 3] = -1

        Run the solver with 6 as an initial guess for k.

        >>> sol = solve_bvp(fun, bc, x, y, p=[6])

        We see that the found k is approximately correct:

        >>> sol.p[0]
        6.28329460046

        And, finally, plot the solution to see the anticipated sinusoid:

        >>> x_plot = np.linspace(0, 1, 100)
        >>> y_plot = sol.sol(x_plot)[0]
        >>> plt.plot(x_plot, y_plot)
        >>> plt.xlabel("x")
        >>> plt.ylabel("y")
        >>> plt.show()

    solve_ivp(fun, t_span, y0, method='RK45', t_eval=None, dense_output=False, events=None, vectorized=False, args=None, **options)
        Solve an initial value problem for a system of ODEs.

        This function numerically integrates a system of ordinary differential
        equations given an initial value::

            dy / dt = f(t, y)
            y(t0) = y0

        Here t is a 1-D independent variable (time), y(t) is an
        N-D vector-valued function (state), and an N-D
        vector-valued function f(t, y) determines the differential equations.
        The goal is to find y(t) approximately satisfying the differential
        equations, given an initial value y(t0)=y0.

        Some of the solvers support integration in the complex domain, but note
        that for stiff ODE solvers, the right-hand side must be
        complex-differentiable (satisfy Cauchy-Riemann equations [11]_).
        To solve a problem in the complex domain, pass y0 with a complex data type.
        Another option always available is to rewrite your problem for real and
        imaginary parts separately.

        Parameters
        ----------
        fun : callable
            Right-hand side of the system: the time derivative of the state ``y``
            at time ``t``. The calling signature is ``fun(t, y)``, where ``t`` is a
            scalar and ``y`` is an ndarray with ``len(y) = len(y0)``. Additional
            arguments need to be passed if ``args`` is used (see documentation of
            ``args`` argument). ``fun`` must return an array of the same shape as
            ``y``. See `vectorized` for more information.
        t_span : 2-member sequence
            Interval of integration (t0, tf). The solver starts with t=t0 and
            integrates until it reaches t=tf. Both t0 and tf must be floats
            or values interpretable by the float conversion function.
        y0 : array_like, shape (n,)
            Initial state. For problems in the complex domain, pass `y0` with a
            complex data type (even if the initial value is purely real).
        method : string or `OdeSolver`, optional
            Integration method to use:

                * 'RK45' (default): Explicit Runge-Kutta method of order 5(4) [1]_.
                  The error is controlled assuming accuracy of the fourth-order
                  method, but steps are taken using the fifth-order accurate
                  formula (local extrapolation is done). A quartic interpolation
                  polynomial is used for the dense output [2]_. Can be applied in
                  the complex domain.
                * 'RK23': Explicit Runge-Kutta method of order 3(2) [3]_. The error
                  is controlled assuming accuracy of the second-order method, but
                  steps are taken using the third-order accurate formula (local
                  extrapolation is done). A cubic Hermite polynomial is used for the
                  dense output. Can be applied in the complex domain.
                * 'DOP853': Explicit Runge-Kutta method of order 8 [13]_.
                  Python implementation of the "DOP853" algorithm originally
                  written in Fortran [14]_. A 7-th order interpolation polynomial
                  accurate to 7-th order is used for the dense output.
                  Can be applied in the complex domain.
                * 'Radau': Implicit Runge-Kutta method of the Radau IIA family of
                  order 5 [4]_. The error is controlled with a third-order accurate
                  embedded formula. A cubic polynomial which satisfies the
                  collocation conditions is used for the dense output.
                * 'BDF': Implicit multi-step variable-order (1 to 5) method based
                  on a backward differentiation formula for the derivative
                  approximation [5]_. The implementation follows the one described
                  in [6]_. A quasi-constant step scheme is used and accuracy is
                  enhanced using the NDF modification. Can be applied in the
                  complex domain.
                * 'LSODA': Adams/BDF method with automatic stiffness detection and
                  switching [7]_, [8]_. This is a wrapper of the Fortran solver
                  from ODEPACK.

            Explicit Runge-Kutta methods ('RK23', 'RK45', 'DOP853') should be used
            for non-stiff problems and implicit methods ('Radau', 'BDF') for
            stiff problems [9]_. Among Runge-Kutta methods, 'DOP853' is recommended
            for solving with high precision (low values of `rtol` and `atol`).

            If not sure, first try to run 'RK45'. If it makes unusually many
            iterations, diverges, or fails, your problem is likely to be stiff and
            you should use 'Radau' or 'BDF'. 'LSODA' can also be a good universal
            choice, but it might be somewhat less convenient to work with as it
            wraps old Fortran code.

            You can also pass an arbitrary class derived from `OdeSolver` which
            implements the solver.
        t_eval : array_like or None, optional
            Times at which to store the computed solution, must be sorted and lie
            within `t_span`. If None (default), use points selected by the solver.
        dense_output : bool, optional
            Whether to compute a continuous solution. Default is False.
        events : callable, or list of callables, optional
            Events to track. If None (default), no events will be tracked.
            Each event occurs at the zeros of a continuous function of time and
            state. Each function must have the signature ``event(t, y)`` where
            additional argument have to be passed if ``args`` is used (see
            documentation of ``args`` argument). Each function must return a
            float. The solver will find an accurate value of `t` at which
            ``event(t, y(t)) = 0`` using a root-finding algorithm. By default,
            all zeros will be found. The solver looks for a sign change over
            each step, so if multiple zero crossings occur within one step,
            events may be missed. Additionally each `event` function might
            have the following attributes:

                terminal: bool or int, optional
                    When boolean, whether to terminate integration if this event occurs.
                    When integral, termination occurs after the specified the number of
                    occurences of this event.
                    Implicitly False if not assigned.
                direction: float, optional
                    Direction of a zero crossing. If `direction` is positive,
                    `event` will only trigger when going from negative to positive,
                    and vice versa if `direction` is negative. If 0, then either
                    direction will trigger event. Implicitly 0 if not assigned.

            You can assign attributes like ``event.terminal = True`` to any
            function in Python.
        vectorized : bool, optional
            Whether `fun` can be called in a vectorized fashion. Default is False.

            If ``vectorized`` is False, `fun` will always be called with ``y`` of
            shape ``(n,)``, where ``n = len(y0)``.

            If ``vectorized`` is True, `fun` may be called with ``y`` of shape
            ``(n, k)``, where ``k`` is an integer. In this case, `fun` must behave
            such that ``fun(t, y)[:, i] == fun(t, y[:, i])`` (i.e. each column of
            the returned array is the time derivative of the state corresponding
            with a column of ``y``).

            Setting ``vectorized=True`` allows for faster finite difference
            approximation of the Jacobian by methods 'Radau' and 'BDF', but
            will result in slower execution for other methods and for 'Radau' and
            'BDF' in some circumstances (e.g. small ``len(y0)``).
        args : tuple, optional
            Additional arguments to pass to the user-defined functions.  If given,
            the additional arguments are passed to all user-defined functions.
            So if, for example, `fun` has the signature ``fun(t, y, a, b, c)``,
            then `jac` (if given) and any event functions must have the same
            signature, and `args` must be a tuple of length 3.
        **options
            Options passed to a chosen solver. All options available for already
            implemented solvers are listed below.
        first_step : float or None, optional
            Initial step size. Default is `None` which means that the algorithm
            should choose.
        max_step : float, optional
            Maximum allowed step size. Default is np.inf, i.e., the step size is not
            bounded and determined solely by the solver.
        rtol, atol : float or array_like, optional
            Relative and absolute tolerances. The solver keeps the local error
            estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
            relative accuracy (number of correct digits), while `atol` controls
            absolute accuracy (number of correct decimal places). To achieve the
            desired `rtol`, set `atol` to be smaller than the smallest value that
            can be expected from ``rtol * abs(y)`` so that `rtol` dominates the
            allowable error. If `atol` is larger than ``rtol * abs(y)`` the
            number of correct digits is not guaranteed. Conversely, to achieve the
            desired `atol` set `rtol` such that ``rtol * abs(y)`` is always smaller
            than `atol`. If components of y have different scales, it might be
            beneficial to set different `atol` values for different components by
            passing array_like with shape (n,) for `atol`. Default values are
            1e-3 for `rtol` and 1e-6 for `atol`.
        jac : array_like, sparse_matrix, callable or None, optional
            Jacobian matrix of the right-hand side of the system with respect
            to y, required by the 'Radau', 'BDF' and 'LSODA' method. The
            Jacobian matrix has shape (n, n) and its element (i, j) is equal to
            ``d f_i / d y_j``.  There are three ways to define the Jacobian:

                * If array_like or sparse_matrix, the Jacobian is assumed to
                  be constant. Not supported by 'LSODA'.
                * If callable, the Jacobian is assumed to depend on both
                  t and y; it will be called as ``jac(t, y)``, as necessary.
                  Additional arguments have to be passed if ``args`` is
                  used (see documentation of ``args`` argument).
                  For 'Radau' and 'BDF' methods, the return value might be a
                  sparse matrix.
                * If None (default), the Jacobian will be approximated by
                  finite differences.

            It is generally recommended to provide the Jacobian rather than
            relying on a finite-difference approximation.
        jac_sparsity : array_like, sparse matrix or None, optional
            Defines a sparsity structure of the Jacobian matrix for a finite-
            difference approximation. Its shape must be (n, n). This argument
            is ignored if `jac` is not `None`. If the Jacobian has only few
            non-zero elements in *each* row, providing the sparsity structure
            will greatly speed up the computations [10]_. A zero entry means that
            a corresponding element in the Jacobian is always zero. If None
            (default), the Jacobian is assumed to be dense.
            Not supported by 'LSODA', see `lband` and `uband` instead.
        lband, uband : int or None, optional
            Parameters defining the bandwidth of the Jacobian for the 'LSODA'
            method, i.e., ``jac[i, j] != 0 only for i - lband <= j <= i + uband``.
            Default is None. Setting these requires your jac routine to return the
            Jacobian in the packed format: the returned array must have ``n``
            columns and ``uband + lband + 1`` rows in which Jacobian diagonals are
            written. Specifically ``jac_packed[uband + i - j , j] = jac[i, j]``.
            The same format is used in `scipy.linalg.solve_banded` (check for an
            illustration).  These parameters can be also used with ``jac=None`` to
            reduce the number of Jacobian elements estimated by finite differences.
        min_step : float, optional
            The minimum allowed step size for 'LSODA' method.
            By default `min_step` is zero.

        Returns
        -------
        Bunch object with the following fields defined:
        t : ndarray, shape (n_points,)
            Time points.
        y : ndarray, shape (n, n_points)
            Values of the solution at `t`.
        sol : `OdeSolution` or None
            Found solution as `OdeSolution` instance; None if `dense_output` was
            set to False.
        t_events : list of ndarray or None
            Contains for each event type a list of arrays at which an event of
            that type event was detected. None if `events` was None.
        y_events : list of ndarray or None
            For each value of `t_events`, the corresponding value of the solution.
            None if `events` was None.
        nfev : int
            Number of evaluations of the right-hand side.
        njev : int
            Number of evaluations of the Jacobian.
        nlu : int
            Number of LU decompositions.
        status : int
            Reason for algorithm termination:

                * -1: Integration step failed.
                *  0: The solver successfully reached the end of `tspan`.
                *  1: A termination event occurred.

        message : string
            Human-readable description of the termination reason.
        success : bool
            True if the solver reached the interval end or a termination event
            occurred (``status >= 0``).

        References
        ----------
        .. [1] J. R. Dormand, P. J. Prince, "A family of embedded Runge-Kutta
               formulae", Journal of Computational and Applied Mathematics, Vol. 6,
               No. 1, pp. 19-26, 1980.
        .. [2] L. W. Shampine, "Some Practical Runge-Kutta Formulas", Mathematics
               of Computation,, Vol. 46, No. 173, pp. 135-150, 1986.
        .. [3] P. Bogacki, L.F. Shampine, "A 3(2) Pair of Runge-Kutta Formulas",
               Appl. Math. Lett. Vol. 2, No. 4. pp. 321-325, 1989.
        .. [4] E. Hairer, G. Wanner, "Solving Ordinary Differential Equations II:
               Stiff and Differential-Algebraic Problems", Sec. IV.8.
        .. [5] `Backward Differentiation Formula
                <https://en.wikipedia.org/wiki/Backward_differentiation_formula>`_
                on Wikipedia.
        .. [6] L. F. Shampine, M. W. Reichelt, "THE MATLAB ODE SUITE", SIAM J. SCI.
               COMPUTE., Vol. 18, No. 1, pp. 1-22, January 1997.
        .. [7] A. C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE
               Solvers," IMACS Transactions on Scientific Computation, Vol 1.,
               pp. 55-64, 1983.
        .. [8] L. Petzold, "Automatic selection of methods for solving stiff and
               nonstiff systems of ordinary differential equations", SIAM Journal
               on Scientific and Statistical Computing, Vol. 4, No. 1, pp. 136-148,
               1983.
        .. [9] `Stiff equation <https://en.wikipedia.org/wiki/Stiff_equation>`_ on
               Wikipedia.
        .. [10] A. Curtis, M. J. D. Powell, and J. Reid, "On the estimation of
                sparse Jacobian matrices", Journal of the Institute of Mathematics
                and its Applications, 13, pp. 117-120, 1974.
        .. [11] `Cauchy-Riemann equations
                 <https://en.wikipedia.org/wiki/Cauchy-Riemann_equations>`_ on
                 Wikipedia.
        .. [12] `Lotka-Volterra equations
                <https://en.wikipedia.org/wiki/Lotka%E2%80%93Volterra_equations>`_
                on Wikipedia.
        .. [13] E. Hairer, S. P. Norsett G. Wanner, "Solving Ordinary Differential
                Equations I: Nonstiff Problems", Sec. II.
        .. [14] `Page with original Fortran code of DOP853
                <http://www.unige.ch/~hairer/software.html>`_.

        Examples
        --------
        Basic exponential decay showing automatically chosen time points.

        >>> import numpy as np
        >>> from scipy.integrate import solve_ivp
        >>> def exponential_decay(t, y): return -0.5 * y
        >>> sol = solve_ivp(exponential_decay, [0, 10], [2, 4, 8])
        >>> print(sol.t)
        [ 0.          0.11487653  1.26364188  3.06061781  4.81611105  6.57445806
          8.33328988 10.        ]
        >>> print(sol.y)
        [[2.         1.88836035 1.06327177 0.43319312 0.18017253 0.07483045
          0.03107158 0.01350781]
         [4.         3.7767207  2.12654355 0.86638624 0.36034507 0.14966091
          0.06214316 0.02701561]
         [8.         7.5534414  4.25308709 1.73277247 0.72069014 0.29932181
          0.12428631 0.05403123]]

        Specifying points where the solution is desired.

        >>> sol = solve_ivp(exponential_decay, [0, 10], [2, 4, 8],
        ...                 t_eval=[0, 1, 2, 4, 10])
        >>> print(sol.t)
        [ 0  1  2  4 10]
        >>> print(sol.y)
        [[2.         1.21305369 0.73534021 0.27066736 0.01350938]
         [4.         2.42610739 1.47068043 0.54133472 0.02701876]
         [8.         4.85221478 2.94136085 1.08266944 0.05403753]]

        Cannon fired upward with terminal event upon impact. The ``terminal`` and
        ``direction`` fields of an event are applied by monkey patching a function.
        Here ``y[0]`` is position and ``y[1]`` is velocity. The projectile starts
        at position 0 with velocity +10. Note that the integration never reaches
        t=100 because the event is terminal.

        >>> def upward_cannon(t, y): return [y[1], -0.5]
        >>> def hit_ground(t, y): return y[0]
        >>> hit_ground.terminal = True
        >>> hit_ground.direction = -1
        >>> sol = solve_ivp(upward_cannon, [0, 100], [0, 10], events=hit_ground)
        >>> print(sol.t_events)
        [array([40.])]
        >>> print(sol.t)
        [0.00000000e+00 9.99900010e-05 1.09989001e-03 1.10988901e-02
         1.11088891e-01 1.11098890e+00 1.11099890e+01 4.00000000e+01]

        Use `dense_output` and `events` to find position, which is 100, at the apex
        of the cannonball's trajectory. Apex is not defined as terminal, so both
        apex and hit_ground are found. There is no information at t=20, so the sol
        attribute is used to evaluate the solution. The sol attribute is returned
        by setting ``dense_output=True``. Alternatively, the `y_events` attribute
        can be used to access the solution at the time of the event.

        >>> def apex(t, y): return y[1]
        >>> sol = solve_ivp(upward_cannon, [0, 100], [0, 10],
        ...                 events=(hit_ground, apex), dense_output=True)
        >>> print(sol.t_events)
        [array([40.]), array([20.])]
        >>> print(sol.t)
        [0.00000000e+00 9.99900010e-05 1.09989001e-03 1.10988901e-02
         1.11088891e-01 1.11098890e+00 1.11099890e+01 4.00000000e+01]
        >>> print(sol.sol(sol.t_events[1][0]))
        [100.   0.]
        >>> print(sol.y_events)
        [array([[-5.68434189e-14, -1.00000000e+01]]),
         array([[1.00000000e+02, 1.77635684e-15]])]

        As an example of a system with additional parameters, we'll implement
        the Lotka-Volterra equations [12]_.

        >>> def lotkavolterra(t, z, a, b, c, d):
        ...     x, y = z
        ...     return [a*x - b*x*y, -c*y + d*x*y]
        ...

        We pass in the parameter values a=1.5, b=1, c=3 and d=1 with the `args`
        argument.

        >>> sol = solve_ivp(lotkavolterra, [0, 15], [10, 5], args=(1.5, 1, 3, 1),
        ...                 dense_output=True)

        Compute a dense solution and plot it.

        >>> t = np.linspace(0, 15, 300)
        >>> z = sol.sol(t)
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(t, z.T)
        >>> plt.xlabel('t')
        >>> plt.legend(['x', 'y'], shadow=True)
        >>> plt.title('Lotka-Volterra System')
        >>> plt.show()

        A couple examples of using solve_ivp to solve the differential
        equation ``y' = Ay`` with complex matrix ``A``.

        >>> A = np.array([[-0.25 + 0.14j, 0, 0.33 + 0.44j],
        ...               [0.25 + 0.58j, -0.2 + 0.14j, 0],
        ...               [0, 0.2 + 0.4j, -0.1 + 0.97j]])

        Solving an IVP with ``A`` from above and ``y`` as 3x1 vector:

        >>> def deriv_vec(t, y):
        ...     return A @ y
        >>> result = solve_ivp(deriv_vec, [0, 25],
        ...                    np.array([10 + 0j, 20 + 0j, 30 + 0j]),
        ...                    t_eval=np.linspace(0, 25, 101))
        >>> print(result.y[:, 0])
        [10.+0.j 20.+0.j 30.+0.j]
        >>> print(result.y[:, -1])
        [18.46291039+45.25653651j 10.01569306+36.23293216j
         -4.98662741+80.07360388j]

        Solving an IVP with ``A`` from above with ``y`` as 3x3 matrix :

        >>> def deriv_mat(t, y):
        ...     return (A @ y.reshape(3, 3)).flatten()
        >>> y0 = np.array([[2 + 0j, 3 + 0j, 4 + 0j],
        ...                [5 + 0j, 6 + 0j, 7 + 0j],
        ...                [9 + 0j, 34 + 0j, 78 + 0j]])

        >>> result = solve_ivp(deriv_mat, [0, 25], y0.flatten(),
        ...                    t_eval=np.linspace(0, 25, 101))
        >>> print(result.y[:, 0].reshape(3, 3))
        [[ 2.+0.j  3.+0.j  4.+0.j]
         [ 5.+0.j  6.+0.j  7.+0.j]
         [ 9.+0.j 34.+0.j 78.+0.j]]
        >>> print(result.y[:, -1].reshape(3, 3))
        [[  5.67451179 +12.07938445j  17.2888073  +31.03278837j
            37.83405768 +63.25138759j]
         [  3.39949503 +11.82123994j  21.32530996 +44.88668871j
            53.17531184+103.80400411j]
         [ -2.26105874 +22.19277664j -15.1255713  +70.19616341j
           -38.34616845+153.29039931j]]

    tplquad(func, a, b, gfun, hfun, qfun, rfun, args=(), epsabs=1.49e-08, epsrel=1.49e-08)
        Compute a triple (definite) integral.

        Return the triple integral of ``func(z, y, x)`` from ``x = a..b``,
        ``y = gfun(x)..hfun(x)``, and ``z = qfun(x,y)..rfun(x,y)``.

        Parameters
        ----------
        func : function
            A Python function or method of at least three variables in the
            order (z, y, x).
        a, b : float
            The limits of integration in x: `a` < `b`
        gfun : function or float
            The lower boundary curve in y which is a function taking a single
            floating point argument (x) and returning a floating point result
            or a float indicating a constant boundary curve.
        hfun : function or float
            The upper boundary curve in y (same requirements as `gfun`).
        qfun : function or float
            The lower boundary surface in z.  It must be a function that takes
            two floats in the order (x, y) and returns a float or a float
            indicating a constant boundary surface.
        rfun : function or float
            The upper boundary surface in z. (Same requirements as `qfun`.)
        args : tuple, optional
            Extra arguments to pass to `func`.
        epsabs : float, optional
            Absolute tolerance passed directly to the innermost 1-D quadrature
            integration. Default is 1.49e-8.
        epsrel : float, optional
            Relative tolerance of the innermost 1-D integrals. Default is 1.49e-8.

        Returns
        -------
        y : float
            The resultant integral.
        abserr : float
            An estimate of the error.

        See Also
        --------
        quad : Adaptive quadrature using QUADPACK
        fixed_quad : Fixed-order Gaussian quadrature
        dblquad : Double integrals
        nquad : N-dimensional integrals
        romb : Integrators for sampled data
        simpson : Integrators for sampled data
        scipy.special : For coefficients and roots of orthogonal polynomials

        Notes
        -----
        For valid results, the integral must converge; behavior for divergent
        integrals is not guaranteed.

        **Details of QUADPACK level routines**

        `quad` calls routines from the FORTRAN library QUADPACK. This section
        provides details on the conditions for each routine to be called and a
        short description of each routine. For each level of integration, ``qagse``
        is used for finite limits or ``qagie`` is used, if either limit (or both!)
        are infinite. The following provides a short description from [1]_ for each
        routine.

        qagse
            is an integrator based on globally adaptive interval
            subdivision in connection with extrapolation, which will
            eliminate the effects of integrand singularities of
            several types.
        qagie
            handles integration over infinite intervals. The infinite range is
            mapped onto a finite interval and subsequently the same strategy as
            in ``QAGS`` is applied.

        References
        ----------

        .. [1] Piessens, Robert; de Doncker-Kapenga, Elise;
               Überhuber, Christoph W.; Kahaner, David (1983).
               QUADPACK: A subroutine package for automatic integration.
               Springer-Verlag.
               ISBN 978-3-540-12553-2.

        Examples
        --------
        Compute the triple integral of ``x * y * z``, over ``x`` ranging
        from 1 to 2, ``y`` ranging from 2 to 3, ``z`` ranging from 0 to 1.
        That is, :math:`\int^{x=2}_{x=1} \int^{y=3}_{y=2} \int^{z=1}_{z=0} x y z
        \,dz \,dy \,dx`.

        >>> import numpy as np
        >>> from scipy import integrate
        >>> f = lambda z, y, x: x*y*z
        >>> integrate.tplquad(f, 1, 2, 2, 3, 0, 1)
        (1.8749999999999998, 3.3246447942574074e-14)

        Calculate :math:`\int^{x=1}_{x=0} \int^{y=1-2x}_{y=0}
        \int^{z=1-x-2y}_{z=0} x y z \,dz \,dy \,dx`.
        Note: `qfun`/`rfun` takes arguments in the order (x, y), even though ``f``
        takes arguments in the order (z, y, x).

        >>> f = lambda z, y, x: x*y*z
        >>> integrate.tplquad(f, 0, 1, 0, lambda x: 1-2*x, 0, lambda x, y: 1-x-2*y)
        (0.05416666666666668, 2.1774196738157757e-14)

        Calculate :math:`\int^{x=1}_{x=0} \int^{y=1}_{y=0} \int^{z=1}_{z=0}
        a x y z \,dz \,dy \,dx` for :math:`a=1, 3`.

        >>> f = lambda z, y, x, a: a*x*y*z
        >>> integrate.tplquad(f, 0, 1, 0, 1, 0, 1, args=(1,))
            (0.125, 5.527033708952211e-15)
        >>> integrate.tplquad(f, 0, 1, 0, 1, 0, 1, args=(3,))
            (0.375, 1.6581101126856635e-14)

        Compute the three-dimensional Gaussian Integral, which is the integral of
        the Gaussian function :math:`f(x,y,z) = e^{-(x^{2} + y^{2} + z^{2})}`, over
        :math:`(-\infty,+\infty)`. That is, compute the integral
        :math:`\iiint^{+\infty}_{-\infty} e^{-(x^{2} + y^{2} + z^{2})} \,dz
        \,dy\,dx`.

        >>> f = lambda x, y, z: np.exp(-(x ** 2 + y ** 2 + z ** 2))
        >>> integrate.tplquad(f, -np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf)
            (5.568327996830833, 4.4619078828029765e-08)

    trapezoid(y, x=None, dx=1.0, axis=-1)
        Integrate along the given axis using the composite trapezoidal rule.

        If `x` is provided, the integration happens in sequence along its
        elements - they are not sorted.

        Integrate `y` (`x`) along each 1d slice on the given axis, compute
        :math:`\int y(x) dx`.
        When `x` is specified, this integrates along the parametric curve,
        computing :math:`\int_t y(t) dt =
        \int_t y(t) \left.\frac{dx}{dt}\right|_{x=x(t)} dt`.

        Parameters
        ----------
        y : array_like
            Input array to integrate.
        x : array_like, optional
            The sample points corresponding to the `y` values. If `x` is None,
            the sample points are assumed to be evenly spaced `dx` apart. The
            default is None.
        dx : scalar, optional
            The spacing between sample points when `x` is None. The default is 1.
        axis : int, optional
            The axis along which to integrate.

        Returns
        -------
        trapezoid : float or ndarray
            Definite integral of `y` = n-dimensional array as approximated along
            a single axis by the trapezoidal rule. If `y` is a 1-dimensional array,
            then the result is a float. If `n` is greater than 1, then the result
            is an `n`-1 dimensional array.

        See Also
        --------
        cumulative_trapezoid, simpson, romb

        Notes
        -----
        Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
        will be taken from `y` array, by default x-axis distances between
        points will be 1.0, alternatively they can be provided with `x` array
        or with `dx` scalar.  Return value will be equal to combined area under
        the red lines.

        References
        ----------
        .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Trapezoidal_rule

        .. [2] Illustration image:
               https://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png

        Examples
        --------
        Use the trapezoidal rule on evenly spaced points:

        >>> import numpy as np
        >>> from scipy import integrate
        >>> integrate.trapezoid([1, 2, 3])
        4.0

        The spacing between sample points can be selected by either the
        ``x`` or ``dx`` arguments:

        >>> integrate.trapezoid([1, 2, 3], x=[4, 6, 8])
        8.0
        >>> integrate.trapezoid([1, 2, 3], dx=2)
        8.0

        Using a decreasing ``x`` corresponds to integrating in reverse:

        >>> integrate.trapezoid([1, 2, 3], x=[8, 6, 4])
        -8.0

        More generally ``x`` is used to integrate along a parametric curve. We can
        estimate the integral :math:`\int_0^1 x^2 = 1/3` using:

        >>> x = np.linspace(0, 1, num=50)
        >>> y = x**2
        >>> integrate.trapezoid(y, x)
        0.33340274885464394

        Or estimate the area of a circle, noting we repeat the sample which closes
        the curve:

        >>> theta = np.linspace(0, 2 * np.pi, num=1000, endpoint=True)
        >>> integrate.trapezoid(np.cos(theta), x=np.sin(theta))
        3.141571941375841

        ``trapezoid`` can be applied along a specified axis to do multiple
        computations in one call:

        >>> a = np.arange(6).reshape(2, 3)
        >>> a
        array([[0, 1, 2],
               [3, 4, 5]])
        >>> integrate.trapezoid(a, axis=0)
        array([1.5, 2.5, 3.5])
        >>> integrate.trapezoid(a, axis=1)
        array([2.,  8.])

DATA
    __all__ = ['AccuracyWarning', 'BDF', 'DOP853', 'DenseOutput', 'Integra...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\integrate\__init__.py

scipy.interpolate
Python Library Documentation: package scipy.interpolate in scipy

NAME
    scipy.interpolate

DESCRIPTION
    ========================================
    Interpolation (:mod:`scipy.interpolate`)
    ========================================

    .. currentmodule:: scipy.interpolate

    Sub-package for objects used in interpolation.

    As listed below, this sub-package contains spline functions and classes,
    1-D and multidimensional (univariate and multivariate)
    interpolation classes, Lagrange and Taylor polynomial interpolators, and
    wrappers for `FITPACK <http://www.netlib.org/dierckx/>`__
    and DFITPACK functions.

    Univariate interpolation
    ========================

    .. autosummary::
       :toctree: generated/

       interp1d
       BarycentricInterpolator
       KroghInterpolator
       barycentric_interpolate
       krogh_interpolate
       pchip_interpolate
       CubicHermiteSpline
       PchipInterpolator
       Akima1DInterpolator
       CubicSpline
       PPoly
       BPoly


    Multivariate interpolation
    ==========================

    Unstructured data:

    .. autosummary::
       :toctree: generated/

       griddata
       LinearNDInterpolator
       NearestNDInterpolator
       CloughTocher2DInterpolator
       RBFInterpolator
       Rbf
       interp2d

    For data on a grid:

    .. autosummary::
       :toctree: generated/

       interpn
       RegularGridInterpolator
       RectBivariateSpline

    .. seealso::

        `scipy.ndimage.map_coordinates`

    Tensor product polynomials:

    .. autosummary::
       :toctree: generated/

       NdPPoly
       NdBSpline

    1-D Splines
    ===========

    .. autosummary::
       :toctree: generated/

       BSpline
       make_interp_spline
       make_lsq_spline
       make_smoothing_spline

    Functional interface to FITPACK routines:

    .. autosummary::
       :toctree: generated/

       splrep
       splprep
       splev
       splint
       sproot
       spalde
       splder
       splantider
       insert

    Object-oriented FITPACK interface:

    .. autosummary::
       :toctree: generated/

       UnivariateSpline
       InterpolatedUnivariateSpline
       LSQUnivariateSpline



    2-D Splines
    ===========

    For data on a grid:

    .. autosummary::
       :toctree: generated/

       RectBivariateSpline
       RectSphereBivariateSpline

    For unstructured data:

    .. autosummary::
       :toctree: generated/

       BivariateSpline
       SmoothBivariateSpline
       SmoothSphereBivariateSpline
       LSQBivariateSpline
       LSQSphereBivariateSpline

    Low-level interface to FITPACK functions:

    .. autosummary::
       :toctree: generated/

       bisplrep
       bisplev

    Additional tools
    ================

    .. autosummary::
       :toctree: generated/

       lagrange
       approximate_taylor_polynomial
       pade

    .. seealso::

       `scipy.ndimage.map_coordinates`,
       `scipy.ndimage.spline_filter`,
       `scipy.signal.resample`,
       `scipy.signal.bspline`,
       `scipy.signal.gauss_spline`,
       `scipy.signal.qspline1d`,
       `scipy.signal.cspline1d`,
       `scipy.signal.qspline1d_eval`,
       `scipy.signal.cspline1d_eval`,
       `scipy.signal.qspline2d`,
       `scipy.signal.cspline2d`.

    ``pchip`` is an alias of `PchipInterpolator` for backward compatibility
    (should not be used in new code).

PACKAGE CONTENTS
    _bspl
    _bsplines
    _cubic
    _dfitpack
    _fitpack
    _fitpack2
    _fitpack_impl
    _fitpack_py
    _interpolate
    _ndbspline
    _ndgriddata
    _pade
    _polyint
    _ppoly
    _rbf
    _rbfinterp
    _rbfinterp_pythran
    _rgi
    _rgi_cython
    dfitpack
    fitpack
    fitpack2
    interpnd
    interpolate
    ndgriddata
    polyint
    rbf
    tests (package)

CLASSES
    builtins.object
        scipy.interpolate._bsplines.BSpline
        scipy.interpolate._fitpack2.UnivariateSpline
            scipy.interpolate._fitpack2.InterpolatedUnivariateSpline
            scipy.interpolate._fitpack2.LSQUnivariateSpline
        scipy.interpolate._interpolate.NdPPoly
        scipy.interpolate._interpolate.interp2d
        scipy.interpolate._ndbspline.NdBSpline
        scipy.interpolate._rbf.Rbf
        scipy.interpolate._rbfinterp.RBFInterpolator
        scipy.interpolate._rgi.RegularGridInterpolator
    scipy.interpolate._fitpack2.SphereBivariateSpline(scipy.interpolate._fitpack2._BivariateSplineBase)
        scipy.interpolate._fitpack2.LSQSphereBivariateSpline
        scipy.interpolate._fitpack2.RectSphereBivariateSpline
        scipy.interpolate._fitpack2.SmoothSphereBivariateSpline
    scipy.interpolate._fitpack2._BivariateSplineBase(builtins.object)
        scipy.interpolate._fitpack2.BivariateSpline
            scipy.interpolate._fitpack2.LSQBivariateSpline
            scipy.interpolate._fitpack2.RectBivariateSpline
            scipy.interpolate._fitpack2.SmoothBivariateSpline
    scipy.interpolate._interpolate._PPolyBase(builtins.object)
        scipy.interpolate._interpolate.BPoly
        scipy.interpolate._interpolate.PPoly
            scipy.interpolate._cubic.CubicHermiteSpline
                scipy.interpolate._cubic.Akima1DInterpolator
                scipy.interpolate._cubic.CubicSpline
                scipy.interpolate._cubic.PchipInterpolator
    scipy.interpolate._polyint._Interpolator1D(builtins.object)
        scipy.interpolate._interpolate.interp1d
    scipy.interpolate._polyint._Interpolator1DWithDerivatives(scipy.interpolate._polyint._Interpolator1D)
        scipy.interpolate._polyint.BarycentricInterpolator
        scipy.interpolate._polyint.KroghInterpolator
    scipy.interpolate.interpnd.NDInterpolatorBase(builtins.object)
        scipy.interpolate._ndgriddata.NearestNDInterpolator
        scipy.interpolate.interpnd.CloughTocher2DInterpolator
        scipy.interpolate.interpnd.LinearNDInterpolator

    class Akima1DInterpolator(CubicHermiteSpline)
     |  Akima1DInterpolator(x, y, axis=0, *, method: "Literal['akima', 'makima']" = 'akima', extrapolate: 'bool | None' = None)
     |
     |  Akima interpolator
     |
     |  Fit piecewise cubic polynomials, given vectors x and y. The interpolation
     |  method by Akima uses a continuously differentiable sub-spline built from
     |  piecewise cubic polynomials. The resultant curve passes through the given
     |  data points and will appear smooth and natural.
     |
     |  Parameters
     |  ----------
     |  x : ndarray, shape (npoints, )
     |      1-D array of monotonically increasing real values.
     |  y : ndarray, shape (..., npoints, ...)
     |      N-D array of real values. The length of ``y`` along the interpolation axis
     |      must be equal to the length of ``x``. Use the ``axis`` parameter to
     |      select the interpolation axis.
     |
     |      .. deprecated:: 1.13.0
     |          Complex data is deprecated and will raise an error in SciPy 1.15.0.
     |          If you are trying to use the real components of the passed array,
     |          use ``np.real`` on ``y``.
     |
     |  axis : int, optional
     |      Axis in the ``y`` array corresponding to the x-coordinate values. Defaults
     |      to ``axis=0``.
     |  method : {'akima', 'makima'}, optional
     |      If ``"makima"``, use the modified Akima interpolation [2]_.
     |      Defaults to ``"akima"``, use the Akima interpolation [1]_.
     |
     |      .. versionadded:: 1.13.0
     |
     |  extrapolate : {bool, None}, optional
     |      If bool, determines whether to extrapolate to out-of-bounds points
     |      based on first and last intervals, or to return NaNs. If None,
     |      ``extrapolate`` is set to False.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  roots
     |
     |  See Also
     |  --------
     |  PchipInterpolator : PCHIP 1-D monotonic cubic interpolator.
     |  CubicSpline : Cubic spline data interpolator.
     |  PPoly : Piecewise polynomial in terms of coefficients and breakpoints
     |
     |  Notes
     |  -----
     |  .. versionadded:: 0.14
     |
     |  Use only for precise data, as the fitted curve passes through the given
     |  points exactly. This routine is useful for plotting a pleasingly smooth
     |  curve through a few given points for purposes of plotting.
     |
     |  Let :math:`\delta_i = (y_{i+1} - y_i) / (x_{i+1} - x_i)` be the slopes of
     |  the interval :math:`\left[x_i, x_{i+1}\right)`. Akima's derivative at
     |  :math:`x_i` is defined as:
     |
     |  .. math::
     |
     |      d_i = \frac{w_1}{w_1 + w_2}\delta_{i-1} + \frac{w_2}{w_1 + w_2}\delta_i
     |
     |  In the Akima interpolation [1]_ (``method="akima"``), the weights are:
     |
     |  .. math::
     |
     |      \begin{aligned}
     |      w_1 &= |\delta_{i+1} - \delta_i| \\
     |      w_2 &= |\delta_{i-1} - \delta_{i-2}|
     |      \end{aligned}
     |
     |  In the modified Akima interpolation [2]_ (``method="makima"``),
     |  to eliminate overshoot and avoid edge cases of both numerator and
     |  denominator being equal to 0, the weights are modified as follows:
     |
     |  .. math::
     |
     |      \begin{align*}
     |      w_1 &= |\delta_{i+1} - \delta_i| + |\delta_{i+1} + \delta_i| / 2 \\
     |      w_2 &= |\delta_{i-1} - \delta_{i-2}| + |\delta_{i-1} + \delta_{i-2}| / 2
     |      \end{align*}
     |
     |  Examples
     |  --------
     |  Comparison of ``method="akima"`` and ``method="makima"``:
     |
     |  >>> import numpy as np
     |  >>> from scipy.interpolate import Akima1DInterpolator
     |  >>> import matplotlib.pyplot as plt
     |  >>> x = np.linspace(1, 7, 7)
     |  >>> y = np.array([-1, -1, -1, 0, 1, 1, 1])
     |  >>> xs = np.linspace(min(x), max(x), num=100)
     |  >>> y_akima = Akima1DInterpolator(x, y, method="akima")(xs)
     |  >>> y_makima = Akima1DInterpolator(x, y, method="makima")(xs)
     |
     |  >>> fig, ax = plt.subplots()
     |  >>> ax.plot(x, y, "o", label="data")
     |  >>> ax.plot(xs, y_akima, label="akima")
     |  >>> ax.plot(xs, y_makima, label="makima")
     |  >>> ax.legend()
     |  >>> fig.show()
     |
     |  The overshoot that occured in ``"akima"`` has been avoided in ``"makima"``.
     |
     |  References
     |  ----------
     |  .. [1] A new method of interpolation and smooth curve fitting based
     |         on local procedures. Hiroshi Akima, J. ACM, October 1970, 17(4),
     |         589-602. :doi:`10.1145/321607.321609`
     |  .. [2] Makima Piecewise Cubic Interpolation. Cleve Moler and Cosmin Ionita, 2019.
     |         https://blogs.mathworks.com/cleve/2019/04/29/makima-piecewise-cubic-interpolation/
     |
     |  Method resolution order:
     |      Akima1DInterpolator
     |      CubicHermiteSpline
     |      scipy.interpolate._interpolate.PPoly
     |      scipy.interpolate._interpolate._PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, axis=0, *, method: "Literal['akima', 'makima']" = 'akima', extrapolate: 'bool | None' = None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  extend(self, c, x, right=True)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  from_bernstein_basis(bp, extrapolate=None)
     |      Construct a piecewise polynomial in the power basis
     |      from a polynomial in Bernstein basis.
     |
     |      Parameters
     |      ----------
     |      bp : BPoly
     |          A Bernstein basis polynomial, as created by BPoly
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  from_spline(tck, extrapolate=None)
     |      Construct a piecewise polynomial from a spline
     |
     |      Parameters
     |      ----------
     |      tck
     |          A spline, as returned by `splrep` or a BSpline object.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Examples
     |      --------
     |      Construct an interpolating spline and convert it to a `PPoly` instance
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> x = np.linspace(0, 1, 11)
     |      >>> y = np.sin(2*np.pi*x)
     |      >>> tck = splrep(x, y, s=0)
     |      >>> p = PPoly.from_spline(tck)
     |      >>> isinstance(p, PPoly)
     |      True
     |
     |      Note that this function only supports 1D splines out of the box.
     |
     |      If the ``tck`` object represents a parametric spline (e.g. constructed
     |      by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
     |      over the dimensions manually.
     |
     |      >>> from scipy.interpolate import splprep, splev
     |      >>> t = np.linspace(0, 1, 11)
     |      >>> x = np.sin(2*np.pi*t)
     |      >>> y = np.cos(2*np.pi*t)
     |      >>> (t, c, k), u = splprep([x, y], s=0)
     |
     |      Note that ``c`` is a list of two arrays of length 11.
     |
     |      >>> unew = np.arange(0, 1.01, 0.01)
     |      >>> out = splev(unew, (t, c, k))
     |
     |      To convert this spline to the power basis, we convert each
     |      component of the list of b-spline coefficients, ``c``, into the
     |      corresponding cubic polynomial.
     |
     |      >>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
     |      >>> polys[0].c.shape
     |      (4, 14)
     |
     |      Note that the coefficients of the polynomials `polys` are in the
     |      power basis and their dimensions reflect just that: here 4 is the order
     |      (degree+1), and 14 is the number of intervals---which is nothing but
     |      the length of the knot array of the original `tck` minus one.
     |
     |      Optionally, we can stack the components into a single `PPoly` along
     |      the third dimension:
     |
     |      >>> cc = np.dstack([p.c for p in polys])    # has shape = (4, 14, 2)
     |      >>> poly = PPoly(cc, polys[0].x)
     |      >>> np.allclose(poly(unew).T,     # note the transpose to match `splev`
     |      ...             out, atol=1e-15)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k - n representing the derivative
     |          of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  roots(self, discontinuity=True, extrapolate=None)
     |      Find real roots of the piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      See Also
     |      --------
     |      PPoly.solve
     |
     |  solve(self, y=0.0, discontinuity=True, extrapolate=None)
     |      Find real solutions of the equation ``pp(x) == y``.
     |
     |      Parameters
     |      ----------
     |      y : float, optional
     |          Right-hand side. Default is zero.
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      Notes
     |      -----
     |      This routine works only on real-valued polynomials.
     |
     |      If the piecewise polynomial contains sections that are
     |      identically zero, the root list will contain the start point
     |      of the corresponding interval, followed by a ``nan`` value.
     |
     |      If the polynomial is discontinuous across a breakpoint, and
     |      there is a sign change across the breakpoint, this is reported
     |      if the `discont` parameter is True.
     |
     |      Examples
     |      --------
     |
     |      Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
     |      ``[-2, 1], [1, 2]``:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import PPoly
     |      >>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
     |      >>> pp.solve()
     |      array([-1.,  1.])
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class BPoly(_PPolyBase)
     |  BPoly(c, x, extrapolate=None, axis=0)
     |
     |  Piecewise polynomial in terms of coefficients and breakpoints.
     |
     |  The polynomial between ``x[i]`` and ``x[i + 1]`` is written in the
     |  Bernstein polynomial basis::
     |
     |      S = sum(c[a, i] * b(a, k; x) for a in range(k+1)),
     |
     |  where ``k`` is the degree of the polynomial, and::
     |
     |      b(a, k; x) = binom(k, a) * t**a * (1 - t)**(k - a),
     |
     |  with ``t = (x - x[i]) / (x[i+1] - x[i])`` and ``binom`` is the binomial
     |  coefficient.
     |
     |  Parameters
     |  ----------
     |  c : ndarray, shape (k, m, ...)
     |      Polynomial coefficients, order `k` and `m` intervals
     |  x : ndarray, shape (m+1,)
     |      Polynomial breakpoints. Must be sorted in either increasing or
     |      decreasing order.
     |  extrapolate : bool, optional
     |      If bool, determines whether to extrapolate to out-of-bounds points
     |      based on first and last intervals, or to return NaNs. If 'periodic',
     |      periodic extrapolation is used. Default is True.
     |  axis : int, optional
     |      Interpolation axis. Default is zero.
     |
     |  Attributes
     |  ----------
     |  x : ndarray
     |      Breakpoints.
     |  c : ndarray
     |      Coefficients of the polynomials. They are reshaped
     |      to a 3-D array with the last dimension representing
     |      the trailing dimensions of the original coefficient array.
     |  axis : int
     |      Interpolation axis.
     |
     |  Methods
     |  -------
     |  __call__
     |  extend
     |  derivative
     |  antiderivative
     |  integrate
     |  construct_fast
     |  from_power_basis
     |  from_derivatives
     |
     |  See also
     |  --------
     |  PPoly : piecewise polynomials in the power basis
     |
     |  Notes
     |  -----
     |  Properties of Bernstein polynomials are well documented in the literature,
     |  see for example [1]_ [2]_ [3]_.
     |
     |  References
     |  ----------
     |  .. [1] https://en.wikipedia.org/wiki/Bernstein_polynomial
     |
     |  .. [2] Kenneth I. Joy, Bernstein polynomials,
     |     http://www.idav.ucdavis.edu/education/CAGDNotes/Bernstein-Polynomials.pdf
     |
     |  .. [3] E. H. Doha, A. H. Bhrawy, and M. A. Saker, Boundary Value Problems,
     |         vol 2011, article ID 829546, :doi:`10.1155/2011/829543`.
     |
     |  Examples
     |  --------
     |  >>> from scipy.interpolate import BPoly
     |  >>> x = [0, 1]
     |  >>> c = [[1], [2], [3]]
     |  >>> bp = BPoly(c, x)
     |
     |  This creates a 2nd order polynomial
     |
     |  .. math::
     |
     |      B(x) = 1 \times b_{0, 2}(x) + 2 \times b_{1, 2}(x) + 3
     |             \times b_{2, 2}(x) \\
     |           = 1 \times (1-x)^2 + 2 \times 2 x (1 - x) + 3 \times x^2
     |
     |  Method resolution order:
     |      BPoly
     |      _PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      bp : BPoly
     |          Piecewise polynomial of order k + nu representing the
     |          antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      bp : BPoly
     |          Piecewise polynomial of order k - nu representing the derivative of
     |          this polynomial.
     |
     |  extend(self, c, x)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          Whether to extrapolate to out-of-bounds points based on first
     |          and last intervals, or to return NaNs. If 'periodic', periodic
     |          extrapolation is used. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  from_derivatives(xi, yi, orders=None, extrapolate=None)
     |      Construct a piecewise polynomial in the Bernstein basis,
     |      compatible with the specified values and derivatives at breakpoints.
     |
     |      Parameters
     |      ----------
     |      xi : array_like
     |          sorted 1-D array of x-coordinates
     |      yi : array_like or list of array_likes
     |          ``yi[i][j]`` is the ``j``\ th derivative known at ``xi[i]``
     |      orders : None or int or array_like of ints. Default: None.
     |          Specifies the degree of local polynomials. If not None, some
     |          derivatives are ignored.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Notes
     |      -----
     |      If ``k`` derivatives are specified at a breakpoint ``x``, the
     |      constructed polynomial is exactly ``k`` times continuously
     |      differentiable at ``x``, unless the ``order`` is provided explicitly.
     |      In the latter case, the smoothness of the polynomial at
     |      the breakpoint is controlled by the ``order``.
     |
     |      Deduces the number of derivatives to match at each end
     |      from ``order`` and the number of derivatives available. If
     |      possible it uses the same number of derivatives from
     |      each end; if the number is odd it tries to take the
     |      extra one from y2. In any case if not enough derivatives
     |      are available at one end or another it draws enough to
     |      make up the total from the other end.
     |
     |      If the order is too high and not enough derivatives are available,
     |      an exception is raised.
     |
     |      Examples
     |      --------
     |
     |      >>> from scipy.interpolate import BPoly
     |      >>> BPoly.from_derivatives([0, 1], [[1, 2], [3, 4]])
     |
     |      Creates a polynomial `f(x)` of degree 3, defined on `[0, 1]`
     |      such that `f(0) = 1, df/dx(0) = 2, f(1) = 3, df/dx(1) = 4`
     |
     |      >>> BPoly.from_derivatives([0, 1, 2], [[0, 1], [0], [2]])
     |
     |      Creates a piecewise polynomial `f(x)`, such that
     |      `f(0) = f(1) = 0`, `f(2) = 2`, and `df/dx(0) = 1`.
     |      Based on the number of derivatives provided, the order of the
     |      local polynomials is 2 on `[0, 1]` and 1 on `[1, 2]`.
     |      Notice that no restriction is imposed on the derivatives at
     |      ``x = 1`` and ``x = 2``.
     |
     |      Indeed, the explicit form of the polynomial is::
     |
     |          f(x) = | x * (1 - x),  0 <= x < 1
     |                 | 2 * (x - 1),  1 <= x <= 2
     |
     |      So that f'(1-0) = -1 and f'(1+0) = 2
     |
     |  from_power_basis(pp, extrapolate=None)
     |      Construct a piecewise polynomial in Bernstein basis
     |      from a power basis polynomial.
     |
     |      Parameters
     |      ----------
     |      pp : PPoly
     |          A piecewise polynomial in the power basis
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  __init__(self, c, x, extrapolate=None, axis=0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from _PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class BSpline(builtins.object)
     |  BSpline(t, c, k, extrapolate=True, axis=0)
     |
     |  Univariate spline in the B-spline basis.
     |
     |  .. math::
     |
     |      S(x) = \sum_{j=0}^{n-1} c_j  B_{j, k; t}(x)
     |
     |  where :math:`B_{j, k; t}` are B-spline basis functions of degree `k`
     |  and knots `t`.
     |
     |  Parameters
     |  ----------
     |  t : ndarray, shape (n+k+1,)
     |      knots
     |  c : ndarray, shape (>=n, ...)
     |      spline coefficients
     |  k : int
     |      B-spline degree
     |  extrapolate : bool or 'periodic', optional
     |      whether to extrapolate beyond the base interval, ``t[k] .. t[n]``,
     |      or to return nans.
     |      If True, extrapolates the first and last polynomial pieces of b-spline
     |      functions active on the base interval.
     |      If 'periodic', periodic extrapolation is used.
     |      Default is True.
     |  axis : int, optional
     |      Interpolation axis. Default is zero.
     |
     |  Attributes
     |  ----------
     |  t : ndarray
     |      knot vector
     |  c : ndarray
     |      spline coefficients
     |  k : int
     |      spline degree
     |  extrapolate : bool
     |      If True, extrapolates the first and last polynomial pieces of b-spline
     |      functions active on the base interval.
     |  axis : int
     |      Interpolation axis.
     |  tck : tuple
     |      A read-only equivalent of ``(self.t, self.c, self.k)``
     |
     |  Methods
     |  -------
     |  __call__
     |  basis_element
     |  derivative
     |  antiderivative
     |  integrate
     |  insert_knot
     |  construct_fast
     |  design_matrix
     |  from_power_basis
     |
     |  Notes
     |  -----
     |  B-spline basis elements are defined via
     |
     |  .. math::
     |
     |      B_{i, 0}(x) = 1, \textrm{if $t_i \le x < t_{i+1}$, otherwise $0$,}
     |
     |      B_{i, k}(x) = \frac{x - t_i}{t_{i+k} - t_i} B_{i, k-1}(x)
     |               + \frac{t_{i+k+1} - x}{t_{i+k+1} - t_{i+1}} B_{i+1, k-1}(x)
     |
     |  **Implementation details**
     |
     |  - At least ``k+1`` coefficients are required for a spline of degree `k`,
     |    so that ``n >= k+1``. Additional coefficients, ``c[j]`` with
     |    ``j > n``, are ignored.
     |
     |  - B-spline basis elements of degree `k` form a partition of unity on the
     |    *base interval*, ``t[k] <= x <= t[n]``.
     |
     |
     |  Examples
     |  --------
     |
     |  Translating the recursive definition of B-splines into Python code, we have:
     |
     |  >>> def B(x, k, i, t):
     |  ...    if k == 0:
     |  ...       return 1.0 if t[i] <= x < t[i+1] else 0.0
     |  ...    if t[i+k] == t[i]:
     |  ...       c1 = 0.0
     |  ...    else:
     |  ...       c1 = (x - t[i])/(t[i+k] - t[i]) * B(x, k-1, i, t)
     |  ...    if t[i+k+1] == t[i+1]:
     |  ...       c2 = 0.0
     |  ...    else:
     |  ...       c2 = (t[i+k+1] - x)/(t[i+k+1] - t[i+1]) * B(x, k-1, i+1, t)
     |  ...    return c1 + c2
     |
     |  >>> def bspline(x, t, c, k):
     |  ...    n = len(t) - k - 1
     |  ...    assert (n >= k+1) and (len(c) >= n)
     |  ...    return sum(c[i] * B(x, k, i, t) for i in range(n))
     |
     |  Note that this is an inefficient (if straightforward) way to
     |  evaluate B-splines --- this spline class does it in an equivalent,
     |  but much more efficient way.
     |
     |  Here we construct a quadratic spline function on the base interval
     |  ``2 <= x <= 4`` and compare with the naive way of evaluating the spline:
     |
     |  >>> from scipy.interpolate import BSpline
     |  >>> k = 2
     |  >>> t = [0, 1, 2, 3, 4, 5, 6]
     |  >>> c = [-1, 2, 0, -1]
     |  >>> spl = BSpline(t, c, k)
     |  >>> spl(2.5)
     |  array(1.375)
     |  >>> bspline(2.5, t, c, k)
     |  1.375
     |
     |  Note that outside of the base interval results differ. This is because
     |  `BSpline` extrapolates the first and last polynomial pieces of B-spline
     |  functions active on the base interval.
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> import numpy as np
     |  >>> fig, ax = plt.subplots()
     |  >>> xx = np.linspace(1.5, 4.5, 50)
     |  >>> ax.plot(xx, [bspline(x, t, c ,k) for x in xx], 'r-', lw=3, label='naive')
     |  >>> ax.plot(xx, spl(xx), 'b-', lw=4, alpha=0.7, label='BSpline')
     |  >>> ax.grid(True)
     |  >>> ax.legend(loc='best')
     |  >>> plt.show()
     |
     |
     |  References
     |  ----------
     |  .. [1] Tom Lyche and Knut Morken, Spline methods,
     |      http://www.uio.no/studier/emner/matnat/ifi/INF-MAT5340/v05/undervisningsmateriale/
     |  .. [2] Carl de Boor, A practical guide to splines, Springer, 2001.
     |
     |  Methods defined here:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate a spline function.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          points to evaluate the spline at.
     |      nu : int, optional
     |          derivative to evaluate (default is 0).
     |      extrapolate : bool or 'periodic', optional
     |          whether to extrapolate based on the first and last intervals
     |          or return nans. If 'periodic', periodic extrapolation is used.
     |          Default is `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Shape is determined by replacing the interpolation axis
     |          in the coefficient array with the shape of `x`.
     |
     |  __init__(self, t, c, k, extrapolate=True, axis=0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  antiderivative(self, nu=1)
     |      Return a B-spline representing the antiderivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Antiderivative order. Default is 1.
     |
     |      Returns
     |      -------
     |      b : BSpline object
     |          A new instance representing the antiderivative.
     |
     |      Notes
     |      -----
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |      See Also
     |      --------
     |      splder, splantider
     |
     |  derivative(self, nu=1)
     |      Return a B-spline representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Derivative order.
     |          Default is 1.
     |
     |      Returns
     |      -------
     |      b : BSpline object
     |          A new instance representing the derivative.
     |
     |      See Also
     |      --------
     |      splder, splantider
     |
     |  insert_knot(self, x, m=1)
     |      Insert a new knot at `x` of multiplicity `m`.
     |
     |      Given the knots and coefficients of a B-spline representation, create a
     |      new B-spline with a knot inserted `m` times at point `x`.
     |
     |      Parameters
     |      ----------
     |      x : float
     |          The position of the new knot
     |      m : int, optional
     |          The number of times to insert the given knot (its multiplicity).
     |          Default is 1.
     |
     |      Returns
     |      -------
     |      spl : BSpline object
     |          A new BSpline object with the new knot inserted.
     |
     |      Notes
     |      -----
     |      Based on algorithms from [1]_ and [2]_.
     |
     |      In case of a periodic spline (``self.extrapolate == "periodic"``)
     |      there must be either at least k interior knots t(j) satisfying
     |      ``t(k+1)<t(j)<=x`` or at least k interior knots t(j) satisfying
     |      ``x<=t(j)<t(n-k)``.
     |
     |      This routine is functionally equivalent to `scipy.interpolate.insert`.
     |
     |      .. versionadded:: 1.13
     |
     |      References
     |      ----------
     |      .. [1] W. Boehm, "Inserting new knots into b-spline curves.",
     |          Computer Aided Design, 12, p.199-201, 1980.
     |          :doi:`10.1016/0010-4485(80)90154-2`.
     |      .. [2] P. Dierckx, "Curve and surface fitting with splines, Monographs on
     |          Numerical Analysis", Oxford University Press, 1993.
     |
     |      See Also
     |      --------
     |      scipy.interpolate.insert
     |
     |      Examples
     |      --------
     |      You can insert knots into a B-spline:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import BSpline, make_interp_spline
     |      >>> x = np.linspace(0, 10, 5)
     |      >>> y = np.sin(x)
     |      >>> spl = make_interp_spline(x, y, k=3)
     |      >>> spl.t
     |      array([ 0.,  0.,  0.,  0.,  5., 10., 10., 10., 10.])
     |
     |      Insert a single knot
     |
     |      >>> spl_1 = spl.insert_knot(3)
     |      >>> spl_1.t
     |      array([ 0.,  0.,  0.,  0.,  3.,  5., 10., 10., 10., 10.])
     |
     |      Insert a multiple knot
     |
     |      >>> spl_2 = spl.insert_knot(8, m=3)
     |      >>> spl_2.t
     |      array([ 0.,  0.,  0.,  0.,  5.,  8.,  8.,  8., 10., 10., 10., 10.])
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral of the spline.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower limit of integration.
     |      b : float
     |          Upper limit of integration.
     |      extrapolate : bool or 'periodic', optional
     |          whether to extrapolate beyond the base interval,
     |          ``t[k] .. t[-k-1]``, or take the spline to be zero outside of the
     |          base interval. If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      I : array_like
     |          Definite integral of the spline over the interval ``[a, b]``.
     |
     |      Examples
     |      --------
     |      Construct the linear spline ``x if x < 1 else 2 - x`` on the base
     |      interval :math:`[0, 2]`, and integrate it
     |
     |      >>> from scipy.interpolate import BSpline
     |      >>> b = BSpline.basis_element([0, 1, 2])
     |      >>> b.integrate(0, 1)
     |      array(0.5)
     |
     |      If the integration limits are outside of the base interval, the result
     |      is controlled by the `extrapolate` parameter
     |
     |      >>> b.integrate(-1, 1)
     |      array(0.0)
     |      >>> b.integrate(-1, 1, extrapolate=False)
     |      array(0.5)
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig, ax = plt.subplots()
     |      >>> ax.grid(True)
     |      >>> ax.axvline(0, c='r', lw=5, alpha=0.5)  # base interval
     |      >>> ax.axvline(2, c='r', lw=5, alpha=0.5)
     |      >>> xx = [-1, 1, 2]
     |      >>> ax.plot(xx, b(xx))
     |      >>> plt.show()
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  basis_element(t, extrapolate=True)
     |      Return a B-spline basis element ``B(x | t[0], ..., t[k+1])``.
     |
     |      Parameters
     |      ----------
     |      t : ndarray, shape (k+2,)
     |          internal knots
     |      extrapolate : bool or 'periodic', optional
     |          whether to extrapolate beyond the base interval, ``t[0] .. t[k+1]``,
     |          or to return nans.
     |          If 'periodic', periodic extrapolation is used.
     |          Default is True.
     |
     |      Returns
     |      -------
     |      basis_element : callable
     |          A callable representing a B-spline basis element for the knot
     |          vector `t`.
     |
     |      Notes
     |      -----
     |      The degree of the B-spline, `k`, is inferred from the length of `t` as
     |      ``len(t)-2``. The knot vector is constructed by appending and prepending
     |      ``k+1`` elements to internal knots `t`.
     |
     |      Examples
     |      --------
     |
     |      Construct a cubic B-spline:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import BSpline
     |      >>> b = BSpline.basis_element([0, 1, 2, 3, 4])
     |      >>> k = b.k
     |      >>> b.t[k:-k]
     |      array([ 0.,  1.,  2.,  3.,  4.])
     |      >>> k
     |      3
     |
     |      Construct a quadratic B-spline on ``[0, 1, 1, 2]``, and compare
     |      to its explicit form:
     |
     |      >>> t = [0, 1, 1, 2]
     |      >>> b = BSpline.basis_element(t)
     |      >>> def f(x):
     |      ...     return np.where(x < 1, x*x, (2. - x)**2)
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig, ax = plt.subplots()
     |      >>> x = np.linspace(0, 2, 51)
     |      >>> ax.plot(x, b(x), 'g', lw=3)
     |      >>> ax.plot(x, f(x), 'r', lw=8, alpha=0.4)
     |      >>> ax.grid(True)
     |      >>> plt.show()
     |
     |  construct_fast(t, c, k, extrapolate=True, axis=0)
     |      Construct a spline without making checks.
     |
     |      Accepts same parameters as the regular constructor. Input arrays
     |      `t` and `c` must of correct shape and dtype.
     |
     |  design_matrix(x, t, k, extrapolate=False)
     |      Returns a design matrix as a CSR format sparse array.
     |
     |      Parameters
     |      ----------
     |      x : array_like, shape (n,)
     |          Points to evaluate the spline at.
     |      t : array_like, shape (nt,)
     |          Sorted 1D array of knots.
     |      k : int
     |          B-spline degree.
     |      extrapolate : bool or 'periodic', optional
     |          Whether to extrapolate based on the first and last intervals
     |          or raise an error. If 'periodic', periodic extrapolation is used.
     |          Default is False.
     |
     |          .. versionadded:: 1.10.0
     |
     |      Returns
     |      -------
     |      design_matrix : `csr_array` object
     |          Sparse matrix in CSR format where each row contains all the basis
     |          elements of the input row (first row = basis elements of x[0],
     |          ..., last row = basis elements x[-1]).
     |
     |      Examples
     |      --------
     |      Construct a design matrix for a B-spline
     |
     |      >>> from scipy.interpolate import make_interp_spline, BSpline
     |      >>> import numpy as np
     |      >>> x = np.linspace(0, np.pi * 2, 4)
     |      >>> y = np.sin(x)
     |      >>> k = 3
     |      >>> bspl = make_interp_spline(x, y, k=k)
     |      >>> design_matrix = bspl.design_matrix(x, bspl.t, k)
     |      >>> design_matrix.toarray()
     |      [[1.        , 0.        , 0.        , 0.        ],
     |      [0.2962963 , 0.44444444, 0.22222222, 0.03703704],
     |      [0.03703704, 0.22222222, 0.44444444, 0.2962963 ],
     |      [0.        , 0.        , 0.        , 1.        ]]
     |
     |      Construct a design matrix for some vector of knots
     |
     |      >>> k = 2
     |      >>> t = [-1, 0, 1, 2, 3, 4, 5, 6]
     |      >>> x = [1, 2, 3, 4]
     |      >>> design_matrix = BSpline.design_matrix(x, t, k).toarray()
     |      >>> design_matrix
     |      [[0.5, 0.5, 0. , 0. , 0. ],
     |      [0. , 0.5, 0.5, 0. , 0. ],
     |      [0. , 0. , 0.5, 0.5, 0. ],
     |      [0. , 0. , 0. , 0.5, 0.5]]
     |
     |      This result is equivalent to the one created in the sparse format
     |
     |      >>> c = np.eye(len(t) - k - 1)
     |      >>> design_matrix_gh = BSpline(t, c, k)(x)
     |      >>> np.allclose(design_matrix, design_matrix_gh, atol=1e-14)
     |      True
     |
     |      Notes
     |      -----
     |      .. versionadded:: 1.8.0
     |
     |      In each row of the design matrix all the basis elements are evaluated
     |      at the certain point (first row - x[0], ..., last row - x[-1]).
     |
     |      `nt` is a length of the vector of knots: as far as there are
     |      `nt - k - 1` basis elements, `nt` should be not less than `2 * k + 2`
     |      to have at least `k + 1` basis element.
     |
     |      Out of bounds `x` raises a ValueError.
     |
     |  from_power_basis(pp, bc_type='not-a-knot')
     |      Construct a polynomial in the B-spline basis
     |      from a piecewise polynomial in the power basis.
     |
     |      For now, accepts ``CubicSpline`` instances only.
     |
     |      Parameters
     |      ----------
     |      pp : CubicSpline
     |          A piecewise polynomial in the power basis, as created
     |          by ``CubicSpline``
     |      bc_type : string, optional
     |          Boundary condition type as in ``CubicSpline``: one of the
     |          ``not-a-knot``, ``natural``, ``clamped``, or ``periodic``.
     |          Necessary for construction an instance of ``BSpline`` class.
     |          Default is ``not-a-knot``.
     |
     |      Returns
     |      -------
     |      b : BSpline object
     |          A new instance representing the initial polynomial
     |          in the B-spline basis.
     |
     |      Notes
     |      -----
     |      .. versionadded:: 1.8.0
     |
     |      Accepts only ``CubicSpline`` instances for now.
     |
     |      The algorithm follows from differentiation
     |      the Marsden's identity [1]: each of coefficients of spline
     |      interpolation function in the B-spline basis is computed as follows:
     |
     |      .. math::
     |
     |          c_j = \sum_{m=0}^{k} \frac{(k-m)!}{k!}
     |                     c_{m,i} (-1)^{k-m} D^m p_{j,k}(x_i)
     |
     |      :math:`c_{m, i}` - a coefficient of CubicSpline,
     |      :math:`D^m p_{j, k}(x_i)` - an m-th defivative of a dual polynomial
     |      in :math:`x_i`.
     |
     |      ``k`` always equals 3 for now.
     |
     |      First ``n - 2`` coefficients are computed in :math:`x_i = x_j`, e.g.
     |
     |      .. math::
     |
     |          c_1 = \sum_{m=0}^{k} \frac{(k-1)!}{k!} c_{m,1} D^m p_{j,3}(x_1)
     |
     |      Last ``nod + 2`` coefficients are computed in ``x[-2]``,
     |      ``nod`` - number of derivatives at the ends.
     |
     |      For example, consider :math:`x = [0, 1, 2, 3, 4]`,
     |      :math:`y = [1, 1, 1, 1, 1]` and bc_type = ``natural``
     |
     |      The coefficients of CubicSpline in the power basis:
     |
     |      :math:`[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0],
     |      [0, 0, 0, 0, 0], [1, 1, 1, 1, 1]]`
     |
     |      The knot vector: :math:`t = [0, 0, 0, 0, 1, 2, 3, 4, 4, 4, 4]`
     |
     |      In this case
     |
     |      .. math::
     |
     |          c_j = \frac{0!}{k!} c_{3, i} k! = c_{3, i} = 1,~j = 0, ..., 6
     |
     |      References
     |      ----------
     |      .. [1] Tom Lyche and Knut Morken, Spline Methods, 2005, Section 3.1.2
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  tck
     |      Equivalent to ``(self.t, self.c, self.k)`` (read-only).
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class BarycentricInterpolator(_Interpolator1DWithDerivatives)
     |  BarycentricInterpolator(xi, yi=None, axis=0, *, wi=None, random_state=None)
     |
     |  Interpolating polynomial for a set of points.
     |
     |  Constructs a polynomial that passes through a given set of points.
     |  Allows evaluation of the polynomial and all its derivatives,
     |  efficient changing of the y-values to be interpolated,
     |  and updating by adding more x- and y-values.
     |
     |  For reasons of numerical stability, this function does not compute
     |  the coefficients of the polynomial.
     |
     |  The values `yi` need to be provided before the function is
     |  evaluated, but none of the preprocessing depends on them, so rapid
     |  updates are possible.
     |
     |  Parameters
     |  ----------
     |  xi : array_like, shape (npoints, )
     |      1-D array of x coordinates of the points the polynomial
     |      should pass through
     |  yi : array_like, shape (..., npoints, ...), optional
     |      N-D array of y coordinates of the points the polynomial should pass through.
     |      If None, the y values will be supplied later via the `set_y` method.
     |      The length of `yi` along the interpolation axis must be equal to the length
     |      of `xi`. Use the ``axis`` parameter to select correct axis.
     |  axis : int, optional
     |      Axis in the yi array corresponding to the x-coordinate values. Defaults
     |      to ``axis=0``.
     |  wi : array_like, optional
     |      The barycentric weights for the chosen interpolation points `xi`.
     |      If absent or None, the weights will be computed from `xi` (default).
     |      This allows for the reuse of the weights `wi` if several interpolants
     |      are being calculated using the same nodes `xi`, without re-computation.
     |  random_state : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
     |      If `seed` is None (or `np.random`), the `numpy.random.RandomState`
     |      singleton is used.
     |      If `seed` is an int, a new ``RandomState`` instance is used,
     |      seeded with `seed`.
     |      If `seed` is already a ``Generator`` or ``RandomState`` instance then
     |      that instance is used.
     |
     |  Notes
     |  -----
     |  This class uses a "barycentric interpolation" method that treats
     |  the problem as a special case of rational function interpolation.
     |  This algorithm is quite stable, numerically, but even in a world of
     |  exact computation, unless the x coordinates are chosen very
     |  carefully - Chebyshev zeros (e.g., cos(i*pi/n)) are a good choice -
     |  polynomial interpolation itself is a very ill-conditioned process
     |  due to the Runge phenomenon.
     |
     |  Based on Berrut and Trefethen 2004, "Barycentric Lagrange Interpolation".
     |
     |  Examples
     |  --------
     |  To produce a quintic barycentric interpolant approximating the function
     |  :math:`\sin x`, and its first four derivatives, using six randomly-spaced
     |  nodes in :math:`(0, \frac{\pi}{2})`:
     |
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.interpolate import BarycentricInterpolator
     |  >>> rng = np.random.default_rng()
     |  >>> xi = rng.random(6) * np.pi/2
     |  >>> f, f_d1, f_d2, f_d3, f_d4 = np.sin, np.cos, lambda x: -np.sin(x), lambda x: -np.cos(x), np.sin
     |  >>> P = BarycentricInterpolator(xi, f(xi), random_state=rng)
     |  >>> fig, axs = plt.subplots(5, 1, sharex=True, layout='constrained', figsize=(7,10))
     |  >>> x = np.linspace(0, np.pi, 100)
     |  >>> axs[0].plot(x, P(x), 'r:', x, f(x), 'k--', xi, f(xi), 'xk')
     |  >>> axs[1].plot(x, P.derivative(x), 'r:', x, f_d1(x), 'k--', xi, f_d1(xi), 'xk')
     |  >>> axs[2].plot(x, P.derivative(x, 2), 'r:', x, f_d2(x), 'k--', xi, f_d2(xi), 'xk')
     |  >>> axs[3].plot(x, P.derivative(x, 3), 'r:', x, f_d3(x), 'k--', xi, f_d3(xi), 'xk')
     |  >>> axs[4].plot(x, P.derivative(x, 4), 'r:', x, f_d4(x), 'k--', xi, f_d4(xi), 'xk')
     |  >>> axs[0].set_xlim(0, np.pi)
     |  >>> axs[4].set_xlabel(r"$x$")
     |  >>> axs[4].set_xticks([i * np.pi / 4 for i in range(5)],
     |  ...                   ["0", r"$\frac{\pi}{4}$", r"$\frac{\pi}{2}$", r"$\frac{3\pi}{4}$", r"$\pi$"])
     |  >>> axs[0].set_ylabel("$f(x)$")
     |  >>> axs[1].set_ylabel("$f'(x)$")
     |  >>> axs[2].set_ylabel("$f''(x)$")
     |  >>> axs[3].set_ylabel("$f^{(3)}(x)$")
     |  >>> axs[4].set_ylabel("$f^{(4)}(x)$")
     |  >>> labels = ['Interpolation nodes', 'True function $f$', 'Barycentric interpolation']
     |  >>> axs[0].legend(axs[0].get_lines()[::-1], labels, bbox_to_anchor=(0., 1.02, 1., .102),
     |  ...               loc='lower left', ncols=3, mode="expand", borderaxespad=0., frameon=False)
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      BarycentricInterpolator
     |      _Interpolator1DWithDerivatives
     |      _Interpolator1D
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __call__(self, x)
     |      Evaluate the interpolating polynomial at the points x
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the interpolant.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of `x`.
     |
     |      Notes
     |      -----
     |      Currently the code computes an outer product between `x` and the
     |      weights, that is, it constructs an intermediate array of size
     |      ``(N, len(x))``, where N is the degree of the polynomial.
     |
     |  __init__(self, xi, yi=None, axis=0, *, wi=None, random_state=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  add_xi(self, xi, yi=None)
     |      Add more x values to the set to be interpolated
     |
     |      The barycentric interpolation algorithm allows easy updating by
     |      adding more points for the polynomial to pass through.
     |
     |      Parameters
     |      ----------
     |      xi : array_like
     |          The x coordinates of the points that the polynomial should pass
     |          through.
     |      yi : array_like, optional
     |          The y coordinates of the points the polynomial should pass through.
     |          Should have shape ``(xi.size, R)``; if R > 1 then the polynomial is
     |          vector-valued.
     |          If `yi` is not given, the y values will be supplied later. `yi`
     |          should be given if and only if the interpolator has y values
     |          specified.
     |
     |      Notes
     |      -----
     |      The new points added by `add_xi` are not randomly permuted
     |      so there is potential for numerical instability,
     |      especially for a large number of points. If this
     |      happens, please reconstruct interpolation from scratch instead.
     |
     |  derivative(self, x, der=1)
     |      Evaluate a single derivative of the polynomial at the point x.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the derivatives
     |      der : integer, optional
     |          Which derivative to evaluate (default: first derivative).
     |          This number includes the function value as 0th derivative.
     |
     |      Returns
     |      -------
     |      d : ndarray
     |          Derivative interpolated at the x-points. Shape of `d` is
     |          determined by replacing the interpolation axis in the
     |          original array with the shape of `x`.
     |
     |  set_yi(self, yi, axis=None)
     |      Update the y values to be interpolated
     |
     |      The barycentric interpolation algorithm requires the calculation
     |      of weights, but these depend only on the `xi`. The `yi` can be changed
     |      at any time.
     |
     |      Parameters
     |      ----------
     |      yi : array_like
     |          The y-coordinates of the points the polynomial will pass through.
     |          If None, the y values must be supplied later.
     |      axis : int, optional
     |          Axis in the `yi` array corresponding to the x-coordinate values.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _Interpolator1DWithDerivatives:
     |
     |  derivatives(self, x, der=None)
     |      Evaluate several derivatives of the polynomial at the point `x`
     |
     |      Produce an array of derivatives evaluated at the point `x`.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the derivatives
     |      der : int or list or None, optional
     |          How many derivatives to evaluate, or None for all potentially
     |          nonzero derivatives (that is, a number equal to the number
     |          of points), or a list of derivatives to evaluate. This number
     |          includes the function value as the '0th' derivative.
     |
     |      Returns
     |      -------
     |      d : ndarray
     |          Array with derivatives; ``d[j]`` contains the jth derivative.
     |          Shape of ``d[j]`` is determined by replacing the interpolation
     |          axis in the original array with the shape of `x`.
     |
     |      Examples
     |      --------
     |      >>> from scipy.interpolate import KroghInterpolator
     |      >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives(0)
     |      array([1.0,2.0,3.0])
     |      >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives([0,0])
     |      array([[1.0,1.0],
     |             [2.0,2.0],
     |             [3.0,3.0]])
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _Interpolator1DWithDerivatives:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _Interpolator1D:
     |
     |  dtype

    class BivariateSpline(_BivariateSplineBase)
     |  Base class for bivariate splines.
     |
     |  This describes a spline ``s(x, y)`` of degrees ``kx`` and ``ky`` on
     |  the rectangle ``[xb, xe] * [yb, ye]`` calculated from a given set
     |  of data points ``(x, y, z)``.
     |
     |  This class is meant to be subclassed, not instantiated directly.
     |  To construct these splines, call either `SmoothBivariateSpline` or
     |  `LSQBivariateSpline` or `RectBivariateSpline`.
     |
     |  See Also
     |  --------
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Method resolution order:
     |      BivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  ev(self, xi, yi, dx=0, dy=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(xi[i], yi[i]),
     |      i=0,...,len(xi)-1``.
     |
     |      Parameters
     |      ----------
     |      xi, yi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int, optional
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int, optional
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |      >>> def f(x, y):
     |      ...     return np.exp(-np.sqrt((x / 2) ** 2 + y**2))
     |
     |      We sample the function on a coarse grid and set up the interpolator. Note that
     |      the default ``indexing="xy"`` of meshgrid would result in an unexpected
     |      (transposed) result after interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 21)
     |      >>> yarr = np.linspace(-3, 3, 21)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |      >>> zdata = f(xgrid, ygrid)
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |
     |      Next we sample the function along a diagonal slice through the coordinate space
     |      on a finer grid using interpolation.
     |
     |      >>> xinterp = np.linspace(-3, 3, 201)
     |      >>> yinterp = np.linspace(3, -3, 201)
     |      >>> zinterp = rbs.ev(xinterp, yinterp)
     |
     |      And check that the interpolation passes through the function evaluations as a
     |      function of the distance from the origin along the slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sqrt(xarr**2 + yarr**2), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sqrt(xinterp**2 + yinterp**2), zinterp, "-b")
     |      >>> plt.show()
     |
     |  integral(self, xa, xb, ya, yb)
     |      Evaluate the integral of the spline over area [xa,xb] x [ya,yb].
     |
     |      Parameters
     |      ----------
     |      xa, xb : float
     |          The end-points of the x integration interval.
     |      ya, yb : float
     |          The end-points of the y integration interval.
     |
     |      Returns
     |      -------
     |      integ : float
     |          The value of the resulting integral.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  __call__(self, x, y, dx=0, dy=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      x, y : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points ``(x[i],
     |          y[i]), i=0, ..., len(x)-1``.  Standard Numpy broadcasting
     |          is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays x, y. The arrays must be
     |          sorted to increasing order.
     |
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |
     |      We sample the function on a coarse grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 100)
     |      >>> yarr = np.linspace(-3, 3, 100)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |
     |      The function to interpolate decays faster along one axis than the other.
     |
     |      >>> zdata = np.exp(-np.sqrt((xgrid / 2) ** 2 + ygrid**2))
     |
     |      Next we sample on a finer grid using interpolation (kx=ky=1 for bilinear).
     |
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |      >>> xarr_fine = np.linspace(-3, 3, 200)
     |      >>> yarr_fine = np.linspace(-3, 3, 200)
     |      >>> xgrid_fine, ygrid_fine = np.meshgrid(xarr_fine, yarr_fine, indexing="ij")
     |      >>> zdata_interp = rbs(xgrid_fine, ygrid_fine, grid=False)
     |
     |      And check that the result agrees with the input by plotting both.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1, aspect="equal")
     |      >>> ax2 = fig.add_subplot(1, 2, 2, aspect="equal")
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_interp)
     |      >>> plt.show()
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class CloughTocher2DInterpolator(NDInterpolatorBase)
     |  CloughTocher2DInterpolator(points, values, fill_value=nan, tol=1e-06, maxiter=400, rescale=False)
     |
     |  CloughTocher2DInterpolator(points, values, tol=1e-6).
     |
     |  Piecewise cubic, C1 smooth, curvature-minimizing interpolator in 2D.
     |
     |  .. versionadded:: 0.9
     |
     |  Methods
     |  -------
     |  __call__
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndims); or Delaunay
     |      2-D array of data point coordinates, or a precomputed Delaunay triangulation.
     |  values : ndarray of float or complex, shape (npoints, ...)
     |      N-D array of data values at `points`. The length of `values` along the
     |      first axis must be equal to the length of `points`. Unlike some
     |      interpolators, the interpolation axis cannot be changed.
     |  fill_value : float, optional
     |      Value used to fill in for requested points outside of the
     |      convex hull of the input points.  If not provided, then
     |      the default is ``nan``.
     |  tol : float, optional
     |      Absolute/relative tolerance for gradient estimation.
     |  maxiter : int, optional
     |      Maximum number of iterations in gradient estimation.
     |  rescale : bool, optional
     |      Rescale points to unit cube before performing interpolation.
     |      This is useful if some of the input dimensions have
     |      incommensurable units and differ by many orders of magnitude.
     |
     |  Notes
     |  -----
     |  The interpolant is constructed by triangulating the input data
     |  with Qhull [1]_, and constructing a piecewise cubic
     |  interpolating Bezier polynomial on each triangle, using a
     |  Clough-Tocher scheme [CT]_.  The interpolant is guaranteed to be
     |  continuously differentiable.
     |
     |  The gradients of the interpolant are chosen so that the curvature
     |  of the interpolating surface is approximatively minimized. The
     |  gradients necessary for this are estimated using the global
     |  algorithm described in [Nielson83]_ and [Renka84]_.
     |
     |  .. note:: For data on a regular grid use `interpn` instead.
     |
     |  Examples
     |  --------
     |  We can interpolate values on a 2D plane:
     |
     |  >>> from scipy.interpolate import CloughTocher2DInterpolator
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> rng = np.random.default_rng()
     |  >>> x = rng.random(10) - 0.5
     |  >>> y = rng.random(10) - 0.5
     |  >>> z = np.hypot(x, y)
     |  >>> X = np.linspace(min(x), max(x))
     |  >>> Y = np.linspace(min(y), max(y))
     |  >>> X, Y = np.meshgrid(X, Y)  # 2D grid for interpolation
     |  >>> interp = CloughTocher2DInterpolator(list(zip(x, y)), z)
     |  >>> Z = interp(X, Y)
     |  >>> plt.pcolormesh(X, Y, Z, shading='auto')
     |  >>> plt.plot(x, y, "ok", label="input point")
     |  >>> plt.legend()
     |  >>> plt.colorbar()
     |  >>> plt.axis("equal")
     |  >>> plt.show()
     |
     |  See also
     |  --------
     |  griddata :
     |      Interpolate unstructured D-D data.
     |  LinearNDInterpolator :
     |      Piecewise linear interpolator in N > 1 dimensions.
     |  NearestNDInterpolator :
     |      Nearest-neighbor interpolator in N > 1 dimensions.
     |  interpn : Interpolation on a regular grid or rectilinear grid.
     |  RegularGridInterpolator : Interpolator on a regular or rectilinear grid
     |                            in arbitrary dimensions (`interpn` wraps this
     |                            class).
     |
     |  References
     |  ----------
     |  .. [1] http://www.qhull.org/
     |
     |  .. [CT] See, for example,
     |     P. Alfeld,
     |     ''A trivariate Clough-Tocher scheme for tetrahedral data''.
     |     Computer Aided Geometric Design, 1, 169 (1984);
     |     G. Farin,
     |     ''Triangular Bernstein-Bezier patches''.
     |     Computer Aided Geometric Design, 3, 83 (1986).
     |
     |  .. [Nielson83] G. Nielson,
     |     ''A method for interpolating scattered data based upon a minimum norm
     |     network''.
     |     Math. Comp., 40, 253 (1983).
     |
     |  .. [Renka84] R. J. Renka and A. K. Cline.
     |     ''A Triangle-based C1 interpolation method.'',
     |     Rocky Mountain J. Math., 14, 223 (1984).
     |
     |  Method resolution order:
     |      CloughTocher2DInterpolator
     |      NDInterpolatorBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, points, values, fill_value=nan, tol=1e-06, maxiter=400, rescale=False)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from NDInterpolatorBase:
     |
     |  __call__(self, *args)
     |      interpolator(xi)
     |
     |      Evaluate interpolator at given points.
     |
     |      Parameters
     |      ----------
     |      x1, x2, ... xn: array-like of float
     |          Points where to interpolate data at.
     |          x1, x2, ... xn can be array-like of float with broadcastable shape.
     |          or x1 can be array-like of float with shape ``(..., ndim)``
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NDInterpolatorBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class CubicHermiteSpline(scipy.interpolate._interpolate.PPoly)
     |  CubicHermiteSpline(x, y, dydx, axis=0, extrapolate=None)
     |
     |  Piecewise-cubic interpolator matching values and first derivatives.
     |
     |  The result is represented as a `PPoly` instance.
     |
     |  Parameters
     |  ----------
     |  x : array_like, shape (n,)
     |      1-D array containing values of the independent variable.
     |      Values must be real, finite and in strictly increasing order.
     |  y : array_like
     |      Array containing values of the dependent variable. It can have
     |      arbitrary number of dimensions, but the length along ``axis``
     |      (see below) must match the length of ``x``. Values must be finite.
     |  dydx : array_like
     |      Array containing derivatives of the dependent variable. It can have
     |      arbitrary number of dimensions, but the length along ``axis``
     |      (see below) must match the length of ``x``. Values must be finite.
     |  axis : int, optional
     |      Axis along which `y` is assumed to be varying. Meaning that for
     |      ``x[i]`` the corresponding values are ``np.take(y, i, axis=axis)``.
     |      Default is 0.
     |  extrapolate : {bool, 'periodic', None}, optional
     |      If bool, determines whether to extrapolate to out-of-bounds points
     |      based on first and last intervals, or to return NaNs. If 'periodic',
     |      periodic extrapolation is used. If None (default), it is set to True.
     |
     |  Attributes
     |  ----------
     |  x : ndarray, shape (n,)
     |      Breakpoints. The same ``x`` which was passed to the constructor.
     |  c : ndarray, shape (4, n-1, ...)
     |      Coefficients of the polynomials on each segment. The trailing
     |      dimensions match the dimensions of `y`, excluding ``axis``.
     |      For example, if `y` is 1-D, then ``c[k, i]`` is a coefficient for
     |      ``(x-x[i])**(3-k)`` on the segment between ``x[i]`` and ``x[i+1]``.
     |  axis : int
     |      Interpolation axis. The same axis which was passed to the
     |      constructor.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  integrate
     |  roots
     |
     |  See Also
     |  --------
     |  Akima1DInterpolator : Akima 1D interpolator.
     |  PchipInterpolator : PCHIP 1-D monotonic cubic interpolator.
     |  CubicSpline : Cubic spline data interpolator.
     |  PPoly : Piecewise polynomial in terms of coefficients and breakpoints
     |
     |  Notes
     |  -----
     |  If you want to create a higher-order spline matching higher-order
     |  derivatives, use `BPoly.from_derivatives`.
     |
     |  References
     |  ----------
     |  .. [1] `Cubic Hermite spline
     |          <https://en.wikipedia.org/wiki/Cubic_Hermite_spline>`_
     |          on Wikipedia.
     |
     |  Method resolution order:
     |      CubicHermiteSpline
     |      scipy.interpolate._interpolate.PPoly
     |      scipy.interpolate._interpolate._PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, dydx, axis=0, extrapolate=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k - n representing the derivative
     |          of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  roots(self, discontinuity=True, extrapolate=None)
     |      Find real roots of the piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      See Also
     |      --------
     |      PPoly.solve
     |
     |  solve(self, y=0.0, discontinuity=True, extrapolate=None)
     |      Find real solutions of the equation ``pp(x) == y``.
     |
     |      Parameters
     |      ----------
     |      y : float, optional
     |          Right-hand side. Default is zero.
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      Notes
     |      -----
     |      This routine works only on real-valued polynomials.
     |
     |      If the piecewise polynomial contains sections that are
     |      identically zero, the root list will contain the start point
     |      of the corresponding interval, followed by a ``nan`` value.
     |
     |      If the polynomial is discontinuous across a breakpoint, and
     |      there is a sign change across the breakpoint, this is reported
     |      if the `discont` parameter is True.
     |
     |      Examples
     |      --------
     |
     |      Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
     |      ``[-2, 1], [1, 2]``:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import PPoly
     |      >>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
     |      >>> pp.solve()
     |      array([-1.,  1.])
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  from_bernstein_basis(bp, extrapolate=None)
     |      Construct a piecewise polynomial in the power basis
     |      from a polynomial in Bernstein basis.
     |
     |      Parameters
     |      ----------
     |      bp : BPoly
     |          A Bernstein basis polynomial, as created by BPoly
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  from_spline(tck, extrapolate=None)
     |      Construct a piecewise polynomial from a spline
     |
     |      Parameters
     |      ----------
     |      tck
     |          A spline, as returned by `splrep` or a BSpline object.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Examples
     |      --------
     |      Construct an interpolating spline and convert it to a `PPoly` instance
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> x = np.linspace(0, 1, 11)
     |      >>> y = np.sin(2*np.pi*x)
     |      >>> tck = splrep(x, y, s=0)
     |      >>> p = PPoly.from_spline(tck)
     |      >>> isinstance(p, PPoly)
     |      True
     |
     |      Note that this function only supports 1D splines out of the box.
     |
     |      If the ``tck`` object represents a parametric spline (e.g. constructed
     |      by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
     |      over the dimensions manually.
     |
     |      >>> from scipy.interpolate import splprep, splev
     |      >>> t = np.linspace(0, 1, 11)
     |      >>> x = np.sin(2*np.pi*t)
     |      >>> y = np.cos(2*np.pi*t)
     |      >>> (t, c, k), u = splprep([x, y], s=0)
     |
     |      Note that ``c`` is a list of two arrays of length 11.
     |
     |      >>> unew = np.arange(0, 1.01, 0.01)
     |      >>> out = splev(unew, (t, c, k))
     |
     |      To convert this spline to the power basis, we convert each
     |      component of the list of b-spline coefficients, ``c``, into the
     |      corresponding cubic polynomial.
     |
     |      >>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
     |      >>> polys[0].c.shape
     |      (4, 14)
     |
     |      Note that the coefficients of the polynomials `polys` are in the
     |      power basis and their dimensions reflect just that: here 4 is the order
     |      (degree+1), and 14 is the number of intervals---which is nothing but
     |      the length of the knot array of the original `tck` minus one.
     |
     |      Optionally, we can stack the components into a single `PPoly` along
     |      the third dimension:
     |
     |      >>> cc = np.dstack([p.c for p in polys])    # has shape = (4, 14, 2)
     |      >>> poly = PPoly(cc, polys[0].x)
     |      >>> np.allclose(poly(unew).T,     # note the transpose to match `splev`
     |      ...             out, atol=1e-15)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  extend(self, c, x)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class CubicSpline(CubicHermiteSpline)
     |  CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)
     |
     |  Cubic spline data interpolator.
     |
     |  Interpolate data with a piecewise cubic polynomial which is twice
     |  continuously differentiable [1]_. The result is represented as a `PPoly`
     |  instance with breakpoints matching the given data.
     |
     |  Parameters
     |  ----------
     |  x : array_like, shape (n,)
     |      1-D array containing values of the independent variable.
     |      Values must be real, finite and in strictly increasing order.
     |  y : array_like
     |      Array containing values of the dependent variable. It can have
     |      arbitrary number of dimensions, but the length along ``axis``
     |      (see below) must match the length of ``x``. Values must be finite.
     |  axis : int, optional
     |      Axis along which `y` is assumed to be varying. Meaning that for
     |      ``x[i]`` the corresponding values are ``np.take(y, i, axis=axis)``.
     |      Default is 0.
     |  bc_type : string or 2-tuple, optional
     |      Boundary condition type. Two additional equations, given by the
     |      boundary conditions, are required to determine all coefficients of
     |      polynomials on each segment [2]_.
     |
     |      If `bc_type` is a string, then the specified condition will be applied
     |      at both ends of a spline. Available conditions are:
     |
     |      * 'not-a-knot' (default): The first and second segment at a curve end
     |        are the same polynomial. It is a good default when there is no
     |        information on boundary conditions.
     |      * 'periodic': The interpolated functions is assumed to be periodic
     |        of period ``x[-1] - x[0]``. The first and last value of `y` must be
     |        identical: ``y[0] == y[-1]``. This boundary condition will result in
     |        ``y'[0] == y'[-1]`` and ``y''[0] == y''[-1]``.
     |      * 'clamped': The first derivative at curves ends are zero. Assuming
     |        a 1D `y`, ``bc_type=((1, 0.0), (1, 0.0))`` is the same condition.
     |      * 'natural': The second derivative at curve ends are zero. Assuming
     |        a 1D `y`, ``bc_type=((2, 0.0), (2, 0.0))`` is the same condition.
     |
     |      If `bc_type` is a 2-tuple, the first and the second value will be
     |      applied at the curve start and end respectively. The tuple values can
     |      be one of the previously mentioned strings (except 'periodic') or a
     |      tuple `(order, deriv_values)` allowing to specify arbitrary
     |      derivatives at curve ends:
     |
     |      * `order`: the derivative order, 1 or 2.
     |      * `deriv_value`: array_like containing derivative values, shape must
     |        be the same as `y`, excluding ``axis`` dimension. For example, if
     |        `y` is 1-D, then `deriv_value` must be a scalar. If `y` is 3-D with
     |        the shape (n0, n1, n2) and axis=2, then `deriv_value` must be 2-D
     |        and have the shape (n0, n1).
     |  extrapolate : {bool, 'periodic', None}, optional
     |      If bool, determines whether to extrapolate to out-of-bounds points
     |      based on first and last intervals, or to return NaNs. If 'periodic',
     |      periodic extrapolation is used. If None (default), ``extrapolate`` is
     |      set to 'periodic' for ``bc_type='periodic'`` and to True otherwise.
     |
     |  Attributes
     |  ----------
     |  x : ndarray, shape (n,)
     |      Breakpoints. The same ``x`` which was passed to the constructor.
     |  c : ndarray, shape (4, n-1, ...)
     |      Coefficients of the polynomials on each segment. The trailing
     |      dimensions match the dimensions of `y`, excluding ``axis``.
     |      For example, if `y` is 1-d, then ``c[k, i]`` is a coefficient for
     |      ``(x-x[i])**(3-k)`` on the segment between ``x[i]`` and ``x[i+1]``.
     |  axis : int
     |      Interpolation axis. The same axis which was passed to the
     |      constructor.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  integrate
     |  roots
     |
     |  See Also
     |  --------
     |  Akima1DInterpolator : Akima 1D interpolator.
     |  PchipInterpolator : PCHIP 1-D monotonic cubic interpolator.
     |  PPoly : Piecewise polynomial in terms of coefficients and breakpoints.
     |
     |  Notes
     |  -----
     |  Parameters `bc_type` and ``extrapolate`` work independently, i.e. the
     |  former controls only construction of a spline, and the latter only
     |  evaluation.
     |
     |  When a boundary condition is 'not-a-knot' and n = 2, it is replaced by
     |  a condition that the first derivative is equal to the linear interpolant
     |  slope. When both boundary conditions are 'not-a-knot' and n = 3, the
     |  solution is sought as a parabola passing through given points.
     |
     |  When 'not-a-knot' boundary conditions is applied to both ends, the
     |  resulting spline will be the same as returned by `splrep` (with ``s=0``)
     |  and `InterpolatedUnivariateSpline`, but these two methods use a
     |  representation in B-spline basis.
     |
     |  .. versionadded:: 0.18.0
     |
     |  Examples
     |  --------
     |  In this example the cubic spline is used to interpolate a sampled sinusoid.
     |  You can see that the spline continuity property holds for the first and
     |  second derivatives and violates only for the third derivative.
     |
     |  >>> import numpy as np
     |  >>> from scipy.interpolate import CubicSpline
     |  >>> import matplotlib.pyplot as plt
     |  >>> x = np.arange(10)
     |  >>> y = np.sin(x)
     |  >>> cs = CubicSpline(x, y)
     |  >>> xs = np.arange(-0.5, 9.6, 0.1)
     |  >>> fig, ax = plt.subplots(figsize=(6.5, 4))
     |  >>> ax.plot(x, y, 'o', label='data')
     |  >>> ax.plot(xs, np.sin(xs), label='true')
     |  >>> ax.plot(xs, cs(xs), label="S")
     |  >>> ax.plot(xs, cs(xs, 1), label="S'")
     |  >>> ax.plot(xs, cs(xs, 2), label="S''")
     |  >>> ax.plot(xs, cs(xs, 3), label="S'''")
     |  >>> ax.set_xlim(-0.5, 9.5)
     |  >>> ax.legend(loc='lower left', ncol=2)
     |  >>> plt.show()
     |
     |  In the second example, the unit circle is interpolated with a spline. A
     |  periodic boundary condition is used. You can see that the first derivative
     |  values, ds/dx=0, ds/dy=1 at the periodic point (1, 0) are correctly
     |  computed. Note that a circle cannot be exactly represented by a cubic
     |  spline. To increase precision, more breakpoints would be required.
     |
     |  >>> theta = 2 * np.pi * np.linspace(0, 1, 5)
     |  >>> y = np.c_[np.cos(theta), np.sin(theta)]
     |  >>> cs = CubicSpline(theta, y, bc_type='periodic')
     |  >>> print("ds/dx={:.1f} ds/dy={:.1f}".format(cs(0, 1)[0], cs(0, 1)[1]))
     |  ds/dx=0.0 ds/dy=1.0
     |  >>> xs = 2 * np.pi * np.linspace(0, 1, 100)
     |  >>> fig, ax = plt.subplots(figsize=(6.5, 4))
     |  >>> ax.plot(y[:, 0], y[:, 1], 'o', label='data')
     |  >>> ax.plot(np.cos(xs), np.sin(xs), label='true')
     |  >>> ax.plot(cs(xs)[:, 0], cs(xs)[:, 1], label='spline')
     |  >>> ax.axes.set_aspect('equal')
     |  >>> ax.legend(loc='center')
     |  >>> plt.show()
     |
     |  The third example is the interpolation of a polynomial y = x**3 on the
     |  interval 0 <= x<= 1. A cubic spline can represent this function exactly.
     |  To achieve that we need to specify values and first derivatives at
     |  endpoints of the interval. Note that y' = 3 * x**2 and thus y'(0) = 0 and
     |  y'(1) = 3.
     |
     |  >>> cs = CubicSpline([0, 1], [0, 1], bc_type=((1, 0), (1, 3)))
     |  >>> x = np.linspace(0, 1)
     |  >>> np.allclose(x**3, cs(x))
     |  True
     |
     |  References
     |  ----------
     |  .. [1] `Cubic Spline Interpolation
     |          <https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation>`_
     |          on Wikiversity.
     |  .. [2] Carl de Boor, "A Practical Guide to Splines", Springer-Verlag, 1978.
     |
     |  Method resolution order:
     |      CubicSpline
     |      CubicHermiteSpline
     |      scipy.interpolate._interpolate.PPoly
     |      scipy.interpolate._interpolate._PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, axis=0, bc_type='not-a-knot', extrapolate=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k - n representing the derivative
     |          of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  roots(self, discontinuity=True, extrapolate=None)
     |      Find real roots of the piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      See Also
     |      --------
     |      PPoly.solve
     |
     |  solve(self, y=0.0, discontinuity=True, extrapolate=None)
     |      Find real solutions of the equation ``pp(x) == y``.
     |
     |      Parameters
     |      ----------
     |      y : float, optional
     |          Right-hand side. Default is zero.
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      Notes
     |      -----
     |      This routine works only on real-valued polynomials.
     |
     |      If the piecewise polynomial contains sections that are
     |      identically zero, the root list will contain the start point
     |      of the corresponding interval, followed by a ``nan`` value.
     |
     |      If the polynomial is discontinuous across a breakpoint, and
     |      there is a sign change across the breakpoint, this is reported
     |      if the `discont` parameter is True.
     |
     |      Examples
     |      --------
     |
     |      Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
     |      ``[-2, 1], [1, 2]``:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import PPoly
     |      >>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
     |      >>> pp.solve()
     |      array([-1.,  1.])
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  from_bernstein_basis(bp, extrapolate=None)
     |      Construct a piecewise polynomial in the power basis
     |      from a polynomial in Bernstein basis.
     |
     |      Parameters
     |      ----------
     |      bp : BPoly
     |          A Bernstein basis polynomial, as created by BPoly
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  from_spline(tck, extrapolate=None)
     |      Construct a piecewise polynomial from a spline
     |
     |      Parameters
     |      ----------
     |      tck
     |          A spline, as returned by `splrep` or a BSpline object.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Examples
     |      --------
     |      Construct an interpolating spline and convert it to a `PPoly` instance
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> x = np.linspace(0, 1, 11)
     |      >>> y = np.sin(2*np.pi*x)
     |      >>> tck = splrep(x, y, s=0)
     |      >>> p = PPoly.from_spline(tck)
     |      >>> isinstance(p, PPoly)
     |      True
     |
     |      Note that this function only supports 1D splines out of the box.
     |
     |      If the ``tck`` object represents a parametric spline (e.g. constructed
     |      by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
     |      over the dimensions manually.
     |
     |      >>> from scipy.interpolate import splprep, splev
     |      >>> t = np.linspace(0, 1, 11)
     |      >>> x = np.sin(2*np.pi*t)
     |      >>> y = np.cos(2*np.pi*t)
     |      >>> (t, c, k), u = splprep([x, y], s=0)
     |
     |      Note that ``c`` is a list of two arrays of length 11.
     |
     |      >>> unew = np.arange(0, 1.01, 0.01)
     |      >>> out = splev(unew, (t, c, k))
     |
     |      To convert this spline to the power basis, we convert each
     |      component of the list of b-spline coefficients, ``c``, into the
     |      corresponding cubic polynomial.
     |
     |      >>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
     |      >>> polys[0].c.shape
     |      (4, 14)
     |
     |      Note that the coefficients of the polynomials `polys` are in the
     |      power basis and their dimensions reflect just that: here 4 is the order
     |      (degree+1), and 14 is the number of intervals---which is nothing but
     |      the length of the knot array of the original `tck` minus one.
     |
     |      Optionally, we can stack the components into a single `PPoly` along
     |      the third dimension:
     |
     |      >>> cc = np.dstack([p.c for p in polys])    # has shape = (4, 14, 2)
     |      >>> poly = PPoly(cc, polys[0].x)
     |      >>> np.allclose(poly(unew).T,     # note the transpose to match `splev`
     |      ...             out, atol=1e-15)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  extend(self, c, x)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class InterpolatedUnivariateSpline(UnivariateSpline)
     |  InterpolatedUnivariateSpline(x, y, w=None, bbox=[None, None], k=3, ext=0, check_finite=False)
     |
     |  1-D interpolating spline for a given set of data points.
     |
     |  Fits a spline y = spl(x) of degree `k` to the provided `x`, `y` data.
     |  Spline function passes through all provided points. Equivalent to
     |  `UnivariateSpline` with  `s` = 0.
     |
     |  Parameters
     |  ----------
     |  x : (N,) array_like
     |      Input dimension of data points -- must be strictly increasing
     |  y : (N,) array_like
     |      input dimension of data points
     |  w : (N,) array_like, optional
     |      Weights for spline fitting.  Must be positive.  If None (default),
     |      weights are all 1.
     |  bbox : (2,) array_like, optional
     |      2-sequence specifying the boundary of the approximation interval. If
     |      None (default), ``bbox=[x[0], x[-1]]``.
     |  k : int, optional
     |      Degree of the smoothing spline.  Must be ``1 <= k <= 5``. Default is
     |      ``k = 3``, a cubic spline.
     |  ext : int or str, optional
     |      Controls the extrapolation mode for elements
     |      not in the interval defined by the knot sequence.
     |
     |      * if ext=0 or 'extrapolate', return the extrapolated value.
     |      * if ext=1 or 'zeros', return 0
     |      * if ext=2 or 'raise', raise a ValueError
     |      * if ext=3 of 'const', return the boundary value.
     |
     |      The default value is 0.
     |
     |  check_finite : bool, optional
     |      Whether to check that the input arrays contain only finite numbers.
     |      Disabling may give a performance gain, but may result in problems
     |      (crashes, non-termination or non-sensical results) if the inputs
     |      do contain infinities or NaNs.
     |      Default is False.
     |
     |  See Also
     |  --------
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  LSQUnivariateSpline :
     |      a spline for which knots are user-selected
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  splrep :
     |      a function to find the B-spline representation of a 1-D curve
     |  splev :
     |      a function to evaluate a B-spline or its derivatives
     |  sproot :
     |      a function to find the roots of a cubic B-spline
     |  splint :
     |      a function to evaluate the definite integral of a B-spline between two
     |      given points
     |  spalde :
     |      a function to evaluate all derivatives of a B-spline
     |
     |  Notes
     |  -----
     |  The number of data points must be larger than the spline degree `k`.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.interpolate import InterpolatedUnivariateSpline
     |  >>> rng = np.random.default_rng()
     |  >>> x = np.linspace(-3, 3, 50)
     |  >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)
     |  >>> spl = InterpolatedUnivariateSpline(x, y)
     |  >>> plt.plot(x, y, 'ro', ms=5)
     |  >>> xs = np.linspace(-3, 3, 1000)
     |  >>> plt.plot(xs, spl(xs), 'g', lw=3, alpha=0.7)
     |  >>> plt.show()
     |
     |  Notice that the ``spl(x)`` interpolates `y`:
     |
     |  >>> spl.get_residual()
     |  0.0
     |
     |  Method resolution order:
     |      InterpolatedUnivariateSpline
     |      UnivariateSpline
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, w=None, bbox=[None, None], k=3, ext=0, check_finite=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from UnivariateSpline:
     |
     |  __call__(self, x, nu=0, ext=None)
     |      Evaluate spline (or its nu-th derivative) at positions x.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          A 1-D array of points at which to return the value of the smoothed
     |          spline or its derivatives. Note: `x` can be unordered but the
     |          evaluation is more efficient if `x` is (partially) ordered.
     |      nu  : int
     |          The order of derivative of the spline to compute.
     |      ext : int
     |          Controls the value returned for elements of `x` not in the
     |          interval defined by the knot sequence.
     |
     |          * if ext=0 or 'extrapolate', return the extrapolated value.
     |          * if ext=1 or 'zeros', return 0
     |          * if ext=2 or 'raise', raise a ValueError
     |          * if ext=3 or 'const', return the boundary value.
     |
     |          The default value is 0, passed from the initialization of
     |          UnivariateSpline.
     |
     |  antiderivative(self, n=1)
     |      Construct a new spline representing the antiderivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of antiderivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k+n representing the antiderivative of this
     |          spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      See Also
     |      --------
     |      splantider, derivative
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, np.pi/2, 70)
     |      >>> y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2)
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |
     |      The derivative is the inverse operation of the antiderivative,
     |      although some floating point error accumulates:
     |
     |      >>> spl(1.7), spl.antiderivative().derivative()(1.7)
     |      (array(2.1565429877197317), array(2.1565429877201865))
     |
     |      Antiderivative can be used to evaluate definite integrals:
     |
     |      >>> ispl = spl.antiderivative()
     |      >>> ispl(np.pi/2) - ispl(0)
     |      2.2572053588768486
     |
     |      This is indeed an approximation to the complete elliptic integral
     |      :math:`K(m) = \int_0^{\pi/2} [1 - m\sin^2 x]^{-1/2} dx`:
     |
     |      >>> from scipy.special import ellipk
     |      >>> ellipk(0.8)
     |      2.2572053268208538
     |
     |  derivative(self, n=1)
     |      Construct a new spline representing the derivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of derivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k-n representing the derivative of this
     |          spline.
     |
     |      See Also
     |      --------
     |      splder, antiderivative
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      Examples
     |      --------
     |      This can be used for finding maxima of a curve:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 10, 70)
     |      >>> y = np.sin(x)
     |      >>> spl = UnivariateSpline(x, y, k=4, s=0)
     |
     |      Now, differentiate the spline and find the zeros of the
     |      derivative. (NB: `sproot` only works for order 3 splines, so we
     |      fit an order 4 spline):
     |
     |      >>> spl.derivative().roots() / np.pi
     |      array([ 0.50000001,  1.5       ,  2.49999998])
     |
     |      This agrees well with roots :math:`\pi/2 + n\pi` of
     |      :math:`\cos(x) = \sin'(x)`.
     |
     |  derivatives(self, x)
     |      Return all derivatives of the spline at the point x.
     |
     |      Parameters
     |      ----------
     |      x : float
     |          The point to evaluate the derivatives at.
     |
     |      Returns
     |      -------
     |      der : ndarray, shape(k+1,)
     |          Derivatives of the orders 0 to k.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.derivatives(1.5)
     |      array([2.25, 3.0, 2.0, 0])
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return positions of interior knots of the spline.
     |
     |      Internally, the knot vector contains ``2*k`` additional boundary knots.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline approximation.
     |
     |      This is equivalent to::
     |
     |           sum((w[i] * (y[i]-spl(x[i])))**2, axis=0)
     |
     |  integral(self, a, b)
     |      Return definite integral of the spline between two given points.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower limit of integration.
     |      b : float
     |          Upper limit of integration.
     |
     |      Returns
     |      -------
     |      integral : float
     |          The value of the definite integral of the spline between limits.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.integral(0, 3)
     |      9.0
     |
     |      which agrees with :math:`\int x^2 dx = x^3 / 3` between the limits
     |      of 0 and 3.
     |
     |      A caveat is that this routine assumes the spline to be zero outside of
     |      the data limits:
     |
     |      >>> spl.integral(-1, 4)
     |      9.0
     |      >>> spl.integral(-1, 0)
     |      0.0
     |
     |  roots(self)
     |      Return the zeros of the spline.
     |
     |      Notes
     |      -----
     |      Restriction: only cubic splines are supported by FITPACK. For non-cubic
     |      splines, use `PPoly.root` (see below for an example).
     |
     |      Examples
     |      --------
     |
     |      For some data, this method may miss a root. This happens when one of
     |      the spline knots (which FITPACK places automatically) happens to
     |      coincide with the true root. A workaround is to convert to `PPoly`,
     |      which uses a different root-finding algorithm.
     |
     |      For example,
     |
     |      >>> x = [1.96, 1.97, 1.98, 1.99, 2.00, 2.01, 2.02, 2.03, 2.04, 2.05]
     |      >>> y = [-6.365470e-03, -4.790580e-03, -3.204320e-03, -1.607270e-03,
     |      ...      4.440892e-16,  1.616930e-03,  3.243000e-03,  4.877670e-03,
     |      ...      6.520430e-03,  8.170770e-03]
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |      >>> spl.roots()
     |      array([], dtype=float64)
     |
     |      Converting to a PPoly object does find the roots at `x=2`:
     |
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> tck = splrep(x, y, s=0)
     |      >>> ppoly = PPoly.from_spline(tck)
     |      >>> ppoly.roots(extrapolate=False)
     |      array([2.])
     |
     |      See Also
     |      --------
     |      sproot
     |      PPoly.roots
     |
     |  set_smoothing_factor(self, s)
     |      Continue spline computation with the given smoothing
     |      factor s and with the knots found at the last call.
     |
     |      This routine modifies the spline in place.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from UnivariateSpline:
     |
     |  validate_input(x, y, w, bbox, k, s, ext, check_finite)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from UnivariateSpline:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class KroghInterpolator(_Interpolator1DWithDerivatives)
     |  KroghInterpolator(xi, yi, axis=0)
     |
     |  Interpolating polynomial for a set of points.
     |
     |  The polynomial passes through all the pairs ``(xi, yi)``. One may
     |  additionally specify a number of derivatives at each point `xi`;
     |  this is done by repeating the value `xi` and specifying the
     |  derivatives as successive `yi` values.
     |
     |  Allows evaluation of the polynomial and all its derivatives.
     |  For reasons of numerical stability, this function does not compute
     |  the coefficients of the polynomial, although they can be obtained
     |  by evaluating all the derivatives.
     |
     |  Parameters
     |  ----------
     |  xi : array_like, shape (npoints, )
     |      Known x-coordinates. Must be sorted in increasing order.
     |  yi : array_like, shape (..., npoints, ...)
     |      Known y-coordinates. When an xi occurs two or more times in
     |      a row, the corresponding yi's represent derivative values. The length of `yi`
     |      along the interpolation axis must be equal to the length of `xi`. Use the
     |      `axis` parameter to select the correct axis.
     |  axis : int, optional
     |      Axis in the `yi` array corresponding to the x-coordinate values. Defaults to
     |      ``axis=0``.
     |
     |  Notes
     |  -----
     |  Be aware that the algorithms implemented here are not necessarily
     |  the most numerically stable known. Moreover, even in a world of
     |  exact computation, unless the x coordinates are chosen very
     |  carefully - Chebyshev zeros (e.g., cos(i*pi/n)) are a good choice -
     |  polynomial interpolation itself is a very ill-conditioned process
     |  due to the Runge phenomenon. In general, even with well-chosen
     |  x values, degrees higher than about thirty cause problems with
     |  numerical instability in this code.
     |
     |  Based on [1]_.
     |
     |  References
     |  ----------
     |  .. [1] Krogh, "Efficient Algorithms for Polynomial Interpolation
     |      and Numerical Differentiation", 1970.
     |
     |  Examples
     |  --------
     |  To produce a polynomial that is zero at 0 and 1 and has
     |  derivative 2 at 0, call
     |
     |  >>> from scipy.interpolate import KroghInterpolator
     |  >>> KroghInterpolator([0,0,1],[0,2,0])
     |
     |  This constructs the quadratic :math:`2x^2-2x`. The derivative condition
     |  is indicated by the repeated zero in the `xi` array; the corresponding
     |  yi values are 0, the function value, and 2, the derivative value.
     |
     |  For another example, given `xi`, `yi`, and a derivative `ypi` for each
     |  point, appropriate arrays can be constructed as:
     |
     |  >>> import numpy as np
     |  >>> rng = np.random.default_rng()
     |  >>> xi = np.linspace(0, 1, 5)
     |  >>> yi, ypi = rng.random((2, 5))
     |  >>> xi_k, yi_k = np.repeat(xi, 2), np.ravel(np.dstack((yi,ypi)))
     |  >>> KroghInterpolator(xi_k, yi_k)
     |
     |  To produce a vector-valued polynomial, supply a higher-dimensional
     |  array for `yi`:
     |
     |  >>> KroghInterpolator([0,1],[[2,3],[4,5]])
     |
     |  This constructs a linear polynomial giving (2,3) at 0 and (4,5) at 1.
     |
     |  Method resolution order:
     |      KroghInterpolator
     |      _Interpolator1DWithDerivatives
     |      _Interpolator1D
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, xi, yi, axis=0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _Interpolator1DWithDerivatives:
     |
     |  derivative(self, x, der=1)
     |      Evaluate a single derivative of the polynomial at the point `x`.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the derivatives
     |
     |      der : integer, optional
     |          Which derivative to evaluate (default: first derivative).
     |          This number includes the function value as 0th derivative.
     |
     |      Returns
     |      -------
     |      d : ndarray
     |          Derivative interpolated at the x-points. Shape of `d` is
     |          determined by replacing the interpolation axis in the
     |          original array with the shape of `x`.
     |
     |      Notes
     |      -----
     |      This may be computed by evaluating all derivatives up to the desired
     |      one (using self.derivatives()) and then discarding the rest.
     |
     |  derivatives(self, x, der=None)
     |      Evaluate several derivatives of the polynomial at the point `x`
     |
     |      Produce an array of derivatives evaluated at the point `x`.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the derivatives
     |      der : int or list or None, optional
     |          How many derivatives to evaluate, or None for all potentially
     |          nonzero derivatives (that is, a number equal to the number
     |          of points), or a list of derivatives to evaluate. This number
     |          includes the function value as the '0th' derivative.
     |
     |      Returns
     |      -------
     |      d : ndarray
     |          Array with derivatives; ``d[j]`` contains the jth derivative.
     |          Shape of ``d[j]`` is determined by replacing the interpolation
     |          axis in the original array with the shape of `x`.
     |
     |      Examples
     |      --------
     |      >>> from scipy.interpolate import KroghInterpolator
     |      >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives(0)
     |      array([1.0,2.0,3.0])
     |      >>> KroghInterpolator([0,0,0],[1,2,3]).derivatives([0,0])
     |      array([[1.0,1.0],
     |             [2.0,2.0],
     |             [3.0,3.0]])
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _Interpolator1DWithDerivatives:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _Interpolator1D:
     |
     |  __call__(self, x)
     |      Evaluate the interpolant
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the interpolant.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of `x`.
     |
     |      Notes
     |      -----
     |      Input values `x` must be convertible to `float` values like `int`
     |      or `float`.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _Interpolator1D:
     |
     |  dtype

    class LSQBivariateSpline(BivariateSpline)
     |  LSQBivariateSpline(x, y, z, tx, ty, w=None, bbox=[None, None, None, None], kx=3, ky=3, eps=None)
     |
     |  Weighted least-squares bivariate spline approximation.
     |
     |  Parameters
     |  ----------
     |  x, y, z : array_like
     |      1-D sequences of data points (order is not important).
     |  tx, ty : array_like
     |      Strictly ordered 1-D sequences of knots coordinates.
     |  w : array_like, optional
     |      Positive 1-D array of weights, of the same length as `x`, `y` and `z`.
     |  bbox : (4,) array_like, optional
     |      Sequence of length 4 specifying the boundary of the rectangular
     |      approximation domain.  By default,
     |      ``bbox=[min(x,tx),max(x,tx), min(y,ty),max(y,ty)]``.
     |  kx, ky : ints, optional
     |      Degrees of the bivariate spline. Default is 3.
     |  eps : float, optional
     |      A threshold for determining the effective rank of an over-determined
     |      linear system of equations. `eps` should have a value within the open
     |      interval ``(0, 1)``, the default is 1e-16.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |  The length of `x`, `y` and `z` should be at least ``(kx+1) * (ky+1)``.
     |
     |  If the input data is such that input dimensions have incommensurate
     |  units and differ by many orders of magnitude, the interpolant may have
     |  numerical artifacts. Consider rescaling the data before interpolating.
     |
     |  Method resolution order:
     |      LSQBivariateSpline
     |      BivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, z, tx, ty, w=None, bbox=[None, None, None, None], kx=3, ky=3, eps=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from BivariateSpline:
     |
     |  ev(self, xi, yi, dx=0, dy=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(xi[i], yi[i]),
     |      i=0,...,len(xi)-1``.
     |
     |      Parameters
     |      ----------
     |      xi, yi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int, optional
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int, optional
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |      >>> def f(x, y):
     |      ...     return np.exp(-np.sqrt((x / 2) ** 2 + y**2))
     |
     |      We sample the function on a coarse grid and set up the interpolator. Note that
     |      the default ``indexing="xy"`` of meshgrid would result in an unexpected
     |      (transposed) result after interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 21)
     |      >>> yarr = np.linspace(-3, 3, 21)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |      >>> zdata = f(xgrid, ygrid)
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |
     |      Next we sample the function along a diagonal slice through the coordinate space
     |      on a finer grid using interpolation.
     |
     |      >>> xinterp = np.linspace(-3, 3, 201)
     |      >>> yinterp = np.linspace(3, -3, 201)
     |      >>> zinterp = rbs.ev(xinterp, yinterp)
     |
     |      And check that the interpolation passes through the function evaluations as a
     |      function of the distance from the origin along the slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sqrt(xarr**2 + yarr**2), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sqrt(xinterp**2 + yinterp**2), zinterp, "-b")
     |      >>> plt.show()
     |
     |  integral(self, xa, xb, ya, yb)
     |      Evaluate the integral of the spline over area [xa,xb] x [ya,yb].
     |
     |      Parameters
     |      ----------
     |      xa, xb : float
     |          The end-points of the x integration interval.
     |      ya, yb : float
     |          The end-points of the y integration interval.
     |
     |      Returns
     |      -------
     |      integ : float
     |          The value of the resulting integral.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  __call__(self, x, y, dx=0, dy=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      x, y : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points ``(x[i],
     |          y[i]), i=0, ..., len(x)-1``.  Standard Numpy broadcasting
     |          is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays x, y. The arrays must be
     |          sorted to increasing order.
     |
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |
     |      We sample the function on a coarse grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 100)
     |      >>> yarr = np.linspace(-3, 3, 100)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |
     |      The function to interpolate decays faster along one axis than the other.
     |
     |      >>> zdata = np.exp(-np.sqrt((xgrid / 2) ** 2 + ygrid**2))
     |
     |      Next we sample on a finer grid using interpolation (kx=ky=1 for bilinear).
     |
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |      >>> xarr_fine = np.linspace(-3, 3, 200)
     |      >>> yarr_fine = np.linspace(-3, 3, 200)
     |      >>> xgrid_fine, ygrid_fine = np.meshgrid(xarr_fine, yarr_fine, indexing="ij")
     |      >>> zdata_interp = rbs(xgrid_fine, ygrid_fine, grid=False)
     |
     |      And check that the result agrees with the input by plotting both.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1, aspect="equal")
     |      >>> ax2 = fig.add_subplot(1, 2, 2, aspect="equal")
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_interp)
     |      >>> plt.show()
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class LSQSphereBivariateSpline(SphereBivariateSpline)
     |  LSQSphereBivariateSpline(theta, phi, r, tt, tp, w=None, eps=1e-16)
     |
     |  Weighted least-squares bivariate spline approximation in spherical
     |  coordinates.
     |
     |  Determines a smoothing bicubic spline according to a given
     |  set of knots in the `theta` and `phi` directions.
     |
     |  .. versionadded:: 0.11.0
     |
     |  Parameters
     |  ----------
     |  theta, phi, r : array_like
     |      1-D sequences of data points (order is not important). Coordinates
     |      must be given in radians. Theta must lie within the interval
     |      ``[0, pi]``, and phi must lie within the interval ``[0, 2pi]``.
     |  tt, tp : array_like
     |      Strictly ordered 1-D sequences of knots coordinates.
     |      Coordinates must satisfy ``0 < tt[i] < pi``, ``0 < tp[i] < 2*pi``.
     |  w : array_like, optional
     |      Positive 1-D sequence of weights, of the same length as `theta`, `phi`
     |      and `r`.
     |  eps : float, optional
     |      A threshold for determining the effective rank of an over-determined
     |      linear system of equations. `eps` should have a value within the
     |      open interval ``(0, 1)``, the default is 1e-16.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |  For more information, see the FITPACK_ site about this function.
     |
     |  .. _FITPACK: http://www.netlib.org/dierckx/sphere.f
     |
     |  Examples
     |  --------
     |  Suppose we have global data on a coarse grid (the input data does not
     |  have to be on a grid):
     |
     |  >>> from scipy.interpolate import LSQSphereBivariateSpline
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |
     |  >>> theta = np.linspace(0, np.pi, num=7)
     |  >>> phi = np.linspace(0, 2*np.pi, num=9)
     |  >>> data = np.empty((theta.shape[0], phi.shape[0]))
     |  >>> data[:,0], data[0,:], data[-1,:] = 0., 0., 0.
     |  >>> data[1:-1,1], data[1:-1,-1] = 1., 1.
     |  >>> data[1,1:-1], data[-2,1:-1] = 1., 1.
     |  >>> data[2:-2,2], data[2:-2,-2] = 2., 2.
     |  >>> data[2,2:-2], data[-3,2:-2] = 2., 2.
     |  >>> data[3,3:-2] = 3.
     |  >>> data = np.roll(data, 4, 1)
     |
     |  We need to set up the interpolator object. Here, we must also specify the
     |  coordinates of the knots to use.
     |
     |  >>> lats, lons = np.meshgrid(theta, phi)
     |  >>> knotst, knotsp = theta.copy(), phi.copy()
     |  >>> knotst[0] += .0001
     |  >>> knotst[-1] -= .0001
     |  >>> knotsp[0] += .0001
     |  >>> knotsp[-1] -= .0001
     |  >>> lut = LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
     |  ...                                data.T.ravel(), knotst, knotsp)
     |
     |  As a first test, we'll see what the algorithm returns when run on the
     |  input coordinates
     |
     |  >>> data_orig = lut(theta, phi)
     |
     |  Finally we interpolate the data to a finer grid
     |
     |  >>> fine_lats = np.linspace(0., np.pi, 70)
     |  >>> fine_lons = np.linspace(0., 2*np.pi, 90)
     |  >>> data_lsq = lut(fine_lats, fine_lons)
     |
     |  >>> fig = plt.figure()
     |  >>> ax1 = fig.add_subplot(131)
     |  >>> ax1.imshow(data, interpolation='nearest')
     |  >>> ax2 = fig.add_subplot(132)
     |  >>> ax2.imshow(data_orig, interpolation='nearest')
     |  >>> ax3 = fig.add_subplot(133)
     |  >>> ax3.imshow(data_lsq, interpolation='nearest')
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      LSQSphereBivariateSpline
     |      SphereBivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __call__(self, theta, phi, dtheta=0, dphi=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points
     |          ``(theta[i], phi[i]), i=0, ..., len(x)-1``.  Standard
     |          Numpy broadcasting is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays theta, phi. The arrays
     |          must be sorted to increasing order.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      on a finer grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetaarr_fine = np.linspace(0, np.pi, 200)
     |      >>> phiarr_fine = np.linspace(0, 2 * np.pi, 200)
     |      >>> zdata_fine = rsbs(thetaarr_fine, phiarr_fine)
     |
     |      Finally we plot the coarsly-sampled input data alongside the
     |      finely-sampled interpolated data to check that they agree.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1)
     |      >>> ax2 = fig.add_subplot(1, 2, 2)
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_fine)
     |      >>> plt.show()
     |
     |  __init__(self, theta, phi, r, tt, tp, w=None, eps=1e-16)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SphereBivariateSpline:
     |
     |  ev(self, theta, phi, dtheta=0, dphi=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(theta[i], phi[i]),
     |      i=0,...,len(theta)-1``.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          np.meshgrid(..., indexing="ij") and inconsistent with the
     |          default ordering np.meshgrid(..., indexing="xy").
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int, optional
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      at points not on the original grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetainterp = np.linspace(thetaarr[0], thetaarr[-1], 200)
     |      >>> phiinterp = np.linspace(phiarr[0], phiarr[-1], 200)
     |      >>> zinterp = rsbs.ev(thetainterp, phiinterp)
     |
     |      Finally we plot the original data for a diagonal slice through the
     |      initial grid, and the spline approximation along the same slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sin(thetaarr) * np.sin(phiarr), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sin(thetainterp) * np.sin(phiinterp), zinterp, "-b")
     |      >>> plt.show()
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class LSQUnivariateSpline(UnivariateSpline)
     |  LSQUnivariateSpline(x, y, t, w=None, bbox=[None, None], k=3, ext=0, check_finite=False)
     |
     |  1-D spline with explicit internal knots.
     |
     |  Fits a spline y = spl(x) of degree `k` to the provided `x`, `y` data.  `t`
     |  specifies the internal knots of the spline
     |
     |  Parameters
     |  ----------
     |  x : (N,) array_like
     |      Input dimension of data points -- must be increasing
     |  y : (N,) array_like
     |      Input dimension of data points
     |  t : (M,) array_like
     |      interior knots of the spline.  Must be in ascending order and::
     |
     |          bbox[0] < t[0] < ... < t[-1] < bbox[-1]
     |
     |  w : (N,) array_like, optional
     |      weights for spline fitting. Must be positive. If None (default),
     |      weights are all 1.
     |  bbox : (2,) array_like, optional
     |      2-sequence specifying the boundary of the approximation interval. If
     |      None (default), ``bbox = [x[0], x[-1]]``.
     |  k : int, optional
     |      Degree of the smoothing spline.  Must be 1 <= `k` <= 5.
     |      Default is `k` = 3, a cubic spline.
     |  ext : int or str, optional
     |      Controls the extrapolation mode for elements
     |      not in the interval defined by the knot sequence.
     |
     |      * if ext=0 or 'extrapolate', return the extrapolated value.
     |      * if ext=1 or 'zeros', return 0
     |      * if ext=2 or 'raise', raise a ValueError
     |      * if ext=3 of 'const', return the boundary value.
     |
     |      The default value is 0.
     |
     |  check_finite : bool, optional
     |      Whether to check that the input arrays contain only finite numbers.
     |      Disabling may give a performance gain, but may result in problems
     |      (crashes, non-termination or non-sensical results) if the inputs
     |      do contain infinities or NaNs.
     |      Default is False.
     |
     |  Raises
     |  ------
     |  ValueError
     |      If the interior knots do not satisfy the Schoenberg-Whitney conditions
     |
     |  See Also
     |  --------
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  InterpolatedUnivariateSpline :
     |      a interpolating univariate spline for a given set of data points.
     |  splrep :
     |      a function to find the B-spline representation of a 1-D curve
     |  splev :
     |      a function to evaluate a B-spline or its derivatives
     |  sproot :
     |      a function to find the roots of a cubic B-spline
     |  splint :
     |      a function to evaluate the definite integral of a B-spline between two
     |      given points
     |  spalde :
     |      a function to evaluate all derivatives of a B-spline
     |
     |  Notes
     |  -----
     |  The number of data points must be larger than the spline degree `k`.
     |
     |  Knots `t` must satisfy the Schoenberg-Whitney conditions,
     |  i.e., there must be a subset of data points ``x[j]`` such that
     |  ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.interpolate import LSQUnivariateSpline, UnivariateSpline
     |  >>> import matplotlib.pyplot as plt
     |  >>> rng = np.random.default_rng()
     |  >>> x = np.linspace(-3, 3, 50)
     |  >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)
     |
     |  Fit a smoothing spline with a pre-defined internal knots:
     |
     |  >>> t = [-1, 0, 1]
     |  >>> spl = LSQUnivariateSpline(x, y, t)
     |
     |  >>> xs = np.linspace(-3, 3, 1000)
     |  >>> plt.plot(x, y, 'ro', ms=5)
     |  >>> plt.plot(xs, spl(xs), 'g-', lw=3)
     |  >>> plt.show()
     |
     |  Check the knot vector:
     |
     |  >>> spl.get_knots()
     |  array([-3., -1., 0., 1., 3.])
     |
     |  Constructing lsq spline using the knots from another spline:
     |
     |  >>> x = np.arange(10)
     |  >>> s = UnivariateSpline(x, x, s=0)
     |  >>> s.get_knots()
     |  array([ 0.,  2.,  3.,  4.,  5.,  6.,  7.,  9.])
     |  >>> knt = s.get_knots()
     |  >>> s1 = LSQUnivariateSpline(x, x, knt[1:-1])    # Chop 1st and last knot
     |  >>> s1.get_knots()
     |  array([ 0.,  2.,  3.,  4.,  5.,  6.,  7.,  9.])
     |
     |  Method resolution order:
     |      LSQUnivariateSpline
     |      UnivariateSpline
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, t, w=None, bbox=[None, None], k=3, ext=0, check_finite=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from UnivariateSpline:
     |
     |  __call__(self, x, nu=0, ext=None)
     |      Evaluate spline (or its nu-th derivative) at positions x.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          A 1-D array of points at which to return the value of the smoothed
     |          spline or its derivatives. Note: `x` can be unordered but the
     |          evaluation is more efficient if `x` is (partially) ordered.
     |      nu  : int
     |          The order of derivative of the spline to compute.
     |      ext : int
     |          Controls the value returned for elements of `x` not in the
     |          interval defined by the knot sequence.
     |
     |          * if ext=0 or 'extrapolate', return the extrapolated value.
     |          * if ext=1 or 'zeros', return 0
     |          * if ext=2 or 'raise', raise a ValueError
     |          * if ext=3 or 'const', return the boundary value.
     |
     |          The default value is 0, passed from the initialization of
     |          UnivariateSpline.
     |
     |  antiderivative(self, n=1)
     |      Construct a new spline representing the antiderivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of antiderivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k+n representing the antiderivative of this
     |          spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      See Also
     |      --------
     |      splantider, derivative
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, np.pi/2, 70)
     |      >>> y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2)
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |
     |      The derivative is the inverse operation of the antiderivative,
     |      although some floating point error accumulates:
     |
     |      >>> spl(1.7), spl.antiderivative().derivative()(1.7)
     |      (array(2.1565429877197317), array(2.1565429877201865))
     |
     |      Antiderivative can be used to evaluate definite integrals:
     |
     |      >>> ispl = spl.antiderivative()
     |      >>> ispl(np.pi/2) - ispl(0)
     |      2.2572053588768486
     |
     |      This is indeed an approximation to the complete elliptic integral
     |      :math:`K(m) = \int_0^{\pi/2} [1 - m\sin^2 x]^{-1/2} dx`:
     |
     |      >>> from scipy.special import ellipk
     |      >>> ellipk(0.8)
     |      2.2572053268208538
     |
     |  derivative(self, n=1)
     |      Construct a new spline representing the derivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of derivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k-n representing the derivative of this
     |          spline.
     |
     |      See Also
     |      --------
     |      splder, antiderivative
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      Examples
     |      --------
     |      This can be used for finding maxima of a curve:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 10, 70)
     |      >>> y = np.sin(x)
     |      >>> spl = UnivariateSpline(x, y, k=4, s=0)
     |
     |      Now, differentiate the spline and find the zeros of the
     |      derivative. (NB: `sproot` only works for order 3 splines, so we
     |      fit an order 4 spline):
     |
     |      >>> spl.derivative().roots() / np.pi
     |      array([ 0.50000001,  1.5       ,  2.49999998])
     |
     |      This agrees well with roots :math:`\pi/2 + n\pi` of
     |      :math:`\cos(x) = \sin'(x)`.
     |
     |  derivatives(self, x)
     |      Return all derivatives of the spline at the point x.
     |
     |      Parameters
     |      ----------
     |      x : float
     |          The point to evaluate the derivatives at.
     |
     |      Returns
     |      -------
     |      der : ndarray, shape(k+1,)
     |          Derivatives of the orders 0 to k.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.derivatives(1.5)
     |      array([2.25, 3.0, 2.0, 0])
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return positions of interior knots of the spline.
     |
     |      Internally, the knot vector contains ``2*k`` additional boundary knots.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline approximation.
     |
     |      This is equivalent to::
     |
     |           sum((w[i] * (y[i]-spl(x[i])))**2, axis=0)
     |
     |  integral(self, a, b)
     |      Return definite integral of the spline between two given points.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower limit of integration.
     |      b : float
     |          Upper limit of integration.
     |
     |      Returns
     |      -------
     |      integral : float
     |          The value of the definite integral of the spline between limits.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.integral(0, 3)
     |      9.0
     |
     |      which agrees with :math:`\int x^2 dx = x^3 / 3` between the limits
     |      of 0 and 3.
     |
     |      A caveat is that this routine assumes the spline to be zero outside of
     |      the data limits:
     |
     |      >>> spl.integral(-1, 4)
     |      9.0
     |      >>> spl.integral(-1, 0)
     |      0.0
     |
     |  roots(self)
     |      Return the zeros of the spline.
     |
     |      Notes
     |      -----
     |      Restriction: only cubic splines are supported by FITPACK. For non-cubic
     |      splines, use `PPoly.root` (see below for an example).
     |
     |      Examples
     |      --------
     |
     |      For some data, this method may miss a root. This happens when one of
     |      the spline knots (which FITPACK places automatically) happens to
     |      coincide with the true root. A workaround is to convert to `PPoly`,
     |      which uses a different root-finding algorithm.
     |
     |      For example,
     |
     |      >>> x = [1.96, 1.97, 1.98, 1.99, 2.00, 2.01, 2.02, 2.03, 2.04, 2.05]
     |      >>> y = [-6.365470e-03, -4.790580e-03, -3.204320e-03, -1.607270e-03,
     |      ...      4.440892e-16,  1.616930e-03,  3.243000e-03,  4.877670e-03,
     |      ...      6.520430e-03,  8.170770e-03]
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |      >>> spl.roots()
     |      array([], dtype=float64)
     |
     |      Converting to a PPoly object does find the roots at `x=2`:
     |
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> tck = splrep(x, y, s=0)
     |      >>> ppoly = PPoly.from_spline(tck)
     |      >>> ppoly.roots(extrapolate=False)
     |      array([2.])
     |
     |      See Also
     |      --------
     |      sproot
     |      PPoly.roots
     |
     |  set_smoothing_factor(self, s)
     |      Continue spline computation with the given smoothing
     |      factor s and with the knots found at the last call.
     |
     |      This routine modifies the spline in place.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from UnivariateSpline:
     |
     |  validate_input(x, y, w, bbox, k, s, ext, check_finite)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from UnivariateSpline:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class LinearNDInterpolator(NDInterpolatorBase)
     |  LinearNDInterpolator(points, values, fill_value=nan, rescale=False)
     |
     |  LinearNDInterpolator(points, values, fill_value=np.nan, rescale=False)
     |
     |  Piecewise linear interpolator in N > 1 dimensions.
     |
     |  .. versionadded:: 0.9
     |
     |  Methods
     |  -------
     |  __call__
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndims); or Delaunay
     |      2-D array of data point coordinates, or a precomputed Delaunay triangulation.
     |  values : ndarray of float or complex, shape (npoints, ...), optional
     |      N-D array of data values at `points`.  The length of `values` along the
     |      first axis must be equal to the length of `points`. Unlike some
     |      interpolators, the interpolation axis cannot be changed.
     |  fill_value : float, optional
     |      Value used to fill in for requested points outside of the
     |      convex hull of the input points.  If not provided, then
     |      the default is ``nan``.
     |  rescale : bool, optional
     |      Rescale points to unit cube before performing interpolation.
     |      This is useful if some of the input dimensions have
     |      incommensurable units and differ by many orders of magnitude.
     |
     |  Notes
     |  -----
     |  The interpolant is constructed by triangulating the input data
     |  with Qhull [1]_, and on each triangle performing linear
     |  barycentric interpolation.
     |
     |  .. note:: For data on a regular grid use `interpn` instead.
     |
     |  Examples
     |  --------
     |  We can interpolate values on a 2D plane:
     |
     |  >>> from scipy.interpolate import LinearNDInterpolator
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> rng = np.random.default_rng()
     |  >>> x = rng.random(10) - 0.5
     |  >>> y = rng.random(10) - 0.5
     |  >>> z = np.hypot(x, y)
     |  >>> X = np.linspace(min(x), max(x))
     |  >>> Y = np.linspace(min(y), max(y))
     |  >>> X, Y = np.meshgrid(X, Y)  # 2D grid for interpolation
     |  >>> interp = LinearNDInterpolator(list(zip(x, y)), z)
     |  >>> Z = interp(X, Y)
     |  >>> plt.pcolormesh(X, Y, Z, shading='auto')
     |  >>> plt.plot(x, y, "ok", label="input point")
     |  >>> plt.legend()
     |  >>> plt.colorbar()
     |  >>> plt.axis("equal")
     |  >>> plt.show()
     |
     |  See also
     |  --------
     |  griddata :
     |      Interpolate unstructured D-D data.
     |  NearestNDInterpolator :
     |      Nearest-neighbor interpolator in N dimensions.
     |  CloughTocher2DInterpolator :
     |      Piecewise cubic, C1 smooth, curvature-minimizing interpolator in 2D.
     |  interpn : Interpolation on a regular grid or rectilinear grid.
     |  RegularGridInterpolator : Interpolator on a regular or rectilinear grid
     |                            in arbitrary dimensions (`interpn` wraps this
     |                            class).
     |
     |  References
     |  ----------
     |  .. [1] http://www.qhull.org/
     |
     |  Method resolution order:
     |      LinearNDInterpolator
     |      NDInterpolatorBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, points, values, fill_value=nan, rescale=False)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from NDInterpolatorBase:
     |
     |  __call__(self, *args)
     |      interpolator(xi)
     |
     |      Evaluate interpolator at given points.
     |
     |      Parameters
     |      ----------
     |      x1, x2, ... xn: array-like of float
     |          Points where to interpolate data at.
     |          x1, x2, ... xn can be array-like of float with broadcastable shape.
     |          or x1 can be array-like of float with shape ``(..., ndim)``
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NDInterpolatorBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class NdBSpline(builtins.object)
     |  NdBSpline(t, c, k, *, extrapolate=None)
     |
     |  Tensor product spline object.
     |
     |  The value at point ``xp = (x1, x2, ..., xN)`` is evaluated as a linear
     |  combination of products of one-dimensional b-splines in each of the ``N``
     |  dimensions::
     |
     |     c[i1, i2, ..., iN] * B(x1; i1, t1) * B(x2; i2, t2) * ... * B(xN; iN, tN)
     |
     |
     |  Here ``B(x; i, t)`` is the ``i``-th b-spline defined by the knot vector
     |  ``t`` evaluated at ``x``.
     |
     |  Parameters
     |  ----------
     |  t : tuple of 1D ndarrays
     |      knot vectors in directions 1, 2, ... N,
     |      ``len(t[i]) == n[i] + k + 1``
     |  c : ndarray, shape (n1, n2, ..., nN, ...)
     |      b-spline coefficients
     |  k : int or length-d tuple of integers
     |      spline degrees.
     |      A single integer is interpreted as having this degree for
     |      all dimensions.
     |  extrapolate : bool, optional
     |      Whether to extrapolate out-of-bounds inputs, or return `nan`.
     |      Default is to extrapolate.
     |
     |  Attributes
     |  ----------
     |  t : tuple of ndarrays
     |      Knots vectors.
     |  c : ndarray
     |      Coefficients of the tensor-produce spline.
     |  k : tuple of integers
     |      Degrees for each dimension.
     |  extrapolate : bool, optional
     |      Whether to extrapolate or return nans for out-of-bounds inputs.
     |      Defaults to true.
     |
     |  Methods
     |  -------
     |  __call__
     |  design_matrix
     |
     |  See Also
     |  --------
     |  BSpline : a one-dimensional B-spline object
     |  NdPPoly : an N-dimensional piecewise tensor product polynomial
     |
     |  Methods defined here:
     |
     |  __call__(self, xi, *, nu=None, extrapolate=None)
     |      Evaluate the tensor product b-spline at ``xi``.
     |
     |      Parameters
     |      ----------
     |      xi : array_like, shape(..., ndim)
     |          The coordinates to evaluate the interpolator at.
     |          This can be a list or tuple of ndim-dimensional points
     |          or an array with the shape (num_points, ndim).
     |      nu : array_like, optional, shape (ndim,)
     |          Orders of derivatives to evaluate. Each must be non-negative.
     |          Defaults to the zeroth derivivative.
     |      extrapolate : bool, optional
     |          Whether to exrapolate based on first and last intervals in each
     |          dimension, or return `nan`. Default is to ``self.extrapolate``.
     |
     |      Returns
     |      -------
     |      values : ndarray, shape ``xi.shape[:-1] + self.c.shape[ndim:]``
     |          Interpolated values at ``xi``
     |
     |  __init__(self, t, c, k, *, extrapolate=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  design_matrix(xvals, t, k, extrapolate=True)
     |      Construct the design matrix as a CSR format sparse array.
     |
     |      Parameters
     |      ----------
     |      xvals :  ndarray, shape(npts, ndim)
     |          Data points. ``xvals[j, :]`` gives the ``j``-th data point as an
     |          ``ndim``-dimensional array.
     |      t : tuple of 1D ndarrays, length-ndim
     |          Knot vectors in directions 1, 2, ... ndim,
     |      k : int
     |          B-spline degree.
     |      extrapolate : bool, optional
     |          Whether to extrapolate out-of-bounds values of raise a `ValueError`
     |
     |      Returns
     |      -------
     |      design_matrix : a CSR array
     |          Each row of the design matrix corresponds to a value in `xvals` and
     |          contains values of b-spline basis elements which are non-zero
     |          at this value.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class NdPPoly(builtins.object)
     |  NdPPoly(c, x, extrapolate=None)
     |
     |  Piecewise tensor product polynomial
     |
     |  The value at point ``xp = (x', y', z', ...)`` is evaluated by first
     |  computing the interval indices `i` such that::
     |
     |      x[0][i[0]] <= x' < x[0][i[0]+1]
     |      x[1][i[1]] <= y' < x[1][i[1]+1]
     |      ...
     |
     |  and then computing::
     |
     |      S = sum(c[k0-m0-1,...,kn-mn-1,i[0],...,i[n]]
     |              * (xp[0] - x[0][i[0]])**m0
     |              * ...
     |              * (xp[n] - x[n][i[n]])**mn
     |              for m0 in range(k[0]+1)
     |              ...
     |              for mn in range(k[n]+1))
     |
     |  where ``k[j]`` is the degree of the polynomial in dimension j. This
     |  representation is the piecewise multivariate power basis.
     |
     |  Parameters
     |  ----------
     |  c : ndarray, shape (k0, ..., kn, m0, ..., mn, ...)
     |      Polynomial coefficients, with polynomial order `kj` and
     |      `mj+1` intervals for each dimension `j`.
     |  x : ndim-tuple of ndarrays, shapes (mj+1,)
     |      Polynomial breakpoints for each dimension. These must be
     |      sorted in increasing order.
     |  extrapolate : bool, optional
     |      Whether to extrapolate to out-of-bounds points based on first
     |      and last intervals, or to return NaNs. Default: True.
     |
     |  Attributes
     |  ----------
     |  x : tuple of ndarrays
     |      Breakpoints.
     |  c : ndarray
     |      Coefficients of the polynomials.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  integrate
     |  integrate_1d
     |  construct_fast
     |
     |  See also
     |  --------
     |  PPoly : piecewise polynomials in 1D
     |
     |  Notes
     |  -----
     |  High-order polynomials in the power basis can be numerically
     |  unstable.
     |
     |  Methods defined here:
     |
     |  __call__(self, x, nu=None, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative
     |
     |      Parameters
     |      ----------
     |      x : array-like
     |          Points to evaluate the interpolant at.
     |      nu : tuple, optional
     |          Orders of derivatives to evaluate. Each must be non-negative.
     |      extrapolate : bool, optional
     |          Whether to extrapolate to out-of-bounds points based on first
     |          and last intervals, or to return NaNs.
     |
     |      Returns
     |      -------
     |      y : array-like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  __init__(self, c, x, extrapolate=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  antiderivative(self, nu)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : ndim-tuple of int
     |          Order of derivatives to evaluate for each dimension.
     |          If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |  derivative(self, nu)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : ndim-tuple of int
     |          Order of derivatives to evaluate for each dimension.
     |          If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : NdPPoly
     |          Piecewise polynomial of orders (k[0] - nu[0], ..., k[n] - nu[n])
     |          representing the derivative of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals in each dimension are
     |      considered half-open, ``[a, b)``, except for the last interval
     |      which is closed ``[a, b]``.
     |
     |  integrate(self, ranges, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      ranges : ndim-tuple of 2-tuples float
     |          Sequence of lower and upper bounds for each dimension,
     |          ``[(a[0], b[0]), ..., (a[ndim-1], b[ndim-1])]``
     |      extrapolate : bool, optional
     |          Whether to extrapolate to out-of-bounds points based on first
     |          and last intervals, or to return NaNs.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over
     |          [a[0], b[0]] x ... x [a[ndim-1], b[ndim-1]]
     |
     |  integrate_1d(self, a, b, axis, extrapolate=None)
     |      Compute NdPPoly representation for one dimensional definite integral
     |
     |      The result is a piecewise polynomial representing the integral:
     |
     |      .. math::
     |
     |         p(y, z, ...) = \int_a^b dx\, p(x, y, z, ...)
     |
     |      where the dimension integrated over is specified with the
     |      `axis` parameter.
     |
     |      Parameters
     |      ----------
     |      a, b : float
     |          Lower and upper bound for integration.
     |      axis : int
     |          Dimension over which to compute the 1-D integrals
     |      extrapolate : bool, optional
     |          Whether to extrapolate to out-of-bounds points based on first
     |          and last intervals, or to return NaNs.
     |
     |      Returns
     |      -------
     |      ig : NdPPoly or array-like
     |          Definite integral of the piecewise polynomial over [a, b].
     |          If the polynomial was 1D, an array is returned,
     |          otherwise, an NdPPoly object.
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  construct_fast(c, x, extrapolate=None)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type.  The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class NearestNDInterpolator(scipy.interpolate.interpnd.NDInterpolatorBase)
     |  NearestNDInterpolator(x, y, rescale=False, tree_options=None)
     |
     |  NearestNDInterpolator(x, y).
     |
     |  Nearest-neighbor interpolator in N > 1 dimensions.
     |
     |  .. versionadded:: 0.9
     |
     |  Methods
     |  -------
     |  __call__
     |
     |  Parameters
     |  ----------
     |  x : (npoints, ndims) 2-D ndarray of floats
     |      Data point coordinates.
     |  y : (npoints, ) 1-D ndarray of float or complex
     |      Data values.
     |  rescale : boolean, optional
     |      Rescale points to unit cube before performing interpolation.
     |      This is useful if some of the input dimensions have
     |      incommensurable units and differ by many orders of magnitude.
     |
     |      .. versionadded:: 0.14.0
     |  tree_options : dict, optional
     |      Options passed to the underlying ``cKDTree``.
     |
     |      .. versionadded:: 0.17.0
     |
     |  See Also
     |  --------
     |  griddata :
     |      Interpolate unstructured D-D data.
     |  LinearNDInterpolator :
     |      Piecewise linear interpolator in N dimensions.
     |  CloughTocher2DInterpolator :
     |      Piecewise cubic, C1 smooth, curvature-minimizing interpolator in 2D.
     |  interpn : Interpolation on a regular grid or rectilinear grid.
     |  RegularGridInterpolator : Interpolator on a regular or rectilinear grid
     |                            in arbitrary dimensions (`interpn` wraps this
     |                            class).
     |
     |  Notes
     |  -----
     |  Uses ``scipy.spatial.cKDTree``
     |
     |  .. note:: For data on a regular grid use `interpn` instead.
     |
     |  Examples
     |  --------
     |  We can interpolate values on a 2D plane:
     |
     |  >>> from scipy.interpolate import NearestNDInterpolator
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> rng = np.random.default_rng()
     |  >>> x = rng.random(10) - 0.5
     |  >>> y = rng.random(10) - 0.5
     |  >>> z = np.hypot(x, y)
     |  >>> X = np.linspace(min(x), max(x))
     |  >>> Y = np.linspace(min(y), max(y))
     |  >>> X, Y = np.meshgrid(X, Y)  # 2D grid for interpolation
     |  >>> interp = NearestNDInterpolator(list(zip(x, y)), z)
     |  >>> Z = interp(X, Y)
     |  >>> plt.pcolormesh(X, Y, Z, shading='auto')
     |  >>> plt.plot(x, y, "ok", label="input point")
     |  >>> plt.legend()
     |  >>> plt.colorbar()
     |  >>> plt.axis("equal")
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      NearestNDInterpolator
     |      scipy.interpolate.interpnd.NDInterpolatorBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __call__(self, *args, **query_options)
     |      Evaluate interpolator at given points.
     |
     |      Parameters
     |      ----------
     |      x1, x2, ... xn : array-like of float
     |          Points where to interpolate data at.
     |          x1, x2, ... xn can be array-like of float with broadcastable shape.
     |          or x1 can be array-like of float with shape ``(..., ndim)``
     |      **query_options
     |          This allows ``eps``, ``p``, ``distance_upper_bound``, and ``workers``
     |          being passed to the cKDTree's query function to be explicitly set.
     |          See `scipy.spatial.cKDTree.query` for an overview of the different options.
     |
     |          .. versionadded:: 1.12.0
     |
     |  __init__(self, x, y, rescale=False, tree_options=None)
     |      Check shape of points and values arrays, and reshape values to
     |      (npoints, nvalues).  Ensure the `points` and values arrays are
     |      C-contiguous, and of correct type.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate.interpnd.NDInterpolatorBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class PPoly(_PPolyBase)
     |  PPoly(c, x, extrapolate=None, axis=0)
     |
     |  Piecewise polynomial in terms of coefficients and breakpoints
     |
     |  The polynomial between ``x[i]`` and ``x[i + 1]`` is written in the
     |  local power basis::
     |
     |      S = sum(c[m, i] * (xp - x[i])**(k-m) for m in range(k+1))
     |
     |  where ``k`` is the degree of the polynomial.
     |
     |  Parameters
     |  ----------
     |  c : ndarray, shape (k, m, ...)
     |      Polynomial coefficients, order `k` and `m` intervals.
     |  x : ndarray, shape (m+1,)
     |      Polynomial breakpoints. Must be sorted in either increasing or
     |      decreasing order.
     |  extrapolate : bool or 'periodic', optional
     |      If bool, determines whether to extrapolate to out-of-bounds points
     |      based on first and last intervals, or to return NaNs. If 'periodic',
     |      periodic extrapolation is used. Default is True.
     |  axis : int, optional
     |      Interpolation axis. Default is zero.
     |
     |  Attributes
     |  ----------
     |  x : ndarray
     |      Breakpoints.
     |  c : ndarray
     |      Coefficients of the polynomials. They are reshaped
     |      to a 3-D array with the last dimension representing
     |      the trailing dimensions of the original coefficient array.
     |  axis : int
     |      Interpolation axis.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  integrate
     |  solve
     |  roots
     |  extend
     |  from_spline
     |  from_bernstein_basis
     |  construct_fast
     |
     |  See also
     |  --------
     |  BPoly : piecewise polynomials in the Bernstein basis
     |
     |  Notes
     |  -----
     |  High-order polynomials in the power basis can be numerically
     |  unstable. Precision problems can start to appear for orders
     |  larger than 20-30.
     |
     |  Method resolution order:
     |      PPoly
     |      _PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k - n representing the derivative
     |          of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  roots(self, discontinuity=True, extrapolate=None)
     |      Find real roots of the piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      See Also
     |      --------
     |      PPoly.solve
     |
     |  solve(self, y=0.0, discontinuity=True, extrapolate=None)
     |      Find real solutions of the equation ``pp(x) == y``.
     |
     |      Parameters
     |      ----------
     |      y : float, optional
     |          Right-hand side. Default is zero.
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      Notes
     |      -----
     |      This routine works only on real-valued polynomials.
     |
     |      If the piecewise polynomial contains sections that are
     |      identically zero, the root list will contain the start point
     |      of the corresponding interval, followed by a ``nan`` value.
     |
     |      If the polynomial is discontinuous across a breakpoint, and
     |      there is a sign change across the breakpoint, this is reported
     |      if the `discont` parameter is True.
     |
     |      Examples
     |      --------
     |
     |      Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
     |      ``[-2, 1], [1, 2]``:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import PPoly
     |      >>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
     |      >>> pp.solve()
     |      array([-1.,  1.])
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  from_bernstein_basis(bp, extrapolate=None)
     |      Construct a piecewise polynomial in the power basis
     |      from a polynomial in Bernstein basis.
     |
     |      Parameters
     |      ----------
     |      bp : BPoly
     |          A Bernstein basis polynomial, as created by BPoly
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  from_spline(tck, extrapolate=None)
     |      Construct a piecewise polynomial from a spline
     |
     |      Parameters
     |      ----------
     |      tck
     |          A spline, as returned by `splrep` or a BSpline object.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Examples
     |      --------
     |      Construct an interpolating spline and convert it to a `PPoly` instance
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> x = np.linspace(0, 1, 11)
     |      >>> y = np.sin(2*np.pi*x)
     |      >>> tck = splrep(x, y, s=0)
     |      >>> p = PPoly.from_spline(tck)
     |      >>> isinstance(p, PPoly)
     |      True
     |
     |      Note that this function only supports 1D splines out of the box.
     |
     |      If the ``tck`` object represents a parametric spline (e.g. constructed
     |      by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
     |      over the dimensions manually.
     |
     |      >>> from scipy.interpolate import splprep, splev
     |      >>> t = np.linspace(0, 1, 11)
     |      >>> x = np.sin(2*np.pi*t)
     |      >>> y = np.cos(2*np.pi*t)
     |      >>> (t, c, k), u = splprep([x, y], s=0)
     |
     |      Note that ``c`` is a list of two arrays of length 11.
     |
     |      >>> unew = np.arange(0, 1.01, 0.01)
     |      >>> out = splev(unew, (t, c, k))
     |
     |      To convert this spline to the power basis, we convert each
     |      component of the list of b-spline coefficients, ``c``, into the
     |      corresponding cubic polynomial.
     |
     |      >>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
     |      >>> polys[0].c.shape
     |      (4, 14)
     |
     |      Note that the coefficients of the polynomials `polys` are in the
     |      power basis and their dimensions reflect just that: here 4 is the order
     |      (degree+1), and 14 is the number of intervals---which is nothing but
     |      the length of the knot array of the original `tck` minus one.
     |
     |      Optionally, we can stack the components into a single `PPoly` along
     |      the third dimension:
     |
     |      >>> cc = np.dstack([p.c for p in polys])    # has shape = (4, 14, 2)
     |      >>> poly = PPoly(cc, polys[0].x)
     |      >>> np.allclose(poly(unew).T,     # note the transpose to match `splev`
     |      ...             out, atol=1e-15)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  __init__(self, c, x, extrapolate=None, axis=0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  extend(self, c, x)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from _PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class PchipInterpolator(CubicHermiteSpline)
     |  PchipInterpolator(x, y, axis=0, extrapolate=None)
     |
     |  PCHIP 1-D monotonic cubic interpolation.
     |
     |  ``x`` and ``y`` are arrays of values used to approximate some function f,
     |  with ``y = f(x)``. The interpolant uses monotonic cubic splines
     |  to find the value of new points. (PCHIP stands for Piecewise Cubic
     |  Hermite Interpolating Polynomial).
     |
     |  Parameters
     |  ----------
     |  x : ndarray, shape (npoints, )
     |      A 1-D array of monotonically increasing real values. ``x`` cannot
     |      include duplicate values (otherwise f is overspecified)
     |  y : ndarray, shape (..., npoints, ...)
     |      A N-D array of real values. ``y``'s length along the interpolation
     |      axis must be equal to the length of ``x``. Use the ``axis``
     |      parameter to select the interpolation axis.
     |
     |      .. deprecated:: 1.13.0
     |          Complex data is deprecated and will raise an error in SciPy 1.15.0.
     |          If you are trying to use the real components of the passed array,
     |          use ``np.real`` on ``y``.
     |
     |  axis : int, optional
     |      Axis in the ``y`` array corresponding to the x-coordinate values. Defaults
     |      to ``axis=0``.
     |  extrapolate : bool, optional
     |      Whether to extrapolate to out-of-bounds points based on first
     |      and last intervals, or to return NaNs.
     |
     |  Methods
     |  -------
     |  __call__
     |  derivative
     |  antiderivative
     |  roots
     |
     |  See Also
     |  --------
     |  CubicHermiteSpline : Piecewise-cubic interpolator.
     |  Akima1DInterpolator : Akima 1D interpolator.
     |  CubicSpline : Cubic spline data interpolator.
     |  PPoly : Piecewise polynomial in terms of coefficients and breakpoints.
     |
     |  Notes
     |  -----
     |  The interpolator preserves monotonicity in the interpolation data and does
     |  not overshoot if the data is not smooth.
     |
     |  The first derivatives are guaranteed to be continuous, but the second
     |  derivatives may jump at :math:`x_k`.
     |
     |  Determines the derivatives at the points :math:`x_k`, :math:`f'_k`,
     |  by using PCHIP algorithm [1]_.
     |
     |  Let :math:`h_k = x_{k+1} - x_k`, and  :math:`d_k = (y_{k+1} - y_k) / h_k`
     |  are the slopes at internal points :math:`x_k`.
     |  If the signs of :math:`d_k` and :math:`d_{k-1}` are different or either of
     |  them equals zero, then :math:`f'_k = 0`. Otherwise, it is given by the
     |  weighted harmonic mean
     |
     |  .. math::
     |
     |      \frac{w_1 + w_2}{f'_k} = \frac{w_1}{d_{k-1}} + \frac{w_2}{d_k}
     |
     |  where :math:`w_1 = 2 h_k + h_{k-1}` and :math:`w_2 = h_k + 2 h_{k-1}`.
     |
     |  The end slopes are set using a one-sided scheme [2]_.
     |
     |
     |  References
     |  ----------
     |  .. [1] F. N. Fritsch and J. Butland,
     |         A method for constructing local
     |         monotone piecewise cubic interpolants,
     |         SIAM J. Sci. Comput., 5(2), 300-304 (1984).
     |         :doi:`10.1137/0905021`.
     |  .. [2] see, e.g., C. Moler, Numerical Computing with Matlab, 2004.
     |         :doi:`10.1137/1.9780898717952`
     |
     |  Method resolution order:
     |      PchipInterpolator
     |      CubicHermiteSpline
     |      scipy.interpolate._interpolate.PPoly
     |      scipy.interpolate._interpolate._PPolyBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, axis=0, extrapolate=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  antiderivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the antiderivative.
     |
     |      Antiderivative is also the indefinite integral of the function,
     |      and derivative is its inverse operation.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of antiderivative to evaluate. Default is 1, i.e., compute
     |          the first integral. If negative, the derivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k + n representing
     |          the antiderivative of this polynomial.
     |
     |      Notes
     |      -----
     |      The antiderivative returned by this function is continuous and
     |      continuously differentiable to order n-1, up to floating point
     |      rounding error.
     |
     |      If antiderivative is computed and ``self.extrapolate='periodic'``,
     |      it will be set to False for the returned instance. This is done because
     |      the antiderivative is no longer periodic and its correct evaluation
     |      outside of the initially given x interval is difficult.
     |
     |  derivative(self, nu=1)
     |      Construct a new piecewise polynomial representing the derivative.
     |
     |      Parameters
     |      ----------
     |      nu : int, optional
     |          Order of derivative to evaluate. Default is 1, i.e., compute the
     |          first derivative. If negative, the antiderivative is returned.
     |
     |      Returns
     |      -------
     |      pp : PPoly
     |          Piecewise polynomial of order k2 = k - n representing the derivative
     |          of this polynomial.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  integrate(self, a, b, extrapolate=None)
     |      Compute a definite integral over a piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower integration bound
     |      b : float
     |          Upper integration bound
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      ig : array_like
     |          Definite integral of the piecewise polynomial over [a, b]
     |
     |  roots(self, discontinuity=True, extrapolate=None)
     |      Find real roots of the piecewise polynomial.
     |
     |      Parameters
     |      ----------
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      See Also
     |      --------
     |      PPoly.solve
     |
     |  solve(self, y=0.0, discontinuity=True, extrapolate=None)
     |      Find real solutions of the equation ``pp(x) == y``.
     |
     |      Parameters
     |      ----------
     |      y : float, optional
     |          Right-hand side. Default is zero.
     |      discontinuity : bool, optional
     |          Whether to report sign changes across discontinuities at
     |          breakpoints as roots.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to return roots from the polynomial
     |          extrapolated based on first and last intervals, 'periodic' works
     |          the same as False. If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      roots : ndarray
     |          Roots of the polynomial(s).
     |
     |          If the PPoly object describes multiple polynomials, the
     |          return value is an object array whose each element is an
     |          ndarray containing the roots.
     |
     |      Notes
     |      -----
     |      This routine works only on real-valued polynomials.
     |
     |      If the piecewise polynomial contains sections that are
     |      identically zero, the root list will contain the start point
     |      of the corresponding interval, followed by a ``nan`` value.
     |
     |      If the polynomial is discontinuous across a breakpoint, and
     |      there is a sign change across the breakpoint, this is reported
     |      if the `discont` parameter is True.
     |
     |      Examples
     |      --------
     |
     |      Finding roots of ``[x**2 - 1, (x - 1)**2]`` defined on intervals
     |      ``[-2, 1], [1, 2]``:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import PPoly
     |      >>> pp = PPoly(np.array([[1, -4, 3], [1, 0, 0]]).T, [-2, 1, 2])
     |      >>> pp.solve()
     |      array([-1.,  1.])
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  from_bernstein_basis(bp, extrapolate=None)
     |      Construct a piecewise polynomial in the power basis
     |      from a polynomial in Bernstein basis.
     |
     |      Parameters
     |      ----------
     |      bp : BPoly
     |          A Bernstein basis polynomial, as created by BPoly
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |  from_spline(tck, extrapolate=None)
     |      Construct a piecewise polynomial from a spline
     |
     |      Parameters
     |      ----------
     |      tck
     |          A spline, as returned by `splrep` or a BSpline object.
     |      extrapolate : bool or 'periodic', optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used. Default is True.
     |
     |      Examples
     |      --------
     |      Construct an interpolating spline and convert it to a `PPoly` instance
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> x = np.linspace(0, 1, 11)
     |      >>> y = np.sin(2*np.pi*x)
     |      >>> tck = splrep(x, y, s=0)
     |      >>> p = PPoly.from_spline(tck)
     |      >>> isinstance(p, PPoly)
     |      True
     |
     |      Note that this function only supports 1D splines out of the box.
     |
     |      If the ``tck`` object represents a parametric spline (e.g. constructed
     |      by `splprep` or a `BSpline` with ``c.ndim > 1``), you will need to loop
     |      over the dimensions manually.
     |
     |      >>> from scipy.interpolate import splprep, splev
     |      >>> t = np.linspace(0, 1, 11)
     |      >>> x = np.sin(2*np.pi*t)
     |      >>> y = np.cos(2*np.pi*t)
     |      >>> (t, c, k), u = splprep([x, y], s=0)
     |
     |      Note that ``c`` is a list of two arrays of length 11.
     |
     |      >>> unew = np.arange(0, 1.01, 0.01)
     |      >>> out = splev(unew, (t, c, k))
     |
     |      To convert this spline to the power basis, we convert each
     |      component of the list of b-spline coefficients, ``c``, into the
     |      corresponding cubic polynomial.
     |
     |      >>> polys = [PPoly.from_spline((t, cj, k)) for cj in c]
     |      >>> polys[0].c.shape
     |      (4, 14)
     |
     |      Note that the coefficients of the polynomials `polys` are in the
     |      power basis and their dimensions reflect just that: here 4 is the order
     |      (degree+1), and 14 is the number of intervals---which is nothing but
     |      the length of the knot array of the original `tck` minus one.
     |
     |      Optionally, we can stack the components into a single `PPoly` along
     |      the third dimension:
     |
     |      >>> cc = np.dstack([p.c for p in polys])    # has shape = (4, 14, 2)
     |      >>> poly = PPoly(cc, polys[0].x)
     |      >>> np.allclose(poly(unew).T,     # note the transpose to match `splev`
     |      ...             out, atol=1e-15)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate.PPoly:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  __call__(self, x, nu=0, extrapolate=None)
     |      Evaluate the piecewise polynomial or its derivative.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Points to evaluate the interpolant at.
     |      nu : int, optional
     |          Order of derivative to evaluate. Must be non-negative.
     |      extrapolate : {bool, 'periodic', None}, optional
     |          If bool, determines whether to extrapolate to out-of-bounds points
     |          based on first and last intervals, or to return NaNs.
     |          If 'periodic', periodic extrapolation is used.
     |          If None (default), use `self.extrapolate`.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of x.
     |
     |      Notes
     |      -----
     |      Derivatives are evaluated piecewise for each polynomial
     |      segment, even if the polynomial is not differentiable at the
     |      breakpoints. The polynomial intervals are considered half-open,
     |      ``[a, b)``, except for the last interval which is closed
     |      ``[a, b]``.
     |
     |  extend(self, c, x)
     |      Add additional breakpoints and coefficients to the polynomial.
     |
     |      Parameters
     |      ----------
     |      c : ndarray, size (k, m, ...)
     |          Additional coefficients for polynomials in intervals. Note that
     |          the first additional interval will be formed using one of the
     |          ``self.x`` end points.
     |      x : ndarray, size (m,)
     |          Additional breakpoints. Must be sorted in the same order as
     |          ``self.x`` and either to the right or to the left of the current
     |          breakpoints.
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  construct_fast(c, x, extrapolate=None, axis=0)
     |      Construct the piecewise polynomial without making checks.
     |
     |      Takes the same parameters as the constructor. Input arguments
     |      ``c`` and ``x`` must be arrays of the correct shape and type. The
     |      ``c`` array can only be of dtypes float and complex, and ``x``
     |      array must have dtype float.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._interpolate._PPolyBase:
     |
     |  axis
     |
     |  c
     |
     |  extrapolate
     |
     |  x

    class RBFInterpolator(builtins.object)
     |  RBFInterpolator(y, d, neighbors=None, smoothing=0.0, kernel='thin_plate_spline', epsilon=None, degree=None)
     |
     |  Radial basis function (RBF) interpolation in N dimensions.
     |
     |  Parameters
     |  ----------
     |  y : (npoints, ndims) array_like
     |      2-D array of data point coordinates.
     |  d : (npoints, ...) array_like
     |      N-D array of data values at `y`. The length of `d` along the first
     |      axis must be equal to the length of `y`. Unlike some interpolators, the
     |      interpolation axis cannot be changed.
     |  neighbors : int, optional
     |      If specified, the value of the interpolant at each evaluation point
     |      will be computed using only this many nearest data points. All the data
     |      points are used by default.
     |  smoothing : float or (npoints, ) array_like, optional
     |      Smoothing parameter. The interpolant perfectly fits the data when this
     |      is set to 0. For large values, the interpolant approaches a least
     |      squares fit of a polynomial with the specified degree. Default is 0.
     |  kernel : str, optional
     |      Type of RBF. This should be one of
     |
     |          - 'linear'               : ``-r``
     |          - 'thin_plate_spline'    : ``r**2 * log(r)``
     |          - 'cubic'                : ``r**3``
     |          - 'quintic'              : ``-r**5``
     |          - 'multiquadric'         : ``-sqrt(1 + r**2)``
     |          - 'inverse_multiquadric' : ``1/sqrt(1 + r**2)``
     |          - 'inverse_quadratic'    : ``1/(1 + r**2)``
     |          - 'gaussian'             : ``exp(-r**2)``
     |
     |      Default is 'thin_plate_spline'.
     |  epsilon : float, optional
     |      Shape parameter that scales the input to the RBF. If `kernel` is
     |      'linear', 'thin_plate_spline', 'cubic', or 'quintic', this defaults to
     |      1 and can be ignored because it has the same effect as scaling the
     |      smoothing parameter. Otherwise, this must be specified.
     |  degree : int, optional
     |      Degree of the added polynomial. For some RBFs the interpolant may not
     |      be well-posed if the polynomial degree is too small. Those RBFs and
     |      their corresponding minimum degrees are
     |
     |          - 'multiquadric'      : 0
     |          - 'linear'            : 0
     |          - 'thin_plate_spline' : 1
     |          - 'cubic'             : 1
     |          - 'quintic'           : 2
     |
     |      The default value is the minimum degree for `kernel` or 0 if there is
     |      no minimum degree. Set this to -1 for no added polynomial.
     |
     |  Notes
     |  -----
     |  An RBF is a scalar valued function in N-dimensional space whose value at
     |  :math:`x` can be expressed in terms of :math:`r=||x - c||`, where :math:`c`
     |  is the center of the RBF.
     |
     |  An RBF interpolant for the vector of data values :math:`d`, which are from
     |  locations :math:`y`, is a linear combination of RBFs centered at :math:`y`
     |  plus a polynomial with a specified degree. The RBF interpolant is written
     |  as
     |
     |  .. math::
     |      f(x) = K(x, y) a + P(x) b,
     |
     |  where :math:`K(x, y)` is a matrix of RBFs with centers at :math:`y`
     |  evaluated at the points :math:`x`, and :math:`P(x)` is a matrix of
     |  monomials, which span polynomials with the specified degree, evaluated at
     |  :math:`x`. The coefficients :math:`a` and :math:`b` are the solution to the
     |  linear equations
     |
     |  .. math::
     |      (K(y, y) + \lambda I) a + P(y) b = d
     |
     |  and
     |
     |  .. math::
     |      P(y)^T a = 0,
     |
     |  where :math:`\lambda` is a non-negative smoothing parameter that controls
     |  how well we want to fit the data. The data are fit exactly when the
     |  smoothing parameter is 0.
     |
     |  The above system is uniquely solvable if the following requirements are
     |  met:
     |
     |      - :math:`P(y)` must have full column rank. :math:`P(y)` always has full
     |        column rank when `degree` is -1 or 0. When `degree` is 1,
     |        :math:`P(y)` has full column rank if the data point locations are not
     |        all collinear (N=2), coplanar (N=3), etc.
     |      - If `kernel` is 'multiquadric', 'linear', 'thin_plate_spline',
     |        'cubic', or 'quintic', then `degree` must not be lower than the
     |        minimum value listed above.
     |      - If `smoothing` is 0, then each data point location must be distinct.
     |
     |  When using an RBF that is not scale invariant ('multiquadric',
     |  'inverse_multiquadric', 'inverse_quadratic', or 'gaussian'), an appropriate
     |  shape parameter must be chosen (e.g., through cross validation). Smaller
     |  values for the shape parameter correspond to wider RBFs. The problem can
     |  become ill-conditioned or singular when the shape parameter is too small.
     |
     |  The memory required to solve for the RBF interpolation coefficients
     |  increases quadratically with the number of data points, which can become
     |  impractical when interpolating more than about a thousand data points.
     |  To overcome memory limitations for large interpolation problems, the
     |  `neighbors` argument can be specified to compute an RBF interpolant for
     |  each evaluation point using only the nearest data points.
     |
     |  .. versionadded:: 1.7.0
     |
     |  See Also
     |  --------
     |  NearestNDInterpolator
     |  LinearNDInterpolator
     |  CloughTocher2DInterpolator
     |
     |  References
     |  ----------
     |  .. [1] Fasshauer, G., 2007. Meshfree Approximation Methods with Matlab.
     |      World Scientific Publishing Co.
     |
     |  .. [2] http://amadeus.math.iit.edu/~fass/603_ch3.pdf
     |
     |  .. [3] Wahba, G., 1990. Spline Models for Observational Data. SIAM.
     |
     |  .. [4] http://pages.stat.wisc.edu/~wahba/stat860public/lect/lect8/lect8.pdf
     |
     |  Examples
     |  --------
     |  Demonstrate interpolating scattered data to a grid in 2-D.
     |
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.interpolate import RBFInterpolator
     |  >>> from scipy.stats.qmc import Halton
     |
     |  >>> rng = np.random.default_rng()
     |  >>> xobs = 2*Halton(2, seed=rng).random(100) - 1
     |  >>> yobs = np.sum(xobs, axis=1)*np.exp(-6*np.sum(xobs**2, axis=1))
     |
     |  >>> xgrid = np.mgrid[-1:1:50j, -1:1:50j]
     |  >>> xflat = xgrid.reshape(2, -1).T
     |  >>> yflat = RBFInterpolator(xobs, yobs)(xflat)
     |  >>> ygrid = yflat.reshape(50, 50)
     |
     |  >>> fig, ax = plt.subplots()
     |  >>> ax.pcolormesh(*xgrid, ygrid, vmin=-0.25, vmax=0.25, shading='gouraud')
     |  >>> p = ax.scatter(*xobs.T, c=yobs, s=50, ec='k', vmin=-0.25, vmax=0.25)
     |  >>> fig.colorbar(p)
     |  >>> plt.show()
     |
     |  Methods defined here:
     |
     |  __call__(self, x)
     |      Evaluate the interpolant at `x`.
     |
     |      Parameters
     |      ----------
     |      x : (Q, N) array_like
     |          Evaluation point coordinates.
     |
     |      Returns
     |      -------
     |      (Q, ...) ndarray
     |          Values of the interpolant at `x`.
     |
     |  __init__(self, y, d, neighbors=None, smoothing=0.0, kernel='thin_plate_spline', epsilon=None, degree=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class Rbf(builtins.object)
     |  Rbf(*args, **kwargs)
     |
     |  Rbf(*args, **kwargs)
     |
     |  A class for radial basis function interpolation of functions from
     |  N-D scattered data to an M-D domain.
     |
     |  .. legacy:: class
     |
     |      `Rbf` is legacy code, for new usage please use `RBFInterpolator`
     |      instead.
     |
     |  Parameters
     |  ----------
     |  *args : arrays
     |      x, y, z, ..., d, where x, y, z, ... are the coordinates of the nodes
     |      and d is the array of values at the nodes
     |  function : str or callable, optional
     |      The radial basis function, based on the radius, r, given by the norm
     |      (default is Euclidean distance); the default is 'multiquadric'::
     |
     |          'multiquadric': sqrt((r/self.epsilon)**2 + 1)
     |          'inverse': 1.0/sqrt((r/self.epsilon)**2 + 1)
     |          'gaussian': exp(-(r/self.epsilon)**2)
     |          'linear': r
     |          'cubic': r**3
     |          'quintic': r**5
     |          'thin_plate': r**2 * log(r)
     |
     |      If callable, then it must take 2 arguments (self, r). The epsilon
     |      parameter will be available as self.epsilon. Other keyword
     |      arguments passed in will be available as well.
     |
     |  epsilon : float, optional
     |      Adjustable constant for gaussian or multiquadrics functions
     |      - defaults to approximate average distance between nodes (which is
     |      a good start).
     |  smooth : float, optional
     |      Values greater than zero increase the smoothness of the
     |      approximation. 0 is for interpolation (default), the function will
     |      always go through the nodal points in this case.
     |  norm : str, callable, optional
     |      A function that returns the 'distance' between two points, with
     |      inputs as arrays of positions (x, y, z, ...), and an output as an
     |      array of distance. E.g., the default: 'euclidean', such that the result
     |      is a matrix of the distances from each point in ``x1`` to each point in
     |      ``x2``. For more options, see documentation of
     |      `scipy.spatial.distances.cdist`.
     |  mode : str, optional
     |      Mode of the interpolation, can be '1-D' (default) or 'N-D'. When it is
     |      '1-D' the data `d` will be considered as 1-D and flattened
     |      internally. When it is 'N-D' the data `d` is assumed to be an array of
     |      shape (n_samples, m), where m is the dimension of the target domain.
     |
     |
     |  Attributes
     |  ----------
     |  N : int
     |      The number of data points (as determined by the input arrays).
     |  di : ndarray
     |      The 1-D array of data values at each of the data coordinates `xi`.
     |  xi : ndarray
     |      The 2-D array of data coordinates.
     |  function : str or callable
     |      The radial basis function. See description under Parameters.
     |  epsilon : float
     |      Parameter used by gaussian or multiquadrics functions. See Parameters.
     |  smooth : float
     |      Smoothing parameter. See description under Parameters.
     |  norm : str or callable
     |      The distance function. See description under Parameters.
     |  mode : str
     |      Mode of the interpolation. See description under Parameters.
     |  nodes : ndarray
     |      A 1-D array of node values for the interpolation.
     |  A : internal property, do not use
     |
     |  See Also
     |  --------
     |  RBFInterpolator
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.interpolate import Rbf
     |  >>> rng = np.random.default_rng()
     |  >>> x, y, z, d = rng.random((4, 50))
     |  >>> rbfi = Rbf(x, y, z, d)  # radial basis function interpolator instance
     |  >>> xi = yi = zi = np.linspace(0, 1, 20)
     |  >>> di = rbfi(xi, yi, zi)   # interpolated values
     |  >>> di.shape
     |  (20,)
     |
     |  Methods defined here:
     |
     |  __call__(self, *args)
     |      Call self as a function.
     |
     |  __init__(self, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  A
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class RectBivariateSpline(BivariateSpline)
     |  RectBivariateSpline(x, y, z, bbox=[None, None, None, None], kx=3, ky=3, s=0)
     |
     |  Bivariate spline approximation over a rectangular mesh.
     |
     |  Can be used for both smoothing and interpolating data.
     |
     |  Parameters
     |  ----------
     |  x,y : array_like
     |      1-D arrays of coordinates in strictly ascending order.
     |      Evaluated points outside the data range will be extrapolated.
     |  z : array_like
     |      2-D array of data with shape (x.size,y.size).
     |  bbox : array_like, optional
     |      Sequence of length 4 specifying the boundary of the rectangular
     |      approximation domain, which means the start and end spline knots of
     |      each dimension are set by these values. By default,
     |      ``bbox=[min(x), max(x), min(y), max(y)]``.
     |  kx, ky : ints, optional
     |      Degrees of the bivariate spline. Default is 3.
     |  s : float, optional
     |      Positive smoothing factor defined for estimation condition:
     |      ``sum((z[i]-f(x[i], y[i]))**2, axis=0) <= s`` where f is a spline
     |      function. Default is ``s=0``, which is for interpolation.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |
     |  If the input data is such that input dimensions have incommensurate
     |  units and differ by many orders of magnitude, the interpolant may have
     |  numerical artifacts. Consider rescaling the data before interpolating.
     |
     |  Method resolution order:
     |      RectBivariateSpline
     |      BivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, z, bbox=[None, None, None, None], kx=3, ky=3, s=0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from BivariateSpline:
     |
     |  ev(self, xi, yi, dx=0, dy=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(xi[i], yi[i]),
     |      i=0,...,len(xi)-1``.
     |
     |      Parameters
     |      ----------
     |      xi, yi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int, optional
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int, optional
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |      >>> def f(x, y):
     |      ...     return np.exp(-np.sqrt((x / 2) ** 2 + y**2))
     |
     |      We sample the function on a coarse grid and set up the interpolator. Note that
     |      the default ``indexing="xy"`` of meshgrid would result in an unexpected
     |      (transposed) result after interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 21)
     |      >>> yarr = np.linspace(-3, 3, 21)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |      >>> zdata = f(xgrid, ygrid)
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |
     |      Next we sample the function along a diagonal slice through the coordinate space
     |      on a finer grid using interpolation.
     |
     |      >>> xinterp = np.linspace(-3, 3, 201)
     |      >>> yinterp = np.linspace(3, -3, 201)
     |      >>> zinterp = rbs.ev(xinterp, yinterp)
     |
     |      And check that the interpolation passes through the function evaluations as a
     |      function of the distance from the origin along the slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sqrt(xarr**2 + yarr**2), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sqrt(xinterp**2 + yinterp**2), zinterp, "-b")
     |      >>> plt.show()
     |
     |  integral(self, xa, xb, ya, yb)
     |      Evaluate the integral of the spline over area [xa,xb] x [ya,yb].
     |
     |      Parameters
     |      ----------
     |      xa, xb : float
     |          The end-points of the x integration interval.
     |      ya, yb : float
     |          The end-points of the y integration interval.
     |
     |      Returns
     |      -------
     |      integ : float
     |          The value of the resulting integral.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  __call__(self, x, y, dx=0, dy=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      x, y : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points ``(x[i],
     |          y[i]), i=0, ..., len(x)-1``.  Standard Numpy broadcasting
     |          is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays x, y. The arrays must be
     |          sorted to increasing order.
     |
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |
     |      We sample the function on a coarse grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 100)
     |      >>> yarr = np.linspace(-3, 3, 100)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |
     |      The function to interpolate decays faster along one axis than the other.
     |
     |      >>> zdata = np.exp(-np.sqrt((xgrid / 2) ** 2 + ygrid**2))
     |
     |      Next we sample on a finer grid using interpolation (kx=ky=1 for bilinear).
     |
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |      >>> xarr_fine = np.linspace(-3, 3, 200)
     |      >>> yarr_fine = np.linspace(-3, 3, 200)
     |      >>> xgrid_fine, ygrid_fine = np.meshgrid(xarr_fine, yarr_fine, indexing="ij")
     |      >>> zdata_interp = rbs(xgrid_fine, ygrid_fine, grid=False)
     |
     |      And check that the result agrees with the input by plotting both.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1, aspect="equal")
     |      >>> ax2 = fig.add_subplot(1, 2, 2, aspect="equal")
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_interp)
     |      >>> plt.show()
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class RectSphereBivariateSpline(SphereBivariateSpline)
     |  RectSphereBivariateSpline(u, v, r, s=0.0, pole_continuity=False, pole_values=None, pole_exact=False, pole_flat=False)
     |
     |  Bivariate spline approximation over a rectangular mesh on a sphere.
     |
     |  Can be used for smoothing data.
     |
     |  .. versionadded:: 0.11.0
     |
     |  Parameters
     |  ----------
     |  u : array_like
     |      1-D array of colatitude coordinates in strictly ascending order.
     |      Coordinates must be given in radians and lie within the open interval
     |      ``(0, pi)``.
     |  v : array_like
     |      1-D array of longitude coordinates in strictly ascending order.
     |      Coordinates must be given in radians. First element (``v[0]``) must lie
     |      within the interval ``[-pi, pi)``. Last element (``v[-1]``) must satisfy
     |      ``v[-1] <= v[0] + 2*pi``.
     |  r : array_like
     |      2-D array of data with shape ``(u.size, v.size)``.
     |  s : float, optional
     |      Positive smoothing factor defined for estimation condition
     |      (``s=0`` is for interpolation).
     |  pole_continuity : bool or (bool, bool), optional
     |      Order of continuity at the poles ``u=0`` (``pole_continuity[0]``) and
     |      ``u=pi`` (``pole_continuity[1]``).  The order of continuity at the pole
     |      will be 1 or 0 when this is True or False, respectively.
     |      Defaults to False.
     |  pole_values : float or (float, float), optional
     |      Data values at the poles ``u=0`` and ``u=pi``.  Either the whole
     |      parameter or each individual element can be None.  Defaults to None.
     |  pole_exact : bool or (bool, bool), optional
     |      Data value exactness at the poles ``u=0`` and ``u=pi``.  If True, the
     |      value is considered to be the right function value, and it will be
     |      fitted exactly. If False, the value will be considered to be a data
     |      value just like the other data values.  Defaults to False.
     |  pole_flat : bool or (bool, bool), optional
     |      For the poles at ``u=0`` and ``u=pi``, specify whether or not the
     |      approximation has vanishing derivatives.  Defaults to False.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |  Currently, only the smoothing spline approximation (``iopt[0] = 0`` and
     |  ``iopt[0] = 1`` in the FITPACK routine) is supported.  The exact
     |  least-squares spline approximation is not implemented yet.
     |
     |  When actually performing the interpolation, the requested `v` values must
     |  lie within the same length 2pi interval that the original `v` values were
     |  chosen from.
     |
     |  For more information, see the FITPACK_ site about this function.
     |
     |  .. _FITPACK: http://www.netlib.org/dierckx/spgrid.f
     |
     |  Examples
     |  --------
     |  Suppose we have global data on a coarse grid
     |
     |  >>> import numpy as np
     |  >>> lats = np.linspace(10, 170, 9) * np.pi / 180.
     |  >>> lons = np.linspace(0, 350, 18) * np.pi / 180.
     |  >>> data = np.dot(np.atleast_2d(90. - np.linspace(-80., 80., 18)).T,
     |  ...               np.atleast_2d(180. - np.abs(np.linspace(0., 350., 9)))).T
     |
     |  We want to interpolate it to a global one-degree grid
     |
     |  >>> new_lats = np.linspace(1, 180, 180) * np.pi / 180
     |  >>> new_lons = np.linspace(1, 360, 360) * np.pi / 180
     |  >>> new_lats, new_lons = np.meshgrid(new_lats, new_lons)
     |
     |  We need to set up the interpolator object
     |
     |  >>> from scipy.interpolate import RectSphereBivariateSpline
     |  >>> lut = RectSphereBivariateSpline(lats, lons, data)
     |
     |  Finally we interpolate the data.  The `RectSphereBivariateSpline` object
     |  only takes 1-D arrays as input, therefore we need to do some reshaping.
     |
     |  >>> data_interp = lut.ev(new_lats.ravel(),
     |  ...                      new_lons.ravel()).reshape((360, 180)).T
     |
     |  Looking at the original and the interpolated data, one can see that the
     |  interpolant reproduces the original data very well:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig = plt.figure()
     |  >>> ax1 = fig.add_subplot(211)
     |  >>> ax1.imshow(data, interpolation='nearest')
     |  >>> ax2 = fig.add_subplot(212)
     |  >>> ax2.imshow(data_interp, interpolation='nearest')
     |  >>> plt.show()
     |
     |  Choosing the optimal value of ``s`` can be a delicate task. Recommended
     |  values for ``s`` depend on the accuracy of the data values.  If the user
     |  has an idea of the statistical errors on the data, she can also find a
     |  proper estimate for ``s``. By assuming that, if she specifies the
     |  right ``s``, the interpolator will use a spline ``f(u,v)`` which exactly
     |  reproduces the function underlying the data, she can evaluate
     |  ``sum((r(i,j)-s(u(i),v(j)))**2)`` to find a good estimate for this ``s``.
     |  For example, if she knows that the statistical errors on her
     |  ``r(i,j)``-values are not greater than 0.1, she may expect that a good
     |  ``s`` should have a value not larger than ``u.size * v.size * (0.1)**2``.
     |
     |  If nothing is known about the statistical error in ``r(i,j)``, ``s`` must
     |  be determined by trial and error.  The best is then to start with a very
     |  large value of ``s`` (to determine the least-squares polynomial and the
     |  corresponding upper bound ``fp0`` for ``s``) and then to progressively
     |  decrease the value of ``s`` (say by a factor 10 in the beginning, i.e.
     |  ``s = fp0 / 10, fp0 / 100, ...``  and more carefully as the approximation
     |  shows more detail) to obtain closer fits.
     |
     |  The interpolation results for different values of ``s`` give some insight
     |  into this process:
     |
     |  >>> fig2 = plt.figure()
     |  >>> s = [3e9, 2e9, 1e9, 1e8]
     |  >>> for idx, sval in enumerate(s, 1):
     |  ...     lut = RectSphereBivariateSpline(lats, lons, data, s=sval)
     |  ...     data_interp = lut.ev(new_lats.ravel(),
     |  ...                          new_lons.ravel()).reshape((360, 180)).T
     |  ...     ax = fig2.add_subplot(2, 2, idx)
     |  ...     ax.imshow(data_interp, interpolation='nearest')
     |  ...     ax.set_title(f"s = {sval:g}")
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      RectSphereBivariateSpline
     |      SphereBivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __call__(self, theta, phi, dtheta=0, dphi=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points
     |          ``(theta[i], phi[i]), i=0, ..., len(x)-1``.  Standard
     |          Numpy broadcasting is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays theta, phi. The arrays
     |          must be sorted to increasing order.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      on a finer grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetaarr_fine = np.linspace(0, np.pi, 200)
     |      >>> phiarr_fine = np.linspace(0, 2 * np.pi, 200)
     |      >>> zdata_fine = rsbs(thetaarr_fine, phiarr_fine)
     |
     |      Finally we plot the coarsly-sampled input data alongside the
     |      finely-sampled interpolated data to check that they agree.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1)
     |      >>> ax2 = fig.add_subplot(1, 2, 2)
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_fine)
     |      >>> plt.show()
     |
     |  __init__(self, u, v, r, s=0.0, pole_continuity=False, pole_values=None, pole_exact=False, pole_flat=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SphereBivariateSpline:
     |
     |  ev(self, theta, phi, dtheta=0, dphi=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(theta[i], phi[i]),
     |      i=0,...,len(theta)-1``.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          np.meshgrid(..., indexing="ij") and inconsistent with the
     |          default ordering np.meshgrid(..., indexing="xy").
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int, optional
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      at points not on the original grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetainterp = np.linspace(thetaarr[0], thetaarr[-1], 200)
     |      >>> phiinterp = np.linspace(phiarr[0], phiarr[-1], 200)
     |      >>> zinterp = rsbs.ev(thetainterp, phiinterp)
     |
     |      Finally we plot the original data for a diagonal slice through the
     |      initial grid, and the spline approximation along the same slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sin(thetaarr) * np.sin(phiarr), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sin(thetainterp) * np.sin(phiinterp), zinterp, "-b")
     |      >>> plt.show()
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class RegularGridInterpolator(builtins.object)
     |  RegularGridInterpolator(points, values, method='linear', bounds_error=True, fill_value=nan, *, solver=None, solver_args=None)
     |
     |  Interpolator on a regular or rectilinear grid in arbitrary dimensions.
     |
     |  The data must be defined on a rectilinear grid; that is, a rectangular
     |  grid with even or uneven spacing. Linear, nearest-neighbor, spline
     |  interpolations are supported. After setting up the interpolator object,
     |  the interpolation method may be chosen at each evaluation.
     |
     |  Parameters
     |  ----------
     |  points : tuple of ndarray of float, with shapes (m1, ), ..., (mn, )
     |      The points defining the regular grid in n dimensions. The points in
     |      each dimension (i.e. every elements of the points tuple) must be
     |      strictly ascending or descending.
     |
     |  values : array_like, shape (m1, ..., mn, ...)
     |      The data on the regular grid in n dimensions. Complex data is
     |      accepted.
     |
     |      .. deprecated:: 1.13.0
     |          Complex data is deprecated with ``method="pchip"`` and will raise an
     |          error in SciPy 1.15.0. This is because ``PchipInterpolator`` only
     |          works with real values. If you are trying to use the real components of
     |          the passed array, use ``np.real`` on ``values``.
     |
     |  method : str, optional
     |      The method of interpolation to perform. Supported are "linear",
     |      "nearest", "slinear", "cubic", "quintic" and "pchip". This
     |      parameter will become the default for the object's ``__call__``
     |      method. Default is "linear".
     |
     |  bounds_error : bool, optional
     |      If True, when interpolated values are requested outside of the
     |      domain of the input data, a ValueError is raised.
     |      If False, then `fill_value` is used.
     |      Default is True.
     |
     |  fill_value : float or None, optional
     |      The value to use for points outside of the interpolation domain.
     |      If None, values outside the domain are extrapolated.
     |      Default is ``np.nan``.
     |
     |  solver : callable, optional
     |      Only used for methods "slinear", "cubic" and "quintic".
     |      Sparse linear algebra solver for construction of the NdBSpline instance.
     |      Default is the iterative solver `scipy.sparse.linalg.gcrotmk`.
     |
     |      .. versionadded:: 1.13
     |
     |  solver_args: dict, optional
     |      Additional arguments to pass to `solver`, if any.
     |
     |      .. versionadded:: 1.13
     |
     |  Methods
     |  -------
     |  __call__
     |
     |  Attributes
     |  ----------
     |  grid : tuple of ndarrays
     |      The points defining the regular grid in n dimensions.
     |      This tuple defines the full grid via
     |      ``np.meshgrid(*grid, indexing='ij')``
     |  values : ndarray
     |      Data values at the grid.
     |  method : str
     |      Interpolation method.
     |  fill_value : float or ``None``
     |      Use this value for out-of-bounds arguments to `__call__`.
     |  bounds_error : bool
     |      If ``True``, out-of-bounds argument raise a ``ValueError``.
     |
     |  Notes
     |  -----
     |  Contrary to `LinearNDInterpolator` and `NearestNDInterpolator`, this class
     |  avoids expensive triangulation of the input data by taking advantage of the
     |  regular grid structure.
     |
     |  In other words, this class assumes that the data is defined on a
     |  *rectilinear* grid.
     |
     |  .. versionadded:: 0.14
     |
     |  The 'slinear'(k=1), 'cubic'(k=3), and 'quintic'(k=5) methods are
     |  tensor-product spline interpolators, where `k` is the spline degree,
     |  If any dimension has fewer points than `k` + 1, an error will be raised.
     |
     |  .. versionadded:: 1.9
     |
     |  If the input data is such that dimensions have incommensurate
     |  units and differ by many orders of magnitude, the interpolant may have
     |  numerical artifacts. Consider rescaling the data before interpolating.
     |
     |  **Choosing a solver for spline methods**
     |
     |  Spline methods, "slinear", "cubic" and "quintic" involve solving a
     |  large sparse linear system at instantiation time. Depending on data,
     |  the default solver may or may not be adequate. When it is not, you may
     |  need to experiment with an optional `solver` argument, where you may
     |  choose between the direct solver (`scipy.sparse.linalg.spsolve`) or
     |  iterative solvers from `scipy.sparse.linalg`. You may need to supply
     |  additional parameters via the optional `solver_args` parameter (for instance,
     |  you may supply the starting value or target tolerance). See the
     |  `scipy.sparse.linalg` documentation for the full list of available options.
     |
     |  Alternatively, you may instead use the legacy methods, "slinear_legacy",
     |  "cubic_legacy" and "quintic_legacy". These methods allow faster construction
     |  but evaluations will be much slower.
     |
     |  Examples
     |  --------
     |  **Evaluate a function on the points of a 3-D grid**
     |
     |  As a first example, we evaluate a simple example function on the points of
     |  a 3-D grid:
     |
     |  >>> from scipy.interpolate import RegularGridInterpolator
     |  >>> import numpy as np
     |  >>> def f(x, y, z):
     |  ...     return 2 * x**3 + 3 * y**2 - z
     |  >>> x = np.linspace(1, 4, 11)
     |  >>> y = np.linspace(4, 7, 22)
     |  >>> z = np.linspace(7, 9, 33)
     |  >>> xg, yg ,zg = np.meshgrid(x, y, z, indexing='ij', sparse=True)
     |  >>> data = f(xg, yg, zg)
     |
     |  ``data`` is now a 3-D array with ``data[i, j, k] = f(x[i], y[j], z[k])``.
     |  Next, define an interpolating function from this data:
     |
     |  >>> interp = RegularGridInterpolator((x, y, z), data)
     |
     |  Evaluate the interpolating function at the two points
     |  ``(x,y,z) = (2.1, 6.2, 8.3)`` and ``(3.3, 5.2, 7.1)``:
     |
     |  >>> pts = np.array([[2.1, 6.2, 8.3],
     |  ...                 [3.3, 5.2, 7.1]])
     |  >>> interp(pts)
     |  array([ 125.80469388,  146.30069388])
     |
     |  which is indeed a close approximation to
     |
     |  >>> f(2.1, 6.2, 8.3), f(3.3, 5.2, 7.1)
     |  (125.54200000000002, 145.894)
     |
     |  **Interpolate and extrapolate a 2D dataset**
     |
     |  As a second example, we interpolate and extrapolate a 2D data set:
     |
     |  >>> x, y = np.array([-2, 0, 4]), np.array([-2, 0, 2, 5])
     |  >>> def ff(x, y):
     |  ...     return x**2 + y**2
     |
     |  >>> xg, yg = np.meshgrid(x, y, indexing='ij')
     |  >>> data = ff(xg, yg)
     |  >>> interp = RegularGridInterpolator((x, y), data,
     |  ...                                  bounds_error=False, fill_value=None)
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig = plt.figure()
     |  >>> ax = fig.add_subplot(projection='3d')
     |  >>> ax.scatter(xg.ravel(), yg.ravel(), data.ravel(),
     |  ...            s=60, c='k', label='data')
     |
     |  Evaluate and plot the interpolator on a finer grid
     |
     |  >>> xx = np.linspace(-4, 9, 31)
     |  >>> yy = np.linspace(-4, 9, 31)
     |  >>> X, Y = np.meshgrid(xx, yy, indexing='ij')
     |
     |  >>> # interpolator
     |  >>> ax.plot_wireframe(X, Y, interp((X, Y)), rstride=3, cstride=3,
     |  ...                   alpha=0.4, color='m', label='linear interp')
     |
     |  >>> # ground truth
     |  >>> ax.plot_wireframe(X, Y, ff(X, Y), rstride=3, cstride=3,
     |  ...                   alpha=0.4, label='ground truth')
     |  >>> plt.legend()
     |  >>> plt.show()
     |
     |  Other examples are given
     |  :ref:`in the tutorial <tutorial-interpolate_regular_grid_interpolator>`.
     |
     |  See Also
     |  --------
     |  NearestNDInterpolator : Nearest neighbor interpolator on *unstructured*
     |                          data in N dimensions
     |
     |  LinearNDInterpolator : Piecewise linear interpolator on *unstructured* data
     |                         in N dimensions
     |
     |  interpn : a convenience function which wraps `RegularGridInterpolator`
     |
     |  scipy.ndimage.map_coordinates : interpolation on grids with equal spacing
     |                                  (suitable for e.g., N-D image resampling)
     |
     |  References
     |  ----------
     |  .. [1] Python package *regulargrid* by Johannes Buchner, see
     |         https://pypi.python.org/pypi/regulargrid/
     |  .. [2] Wikipedia, "Trilinear interpolation",
     |         https://en.wikipedia.org/wiki/Trilinear_interpolation
     |  .. [3] Weiser, Alan, and Sergio E. Zarantonello. "A note on piecewise linear
     |         and multilinear table interpolation in many dimensions." MATH.
     |         COMPUT. 50.181 (1988): 189-196.
     |         https://www.ams.org/journals/mcom/1988-50-181/S0025-5718-1988-0917826-0/S0025-5718-1988-0917826-0.pdf
     |         :doi:`10.1090/S0025-5718-1988-0917826-0`
     |
     |  Methods defined here:
     |
     |  __call__(self, xi, method=None, *, nu=None)
     |      Interpolation at coordinates.
     |
     |      Parameters
     |      ----------
     |      xi : ndarray of shape (..., ndim)
     |          The coordinates to evaluate the interpolator at.
     |
     |      method : str, optional
     |          The method of interpolation to perform. Supported are "linear",
     |          "nearest", "slinear", "cubic", "quintic" and "pchip". Default is
     |          the method chosen when the interpolator was created.
     |
     |      nu : sequence of ints, length ndim, optional
     |          If not None, the orders of the derivatives to evaluate.
     |          Each entry must be non-negative.
     |          Only allowed for methods "slinear", "cubic" and "quintic".
     |
     |          .. versionadded:: 1.13
     |
     |      Returns
     |      -------
     |      values_x : ndarray, shape xi.shape[:-1] + values.shape[ndim:]
     |          Interpolated values at `xi`. See notes for behaviour when
     |          ``xi.ndim == 1``.
     |
     |      Notes
     |      -----
     |      In the case that ``xi.ndim == 1`` a new axis is inserted into
     |      the 0 position of the returned array, values_x, so its shape is
     |      instead ``(1,) + values.shape[ndim:]``.
     |
     |      Examples
     |      --------
     |      Here we define a nearest-neighbor interpolator of a simple function
     |
     |      >>> import numpy as np
     |      >>> x, y = np.array([0, 1, 2]), np.array([1, 3, 7])
     |      >>> def f(x, y):
     |      ...     return x**2 + y**2
     |      >>> data = f(*np.meshgrid(x, y, indexing='ij', sparse=True))
     |      >>> from scipy.interpolate import RegularGridInterpolator
     |      >>> interp = RegularGridInterpolator((x, y), data, method='nearest')
     |
     |      By construction, the interpolator uses the nearest-neighbor
     |      interpolation
     |
     |      >>> interp([[1.5, 1.3], [0.3, 4.5]])
     |      array([2., 9.])
     |
     |      We can however evaluate the linear interpolant by overriding the
     |      `method` parameter
     |
     |      >>> interp([[1.5, 1.3], [0.3, 4.5]], method='linear')
     |      array([ 4.7, 24.3])
     |
     |  __init__(self, points, values, method='linear', bounds_error=True, fill_value=nan, *, solver=None, solver_args=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class SmoothBivariateSpline(BivariateSpline)
     |  SmoothBivariateSpline(x, y, z, w=None, bbox=[None, None, None, None], kx=3, ky=3, s=None, eps=1e-16)
     |
     |  Smooth bivariate spline approximation.
     |
     |  Parameters
     |  ----------
     |  x, y, z : array_like
     |      1-D sequences of data points (order is not important).
     |  w : array_like, optional
     |      Positive 1-D sequence of weights, of same length as `x`, `y` and `z`.
     |  bbox : array_like, optional
     |      Sequence of length 4 specifying the boundary of the rectangular
     |      approximation domain.  By default,
     |      ``bbox=[min(x), max(x), min(y), max(y)]``.
     |  kx, ky : ints, optional
     |      Degrees of the bivariate spline. Default is 3.
     |  s : float, optional
     |      Positive smoothing factor defined for estimation condition:
     |      ``sum((w[i]*(z[i]-s(x[i], y[i])))**2, axis=0) <= s``
     |      Default ``s=len(w)`` which should be a good value if ``1/w[i]`` is an
     |      estimate of the standard deviation of ``z[i]``.
     |  eps : float, optional
     |      A threshold for determining the effective rank of an over-determined
     |      linear system of equations. `eps` should have a value within the open
     |      interval ``(0, 1)``, the default is 1e-16.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |  The length of `x`, `y` and `z` should be at least ``(kx+1) * (ky+1)``.
     |
     |  If the input data is such that input dimensions have incommensurate
     |  units and differ by many orders of magnitude, the interpolant may have
     |  numerical artifacts. Consider rescaling the data before interpolating.
     |
     |  This routine constructs spline knot vectors automatically via the FITPACK
     |  algorithm. The spline knots may be placed away from the data points. For
     |  some data sets, this routine may fail to construct an interpolating spline,
     |  even if one is requested via ``s=0`` parameter. In such situations, it is
     |  recommended to use `bisplrep` / `bisplev` directly instead of this routine
     |  and, if needed, increase the values of ``nxest`` and ``nyest`` parameters
     |  of `bisplrep`.
     |
     |  For linear interpolation, prefer `LinearNDInterpolator`.
     |  See ``https://gist.github.com/ev-br/8544371b40f414b7eaf3fe6217209bff``
     |  for discussion.
     |
     |  Method resolution order:
     |      SmoothBivariateSpline
     |      BivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, z, w=None, bbox=[None, None, None, None], kx=3, ky=3, s=None, eps=1e-16)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from BivariateSpline:
     |
     |  ev(self, xi, yi, dx=0, dy=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(xi[i], yi[i]),
     |      i=0,...,len(xi)-1``.
     |
     |      Parameters
     |      ----------
     |      xi, yi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int, optional
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int, optional
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |      >>> def f(x, y):
     |      ...     return np.exp(-np.sqrt((x / 2) ** 2 + y**2))
     |
     |      We sample the function on a coarse grid and set up the interpolator. Note that
     |      the default ``indexing="xy"`` of meshgrid would result in an unexpected
     |      (transposed) result after interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 21)
     |      >>> yarr = np.linspace(-3, 3, 21)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |      >>> zdata = f(xgrid, ygrid)
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |
     |      Next we sample the function along a diagonal slice through the coordinate space
     |      on a finer grid using interpolation.
     |
     |      >>> xinterp = np.linspace(-3, 3, 201)
     |      >>> yinterp = np.linspace(3, -3, 201)
     |      >>> zinterp = rbs.ev(xinterp, yinterp)
     |
     |      And check that the interpolation passes through the function evaluations as a
     |      function of the distance from the origin along the slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sqrt(xarr**2 + yarr**2), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sqrt(xinterp**2 + yinterp**2), zinterp, "-b")
     |      >>> plt.show()
     |
     |  integral(self, xa, xb, ya, yb)
     |      Evaluate the integral of the spline over area [xa,xb] x [ya,yb].
     |
     |      Parameters
     |      ----------
     |      xa, xb : float
     |          The end-points of the x integration interval.
     |      ya, yb : float
     |          The end-points of the y integration interval.
     |
     |      Returns
     |      -------
     |      integ : float
     |          The value of the resulting integral.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  __call__(self, x, y, dx=0, dy=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      x, y : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points ``(x[i],
     |          y[i]), i=0, ..., len(x)-1``.  Standard Numpy broadcasting
     |          is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays x, y. The arrays must be
     |          sorted to increasing order.
     |
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dx : int
     |          Order of x-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dy : int
     |          Order of y-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to bilinearly interpolate an exponentially decaying
     |      function in 2 dimensions.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectBivariateSpline
     |
     |      We sample the function on a coarse grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> xarr = np.linspace(-3, 3, 100)
     |      >>> yarr = np.linspace(-3, 3, 100)
     |      >>> xgrid, ygrid = np.meshgrid(xarr, yarr, indexing="ij")
     |
     |      The function to interpolate decays faster along one axis than the other.
     |
     |      >>> zdata = np.exp(-np.sqrt((xgrid / 2) ** 2 + ygrid**2))
     |
     |      Next we sample on a finer grid using interpolation (kx=ky=1 for bilinear).
     |
     |      >>> rbs = RectBivariateSpline(xarr, yarr, zdata, kx=1, ky=1)
     |      >>> xarr_fine = np.linspace(-3, 3, 200)
     |      >>> yarr_fine = np.linspace(-3, 3, 200)
     |      >>> xgrid_fine, ygrid_fine = np.meshgrid(xarr_fine, yarr_fine, indexing="ij")
     |      >>> zdata_interp = rbs(xgrid_fine, ygrid_fine, grid=False)
     |
     |      And check that the result agrees with the input by plotting both.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1, aspect="equal")
     |      >>> ax2 = fig.add_subplot(1, 2, 2, aspect="equal")
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_interp)
     |      >>> plt.show()
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class SmoothSphereBivariateSpline(SphereBivariateSpline)
     |  SmoothSphereBivariateSpline(theta, phi, r, w=None, s=0.0, eps=1e-16)
     |
     |  Smooth bivariate spline approximation in spherical coordinates.
     |
     |  .. versionadded:: 0.11.0
     |
     |  Parameters
     |  ----------
     |  theta, phi, r : array_like
     |      1-D sequences of data points (order is not important). Coordinates
     |      must be given in radians. Theta must lie within the interval
     |      ``[0, pi]``, and phi must lie within the interval ``[0, 2pi]``.
     |  w : array_like, optional
     |      Positive 1-D sequence of weights.
     |  s : float, optional
     |      Positive smoothing factor defined for estimation condition:
     |      ``sum((w(i)*(r(i) - s(theta(i), phi(i))))**2, axis=0) <= s``
     |      Default ``s=len(w)`` which should be a good value if ``1/w[i]`` is an
     |      estimate of the standard deviation of ``r[i]``.
     |  eps : float, optional
     |      A threshold for determining the effective rank of an over-determined
     |      linear system of equations. `eps` should have a value within the open
     |      interval ``(0, 1)``, the default is 1e-16.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  UnivariateSpline :
     |      a smooth univariate spline to fit a given set of data points.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |
     |  Notes
     |  -----
     |  For more information, see the FITPACK_ site about this function.
     |
     |  .. _FITPACK: http://www.netlib.org/dierckx/sphere.f
     |
     |  Examples
     |  --------
     |  Suppose we have global data on a coarse grid (the input data does not
     |  have to be on a grid):
     |
     |  >>> import numpy as np
     |  >>> theta = np.linspace(0., np.pi, 7)
     |  >>> phi = np.linspace(0., 2*np.pi, 9)
     |  >>> data = np.empty((theta.shape[0], phi.shape[0]))
     |  >>> data[:,0], data[0,:], data[-1,:] = 0., 0., 0.
     |  >>> data[1:-1,1], data[1:-1,-1] = 1., 1.
     |  >>> data[1,1:-1], data[-2,1:-1] = 1., 1.
     |  >>> data[2:-2,2], data[2:-2,-2] = 2., 2.
     |  >>> data[2,2:-2], data[-3,2:-2] = 2., 2.
     |  >>> data[3,3:-2] = 3.
     |  >>> data = np.roll(data, 4, 1)
     |
     |  We need to set up the interpolator object
     |
     |  >>> lats, lons = np.meshgrid(theta, phi)
     |  >>> from scipy.interpolate import SmoothSphereBivariateSpline
     |  >>> lut = SmoothSphereBivariateSpline(lats.ravel(), lons.ravel(),
     |  ...                                   data.T.ravel(), s=3.5)
     |
     |  As a first test, we'll see what the algorithm returns when run on the
     |  input coordinates
     |
     |  >>> data_orig = lut(theta, phi)
     |
     |  Finally we interpolate the data to a finer grid
     |
     |  >>> fine_lats = np.linspace(0., np.pi, 70)
     |  >>> fine_lons = np.linspace(0., 2 * np.pi, 90)
     |
     |  >>> data_smth = lut(fine_lats, fine_lons)
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig = plt.figure()
     |  >>> ax1 = fig.add_subplot(131)
     |  >>> ax1.imshow(data, interpolation='nearest')
     |  >>> ax2 = fig.add_subplot(132)
     |  >>> ax2.imshow(data_orig, interpolation='nearest')
     |  >>> ax3 = fig.add_subplot(133)
     |  >>> ax3.imshow(data_smth, interpolation='nearest')
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      SmoothSphereBivariateSpline
     |      SphereBivariateSpline
     |      _BivariateSplineBase
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __call__(self, theta, phi, dtheta=0, dphi=0, grid=True)
     |      Evaluate the spline or its derivatives at given positions.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates.
     |
     |          If `grid` is False, evaluate the spline at points
     |          ``(theta[i], phi[i]), i=0, ..., len(x)-1``.  Standard
     |          Numpy broadcasting is obeyed.
     |
     |          If `grid` is True: evaluate spline at the grid points
     |          defined by the coordinate arrays theta, phi. The arrays
     |          must be sorted to increasing order.
     |          The ordering of axes is consistent with
     |          ``np.meshgrid(..., indexing="ij")`` and inconsistent with the
     |          default ordering ``np.meshgrid(..., indexing="xy")``.
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |      grid : bool
     |          Whether to evaluate the results on a grid spanned by the
     |          input arrays, or at points specified by the input arrays.
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      on a finer grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetaarr_fine = np.linspace(0, np.pi, 200)
     |      >>> phiarr_fine = np.linspace(0, 2 * np.pi, 200)
     |      >>> zdata_fine = rsbs(thetaarr_fine, phiarr_fine)
     |
     |      Finally we plot the coarsly-sampled input data alongside the
     |      finely-sampled interpolated data to check that they agree.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 2, 1)
     |      >>> ax2 = fig.add_subplot(1, 2, 2)
     |      >>> ax1.imshow(zdata)
     |      >>> ax2.imshow(zdata_fine)
     |      >>> plt.show()
     |
     |  __init__(self, theta, phi, r, w=None, s=0.0, eps=1e-16)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SphereBivariateSpline:
     |
     |  ev(self, theta, phi, dtheta=0, dphi=0)
     |      Evaluate the spline at points
     |
     |      Returns the interpolated value at ``(theta[i], phi[i]),
     |      i=0,...,len(theta)-1``.
     |
     |      Parameters
     |      ----------
     |      theta, phi : array_like
     |          Input coordinates. Standard Numpy broadcasting is obeyed.
     |          The ordering of axes is consistent with
     |          np.meshgrid(..., indexing="ij") and inconsistent with the
     |          default ordering np.meshgrid(..., indexing="xy").
     |      dtheta : int, optional
     |          Order of theta-derivative
     |
     |          .. versionadded:: 0.14.0
     |      dphi : int, optional
     |          Order of phi-derivative
     |
     |          .. versionadded:: 0.14.0
     |
     |      Examples
     |      --------
     |      Suppose that we want to use splines to interpolate a bivariate function on a
     |      sphere. The value of the function is known on a grid of longitudes and
     |      colatitudes.
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import RectSphereBivariateSpline
     |      >>> def f(theta, phi):
     |      ...     return np.sin(theta) * np.cos(phi)
     |
     |      We evaluate the function on the grid. Note that the default indexing="xy"
     |      of meshgrid would result in an unexpected (transposed) result after
     |      interpolation.
     |
     |      >>> thetaarr = np.linspace(0, np.pi, 22)[1:-1]
     |      >>> phiarr = np.linspace(0, 2 * np.pi, 21)[:-1]
     |      >>> thetagrid, phigrid = np.meshgrid(thetaarr, phiarr, indexing="ij")
     |      >>> zdata = f(thetagrid, phigrid)
     |
     |      We next set up the interpolator and use it to evaluate the function
     |      at points not on the original grid.
     |
     |      >>> rsbs = RectSphereBivariateSpline(thetaarr, phiarr, zdata)
     |      >>> thetainterp = np.linspace(thetaarr[0], thetaarr[-1], 200)
     |      >>> phiinterp = np.linspace(phiarr[0], phiarr[-1], 200)
     |      >>> zinterp = rsbs.ev(thetainterp, phiinterp)
     |
     |      Finally we plot the original data for a diagonal slice through the
     |      initial grid, and the spline approximation along the same slice.
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig = plt.figure()
     |      >>> ax1 = fig.add_subplot(1, 1, 1)
     |      >>> ax1.plot(np.sin(thetaarr) * np.sin(phiarr), np.diag(zdata), "or")
     |      >>> ax1.plot(np.sin(thetainterp) * np.sin(phiinterp), zinterp, "-b")
     |      >>> plt.show()
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _BivariateSplineBase:
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return a tuple (tx,ty) where tx,ty contain knots positions
     |      of the spline with respect to x-, y-variable, respectively.
     |      The position of interior and additional knots are given as
     |      t[k+1:-k-1] and t[:k+1]=b, t[-k-1:]=e, respectively.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline
     |      approximation: sum ((w[i]*(z[i]-s(x[i],y[i])))**2,axis=0)
     |
     |  partial_derivative(self, dx, dy)
     |      Construct a new spline representing a partial derivative of this
     |      spline.
     |
     |      Parameters
     |      ----------
     |      dx, dy : int
     |          Orders of the derivative in x and y respectively. They must be
     |          non-negative integers and less than the respective degree of the
     |          original spline (self) in that direction (``kx``, ``ky``).
     |
     |      Returns
     |      -------
     |      spline :
     |          A new spline of degrees (``kx - dx``, ``ky - dy``) representing the
     |          derivative of this spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 1.9.0
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _BivariateSplineBase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class UnivariateSpline(builtins.object)
     |  UnivariateSpline(x, y, w=None, bbox=[None, None], k=3, s=None, ext=0, check_finite=False)
     |
     |  1-D smoothing spline fit to a given set of data points.
     |
     |  Fits a spline y = spl(x) of degree `k` to the provided `x`, `y` data.  `s`
     |  specifies the number of knots by specifying a smoothing condition.
     |
     |  Parameters
     |  ----------
     |  x : (N,) array_like
     |      1-D array of independent input data. Must be increasing;
     |      must be strictly increasing if `s` is 0.
     |  y : (N,) array_like
     |      1-D array of dependent input data, of the same length as `x`.
     |  w : (N,) array_like, optional
     |      Weights for spline fitting.  Must be positive.  If `w` is None,
     |      weights are all 1. Default is None.
     |  bbox : (2,) array_like, optional
     |      2-sequence specifying the boundary of the approximation interval. If
     |      `bbox` is None, ``bbox=[x[0], x[-1]]``. Default is None.
     |  k : int, optional
     |      Degree of the smoothing spline.  Must be 1 <= `k` <= 5.
     |      ``k = 3`` is a cubic spline. Default is 3.
     |  s : float or None, optional
     |      Positive smoothing factor used to choose the number of knots.  Number
     |      of knots will be increased until the smoothing condition is satisfied::
     |
     |          sum((w[i] * (y[i]-spl(x[i])))**2, axis=0) <= s
     |
     |      However, because of numerical issues, the actual condition is::
     |
     |          abs(sum((w[i] * (y[i]-spl(x[i])))**2, axis=0) - s) < 0.001 * s
     |
     |      If `s` is None, `s` will be set as `len(w)` for a smoothing spline
     |      that uses all data points.
     |      If 0, spline will interpolate through all data points. This is
     |      equivalent to `InterpolatedUnivariateSpline`.
     |      Default is None.
     |      The user can use the `s` to control the tradeoff between closeness
     |      and smoothness of fit. Larger `s` means more smoothing while smaller
     |      values of `s` indicate less smoothing.
     |      Recommended values of `s` depend on the weights, `w`. If the weights
     |      represent the inverse of the standard-deviation of `y`, then a good
     |      `s` value should be found in the range (m-sqrt(2*m),m+sqrt(2*m))
     |      where m is the number of datapoints in `x`, `y`, and `w`. This means
     |      ``s = len(w)`` should be a good value if ``1/w[i]`` is an
     |      estimate of the standard deviation of ``y[i]``.
     |  ext : int or str, optional
     |      Controls the extrapolation mode for elements
     |      not in the interval defined by the knot sequence.
     |
     |      * if ext=0 or 'extrapolate', return the extrapolated value.
     |      * if ext=1 or 'zeros', return 0
     |      * if ext=2 or 'raise', raise a ValueError
     |      * if ext=3 or 'const', return the boundary value.
     |
     |      Default is 0.
     |
     |  check_finite : bool, optional
     |      Whether to check that the input arrays contain only finite numbers.
     |      Disabling may give a performance gain, but may result in problems
     |      (crashes, non-termination or non-sensical results) if the inputs
     |      do contain infinities or NaNs.
     |      Default is False.
     |
     |  See Also
     |  --------
     |  BivariateSpline :
     |      a base class for bivariate splines.
     |  SmoothBivariateSpline :
     |      a smoothing bivariate spline through the given points
     |  LSQBivariateSpline :
     |      a bivariate spline using weighted least-squares fitting
     |  RectSphereBivariateSpline :
     |      a bivariate spline over a rectangular mesh on a sphere
     |  SmoothSphereBivariateSpline :
     |      a smoothing bivariate spline in spherical coordinates
     |  LSQSphereBivariateSpline :
     |      a bivariate spline in spherical coordinates using weighted
     |      least-squares fitting
     |  RectBivariateSpline :
     |      a bivariate spline over a rectangular mesh
     |  InterpolatedUnivariateSpline :
     |      a interpolating univariate spline for a given set of data points.
     |  bisplrep :
     |      a function to find a bivariate B-spline representation of a surface
     |  bisplev :
     |      a function to evaluate a bivariate B-spline and its derivatives
     |  splrep :
     |      a function to find the B-spline representation of a 1-D curve
     |  splev :
     |      a function to evaluate a B-spline or its derivatives
     |  sproot :
     |      a function to find the roots of a cubic B-spline
     |  splint :
     |      a function to evaluate the definite integral of a B-spline between two
     |      given points
     |  spalde :
     |      a function to evaluate all derivatives of a B-spline
     |
     |  Notes
     |  -----
     |  The number of data points must be larger than the spline degree `k`.
     |
     |  **NaN handling**: If the input arrays contain ``nan`` values, the result
     |  is not useful, since the underlying spline fitting routines cannot deal
     |  with ``nan``. A workaround is to use zero weights for not-a-number
     |  data points:
     |
     |  >>> import numpy as np
     |  >>> from scipy.interpolate import UnivariateSpline
     |  >>> x, y = np.array([1, 2, 3, 4]), np.array([1, np.nan, 3, 4])
     |  >>> w = np.isnan(y)
     |  >>> y[w] = 0.
     |  >>> spl = UnivariateSpline(x, y, w=~w)
     |
     |  Notice the need to replace a ``nan`` by a numerical value (precise value
     |  does not matter as long as the corresponding weight is zero.)
     |
     |  References
     |  ----------
     |  Based on algorithms described in [1]_, [2]_, [3]_, and [4]_:
     |
     |  .. [1] P. Dierckx, "An algorithm for smoothing, differentiation and
     |     integration of experimental data using spline functions",
     |     J.Comp.Appl.Maths 1 (1975) 165-184.
     |  .. [2] P. Dierckx, "A fast algorithm for smoothing data on a rectangular
     |     grid while using spline functions", SIAM J.Numer.Anal. 19 (1982)
     |     1286-1304.
     |  .. [3] P. Dierckx, "An improved algorithm for curve fitting with spline
     |     functions", report tw54, Dept. Computer Science,K.U. Leuven, 1981.
     |  .. [4] P. Dierckx, "Curve and surface fitting with splines", Monographs on
     |     Numerical Analysis, Oxford University Press, 1993.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.interpolate import UnivariateSpline
     |  >>> rng = np.random.default_rng()
     |  >>> x = np.linspace(-3, 3, 50)
     |  >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)
     |  >>> plt.plot(x, y, 'ro', ms=5)
     |
     |  Use the default value for the smoothing parameter:
     |
     |  >>> spl = UnivariateSpline(x, y)
     |  >>> xs = np.linspace(-3, 3, 1000)
     |  >>> plt.plot(xs, spl(xs), 'g', lw=3)
     |
     |  Manually change the amount of smoothing:
     |
     |  >>> spl.set_smoothing_factor(0.5)
     |  >>> plt.plot(xs, spl(xs), 'b', lw=3)
     |  >>> plt.show()
     |
     |  Methods defined here:
     |
     |  __call__(self, x, nu=0, ext=None)
     |      Evaluate spline (or its nu-th derivative) at positions x.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          A 1-D array of points at which to return the value of the smoothed
     |          spline or its derivatives. Note: `x` can be unordered but the
     |          evaluation is more efficient if `x` is (partially) ordered.
     |      nu  : int
     |          The order of derivative of the spline to compute.
     |      ext : int
     |          Controls the value returned for elements of `x` not in the
     |          interval defined by the knot sequence.
     |
     |          * if ext=0 or 'extrapolate', return the extrapolated value.
     |          * if ext=1 or 'zeros', return 0
     |          * if ext=2 or 'raise', raise a ValueError
     |          * if ext=3 or 'const', return the boundary value.
     |
     |          The default value is 0, passed from the initialization of
     |          UnivariateSpline.
     |
     |  __init__(self, x, y, w=None, bbox=[None, None], k=3, s=None, ext=0, check_finite=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  antiderivative(self, n=1)
     |      Construct a new spline representing the antiderivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of antiderivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k+n representing the antiderivative of this
     |          spline.
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      See Also
     |      --------
     |      splantider, derivative
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, np.pi/2, 70)
     |      >>> y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2)
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |
     |      The derivative is the inverse operation of the antiderivative,
     |      although some floating point error accumulates:
     |
     |      >>> spl(1.7), spl.antiderivative().derivative()(1.7)
     |      (array(2.1565429877197317), array(2.1565429877201865))
     |
     |      Antiderivative can be used to evaluate definite integrals:
     |
     |      >>> ispl = spl.antiderivative()
     |      >>> ispl(np.pi/2) - ispl(0)
     |      2.2572053588768486
     |
     |      This is indeed an approximation to the complete elliptic integral
     |      :math:`K(m) = \int_0^{\pi/2} [1 - m\sin^2 x]^{-1/2} dx`:
     |
     |      >>> from scipy.special import ellipk
     |      >>> ellipk(0.8)
     |      2.2572053268208538
     |
     |  derivative(self, n=1)
     |      Construct a new spline representing the derivative of this spline.
     |
     |      Parameters
     |      ----------
     |      n : int, optional
     |          Order of derivative to evaluate. Default: 1
     |
     |      Returns
     |      -------
     |      spline : UnivariateSpline
     |          Spline of order k2=k-n representing the derivative of this
     |          spline.
     |
     |      See Also
     |      --------
     |      splder, antiderivative
     |
     |      Notes
     |      -----
     |
     |      .. versionadded:: 0.13.0
     |
     |      Examples
     |      --------
     |      This can be used for finding maxima of a curve:
     |
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 10, 70)
     |      >>> y = np.sin(x)
     |      >>> spl = UnivariateSpline(x, y, k=4, s=0)
     |
     |      Now, differentiate the spline and find the zeros of the
     |      derivative. (NB: `sproot` only works for order 3 splines, so we
     |      fit an order 4 spline):
     |
     |      >>> spl.derivative().roots() / np.pi
     |      array([ 0.50000001,  1.5       ,  2.49999998])
     |
     |      This agrees well with roots :math:`\pi/2 + n\pi` of
     |      :math:`\cos(x) = \sin'(x)`.
     |
     |  derivatives(self, x)
     |      Return all derivatives of the spline at the point x.
     |
     |      Parameters
     |      ----------
     |      x : float
     |          The point to evaluate the derivatives at.
     |
     |      Returns
     |      -------
     |      der : ndarray, shape(k+1,)
     |          Derivatives of the orders 0 to k.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.derivatives(1.5)
     |      array([2.25, 3.0, 2.0, 0])
     |
     |  get_coeffs(self)
     |      Return spline coefficients.
     |
     |  get_knots(self)
     |      Return positions of interior knots of the spline.
     |
     |      Internally, the knot vector contains ``2*k`` additional boundary knots.
     |
     |  get_residual(self)
     |      Return weighted sum of squared residuals of the spline approximation.
     |
     |      This is equivalent to::
     |
     |           sum((w[i] * (y[i]-spl(x[i])))**2, axis=0)
     |
     |  integral(self, a, b)
     |      Return definite integral of the spline between two given points.
     |
     |      Parameters
     |      ----------
     |      a : float
     |          Lower limit of integration.
     |      b : float
     |          Upper limit of integration.
     |
     |      Returns
     |      -------
     |      integral : float
     |          The value of the definite integral of the spline between limits.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> x = np.linspace(0, 3, 11)
     |      >>> y = x**2
     |      >>> spl = UnivariateSpline(x, y)
     |      >>> spl.integral(0, 3)
     |      9.0
     |
     |      which agrees with :math:`\int x^2 dx = x^3 / 3` between the limits
     |      of 0 and 3.
     |
     |      A caveat is that this routine assumes the spline to be zero outside of
     |      the data limits:
     |
     |      >>> spl.integral(-1, 4)
     |      9.0
     |      >>> spl.integral(-1, 0)
     |      0.0
     |
     |  roots(self)
     |      Return the zeros of the spline.
     |
     |      Notes
     |      -----
     |      Restriction: only cubic splines are supported by FITPACK. For non-cubic
     |      splines, use `PPoly.root` (see below for an example).
     |
     |      Examples
     |      --------
     |
     |      For some data, this method may miss a root. This happens when one of
     |      the spline knots (which FITPACK places automatically) happens to
     |      coincide with the true root. A workaround is to convert to `PPoly`,
     |      which uses a different root-finding algorithm.
     |
     |      For example,
     |
     |      >>> x = [1.96, 1.97, 1.98, 1.99, 2.00, 2.01, 2.02, 2.03, 2.04, 2.05]
     |      >>> y = [-6.365470e-03, -4.790580e-03, -3.204320e-03, -1.607270e-03,
     |      ...      4.440892e-16,  1.616930e-03,  3.243000e-03,  4.877670e-03,
     |      ...      6.520430e-03,  8.170770e-03]
     |      >>> from scipy.interpolate import UnivariateSpline
     |      >>> spl = UnivariateSpline(x, y, s=0)
     |      >>> spl.roots()
     |      array([], dtype=float64)
     |
     |      Converting to a PPoly object does find the roots at `x=2`:
     |
     |      >>> from scipy.interpolate import splrep, PPoly
     |      >>> tck = splrep(x, y, s=0)
     |      >>> ppoly = PPoly.from_spline(tck)
     |      >>> ppoly.roots(extrapolate=False)
     |      array([2.])
     |
     |      See Also
     |      --------
     |      sproot
     |      PPoly.roots
     |
     |  set_smoothing_factor(self, s)
     |      Continue spline computation with the given smoothing
     |      factor s and with the knots found at the last call.
     |
     |      This routine modifies the spline in place.
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  validate_input(x, y, w, bbox, k, s, ext, check_finite)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class interp1d(scipy.interpolate._polyint._Interpolator1D)
     |  interp1d(x, y, kind='linear', axis=-1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)
     |
     |  Interpolate a 1-D function.
     |
     |  .. legacy:: class
     |
     |      For a guide to the intended replacements for `interp1d` see
     |      :ref:`tutorial-interpolate_1Dsection`.
     |
     |  `x` and `y` are arrays of values used to approximate some function f:
     |  ``y = f(x)``. This class returns a function whose call method uses
     |  interpolation to find the value of new points.
     |
     |  Parameters
     |  ----------
     |  x : (npoints, ) array_like
     |      A 1-D array of real values.
     |  y : (..., npoints, ...) array_like
     |      A N-D array of real values. The length of `y` along the interpolation
     |      axis must be equal to the length of `x`. Use the ``axis`` parameter
     |      to select correct axis. Unlike other interpolators, the default
     |      interpolation axis is the last axis of `y`.
     |  kind : str or int, optional
     |      Specifies the kind of interpolation as a string or as an integer
     |      specifying the order of the spline interpolator to use.
     |      The string has to be one of 'linear', 'nearest', 'nearest-up', 'zero',
     |      'slinear', 'quadratic', 'cubic', 'previous', or 'next'. 'zero',
     |      'slinear', 'quadratic' and 'cubic' refer to a spline interpolation of
     |      zeroth, first, second or third order; 'previous' and 'next' simply
     |      return the previous or next value of the point; 'nearest-up' and
     |      'nearest' differ when interpolating half-integers (e.g. 0.5, 1.5)
     |      in that 'nearest-up' rounds up and 'nearest' rounds down. Default
     |      is 'linear'.
     |  axis : int, optional
     |      Axis in the ``y`` array corresponding to the x-coordinate values. Unlike
     |      other interpolators, defaults to ``axis=-1``.
     |  copy : bool, optional
     |      If ``True``, the class makes internal copies of x and y. If ``False``,
     |      references to ``x`` and ``y`` are used if possible. The default is to copy.
     |  bounds_error : bool, optional
     |      If True, a ValueError is raised any time interpolation is attempted on
     |      a value outside of the range of x (where extrapolation is
     |      necessary). If False, out of bounds values are assigned `fill_value`.
     |      By default, an error is raised unless ``fill_value="extrapolate"``.
     |  fill_value : array-like or (array-like, array_like) or "extrapolate", optional
     |      - if a ndarray (or float), this value will be used to fill in for
     |        requested points outside of the data range. If not provided, then
     |        the default is NaN. The array-like must broadcast properly to the
     |        dimensions of the non-interpolation axes.
     |      - If a two-element tuple, then the first element is used as a
     |        fill value for ``x_new < x[0]`` and the second element is used for
     |        ``x_new > x[-1]``. Anything that is not a 2-element tuple (e.g.,
     |        list or ndarray, regardless of shape) is taken to be a single
     |        array-like argument meant to be used for both bounds as
     |        ``below, above = fill_value, fill_value``. Using a two-element tuple
     |        or ndarray requires ``bounds_error=False``.
     |
     |        .. versionadded:: 0.17.0
     |      - If "extrapolate", then points outside the data range will be
     |        extrapolated.
     |
     |        .. versionadded:: 0.17.0
     |  assume_sorted : bool, optional
     |      If False, values of `x` can be in any order and they are sorted first.
     |      If True, `x` has to be an array of monotonically increasing values.
     |
     |  Attributes
     |  ----------
     |  fill_value
     |
     |  Methods
     |  -------
     |  __call__
     |
     |  See Also
     |  --------
     |  splrep, splev
     |      Spline interpolation/smoothing based on FITPACK.
     |  UnivariateSpline : An object-oriented wrapper of the FITPACK routines.
     |  interp2d : 2-D interpolation
     |
     |  Notes
     |  -----
     |  Calling `interp1d` with NaNs present in input values results in
     |  undefined behaviour.
     |
     |  Input values `x` and `y` must be convertible to `float` values like
     |  `int` or `float`.
     |
     |  If the values in `x` are not unique, the resulting behavior is
     |  undefined and specific to the choice of `kind`, i.e., changing
     |  `kind` will change the behavior for duplicates.
     |
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy import interpolate
     |  >>> x = np.arange(0, 10)
     |  >>> y = np.exp(-x/3.0)
     |  >>> f = interpolate.interp1d(x, y)
     |
     |  >>> xnew = np.arange(0, 9, 0.1)
     |  >>> ynew = f(xnew)   # use interpolation function returned by `interp1d`
     |  >>> plt.plot(x, y, 'o', xnew, ynew, '-')
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      interp1d
     |      scipy.interpolate._polyint._Interpolator1D
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, kind='linear', axis=-1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)
     |      Initialize a 1-D linear interpolation class.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  fill_value
     |      The fill value.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.interpolate._polyint._Interpolator1D:
     |
     |  __call__(self, x)
     |      Evaluate the interpolant
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Point or points at which to evaluate the interpolant.
     |
     |      Returns
     |      -------
     |      y : array_like
     |          Interpolated values. Shape is determined by replacing
     |          the interpolation axis in the original array with the shape of `x`.
     |
     |      Notes
     |      -----
     |      Input values `x` must be convertible to `float` values like `int`
     |      or `float`.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.interpolate._polyint._Interpolator1D:
     |
     |  dtype

    class interp2d(builtins.object)
     |  interp2d(x, y, z, kind='linear', copy=True, bounds_error=False, fill_value=None)
     |
     |  interp2d(x, y, z, kind='linear', copy=True, bounds_error=False,
     |           fill_value=None)
     |
     |  .. versionremoved:: 1.14.0
     |
     |      `interp2d` has been removed in SciPy 1.14.0.
     |
     |      For legacy code, nearly bug-for-bug compatible replacements are
     |      `RectBivariateSpline` on regular grids, and `bisplrep`/`bisplev` for
     |      scattered 2D data.
     |
     |      In new code, for regular grids use `RegularGridInterpolator` instead.
     |      For scattered data, prefer `LinearNDInterpolator` or
     |      `CloughTocher2DInterpolator`.
     |
     |      For more details see :ref:`interp-transition-guide`.
     |
     |  Methods defined here:
     |
     |  __init__(self, x, y, z, kind='linear', copy=True, bounds_error=False, fill_value=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    approximate_taylor_polynomial(f, x, degree, scale, order=None)
        Estimate the Taylor polynomial of f at x by polynomial fitting.

        Parameters
        ----------
        f : callable
            The function whose Taylor polynomial is sought. Should accept
            a vector of `x` values.
        x : scalar
            The point at which the polynomial is to be evaluated.
        degree : int
            The degree of the Taylor polynomial
        scale : scalar
            The width of the interval to use to evaluate the Taylor polynomial.
            Function values spread over a range this wide are used to fit the
            polynomial. Must be chosen carefully.
        order : int or None, optional
            The order of the polynomial to be used in the fitting; `f` will be
            evaluated ``order+1`` times. If None, use `degree`.

        Returns
        -------
        p : poly1d instance
            The Taylor polynomial (translated to the origin, so that
            for example p(0)=f(x)).

        Notes
        -----
        The appropriate choice of "scale" is a trade-off; too large and the
        function differs from its Taylor polynomial too much to get a good
        answer, too small and round-off errors overwhelm the higher-order terms.
        The algorithm used becomes numerically unstable around order 30 even
        under ideal circumstances.

        Choosing order somewhat larger than degree may improve the higher-order
        terms.

        Examples
        --------
        We can calculate Taylor approximation polynomials of sin function with
        various degrees:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import approximate_taylor_polynomial
        >>> x = np.linspace(-10.0, 10.0, num=100)
        >>> plt.plot(x, np.sin(x), label="sin curve")
        >>> for degree in np.arange(1, 15, step=2):
        ...     sin_taylor = approximate_taylor_polynomial(np.sin, 0, degree, 1,
        ...                                                order=degree + 2)
        ...     plt.plot(x, sin_taylor(x), label=f"degree={degree}")
        >>> plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left',
        ...            borderaxespad=0.0, shadow=True)
        >>> plt.tight_layout()
        >>> plt.axis([-10, 10, -10, 10])
        >>> plt.show()

    barycentric_interpolate(xi, yi, x, axis=0, *, der=0)
        Convenience function for polynomial interpolation.

        Constructs a polynomial that passes through a given set of points,
        then evaluates the polynomial. For reasons of numerical stability,
        this function does not compute the coefficients of the polynomial.

        This function uses a "barycentric interpolation" method that treats
        the problem as a special case of rational function interpolation.
        This algorithm is quite stable, numerically, but even in a world of
        exact computation, unless the `x` coordinates are chosen very
        carefully - Chebyshev zeros (e.g., cos(i*pi/n)) are a good choice -
        polynomial interpolation itself is a very ill-conditioned process
        due to the Runge phenomenon.

        Parameters
        ----------
        xi : array_like
            1-D array of x coordinates of the points the polynomial should
            pass through
        yi : array_like
            The y coordinates of the points the polynomial should pass through.
        x : scalar or array_like
            Point or points at which to evaluate the interpolant.
        der : int or list or None, optional
            How many derivatives to evaluate, or None for all potentially
            nonzero derivatives (that is, a number equal to the number
            of points), or a list of derivatives to evaluate. This number
            includes the function value as the '0th' derivative.
        axis : int, optional
            Axis in the `yi` array corresponding to the x-coordinate values.

        Returns
        -------
        y : scalar or array_like
            Interpolated values. Shape is determined by replacing
            the interpolation axis in the original array with the shape of `x`.

        See Also
        --------
        BarycentricInterpolator : Barycentric interpolator

        Notes
        -----
        Construction of the interpolation weights is a relatively slow process.
        If you want to call this many times with the same xi (but possibly
        varying yi or x) you should use the class `BarycentricInterpolator`.
        This is what this function uses internally.

        Examples
        --------
        We can interpolate 2D observed data using barycentric interpolation:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import barycentric_interpolate
        >>> x_observed = np.linspace(0.0, 10.0, 11)
        >>> y_observed = np.sin(x_observed)
        >>> x = np.linspace(min(x_observed), max(x_observed), num=100)
        >>> y = barycentric_interpolate(x_observed, y_observed, x)
        >>> plt.plot(x_observed, y_observed, "o", label="observation")
        >>> plt.plot(x, y, label="barycentric interpolation")
        >>> plt.legend()
        >>> plt.show()

    bisplev(x, y, tck, dx=0, dy=0)
        Evaluate a bivariate B-spline and its derivatives.

        Return a rank-2 array of spline function values (or spline derivative
        values) at points given by the cross-product of the rank-1 arrays `x` and
        `y`.  In special cases, return an array or just a float if either `x` or
        `y` or both are floats.  Based on BISPEV and PARDER from FITPACK.

        Parameters
        ----------
        x, y : ndarray
            Rank-1 arrays specifying the domain over which to evaluate the
            spline or its derivative.
        tck : tuple
            A sequence of length 5 returned by `bisplrep` containing the knot
            locations, the coefficients, and the degree of the spline:
            [tx, ty, c, kx, ky].
        dx, dy : int, optional
            The orders of the partial derivatives in `x` and `y` respectively.

        Returns
        -------
        vals : ndarray
            The B-spline or its derivative evaluated over the set formed by
            the cross-product of `x` and `y`.

        See Also
        --------
        splprep, splrep, splint, sproot, splev
        UnivariateSpline, BivariateSpline

        Notes
        -----
            See `bisplrep` to generate the `tck` representation.

        References
        ----------
        .. [1] Dierckx P. : An algorithm for surface fitting
           with spline functions
           Ima J. Numer. Anal. 1 (1981) 267-283.
        .. [2] Dierckx P. : An algorithm for surface fitting
           with spline functions
           report tw50, Dept. Computer Science,K.U.Leuven, 1980.
        .. [3] Dierckx P. : Curve and surface fitting with splines,
           Monographs on Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-interpolate_2d_spline>`.

    bisplrep(x, y, z, w=None, xb=None, xe=None, yb=None, ye=None, kx=3, ky=3, task=0, s=None, eps=1e-16, tx=None, ty=None, full_output=0, nxest=None, nyest=None, quiet=1)
        Find a bivariate B-spline representation of a surface.

        Given a set of data points (x[i], y[i], z[i]) representing a surface
        z=f(x,y), compute a B-spline representation of the surface. Based on
        the routine SURFIT from FITPACK.

        Parameters
        ----------
        x, y, z : ndarray
            Rank-1 arrays of data points.
        w : ndarray, optional
            Rank-1 array of weights. By default ``w=np.ones(len(x))``.
        xb, xe : float, optional
            End points of approximation interval in `x`.
            By default ``xb = x.min(), xe=x.max()``.
        yb, ye : float, optional
            End points of approximation interval in `y`.
            By default ``yb=y.min(), ye = y.max()``.
        kx, ky : int, optional
            The degrees of the spline (1 <= kx, ky <= 5).
            Third order (kx=ky=3) is recommended.
        task : int, optional
            If task=0, find knots in x and y and coefficients for a given
            smoothing factor, s.
            If task=1, find knots and coefficients for another value of the
            smoothing factor, s.  bisplrep must have been previously called
            with task=0 or task=1.
            If task=-1, find coefficients for a given set of knots tx, ty.
        s : float, optional
            A non-negative smoothing factor. If weights correspond
            to the inverse of the standard-deviation of the errors in z,
            then a good s-value should be found in the range
            ``(m-sqrt(2*m),m+sqrt(2*m))`` where m=len(x).
        eps : float, optional
            A threshold for determining the effective rank of an
            over-determined linear system of equations (0 < eps < 1).
            `eps` is not likely to need changing.
        tx, ty : ndarray, optional
            Rank-1 arrays of the knots of the spline for task=-1
        full_output : int, optional
            Non-zero to return optional outputs.
        nxest, nyest : int, optional
            Over-estimates of the total number of knots. If None then
            ``nxest = max(kx+sqrt(m/2),2*kx+3)``,
            ``nyest = max(ky+sqrt(m/2),2*ky+3)``.
        quiet : int, optional
            Non-zero to suppress printing of messages.

        Returns
        -------
        tck : array_like
            A list [tx, ty, c, kx, ky] containing the knots (tx, ty) and
            coefficients (c) of the bivariate B-spline representation of the
            surface along with the degree of the spline.
        fp : ndarray
            The weighted sum of squared residuals of the spline approximation.
        ier : int
            An integer flag about splrep success. Success is indicated if
            ier<=0. If ier in [1,2,3] an error occurred but was not raised.
            Otherwise an error is raised.
        msg : str
            A message corresponding to the integer flag, ier.

        See Also
        --------
        splprep, splrep, splint, sproot, splev
        UnivariateSpline, BivariateSpline

        Notes
        -----
        See `bisplev` to evaluate the value of the B-spline given its tck
        representation.

        If the input data is such that input dimensions have incommensurate
        units and differ by many orders of magnitude, the interpolant may have
        numerical artifacts. Consider rescaling the data before interpolation.

        References
        ----------
        .. [1] Dierckx P.:An algorithm for surface fitting with spline functions
           Ima J. Numer. Anal. 1 (1981) 267-283.
        .. [2] Dierckx P.:An algorithm for surface fitting with spline functions
           report tw50, Dept. Computer Science,K.U.Leuven, 1980.
        .. [3] Dierckx P.:Curve and surface fitting with splines, Monographs on
           Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-interpolate_2d_spline>`.

    griddata(points, values, xi, method='linear', fill_value=nan, rescale=False)
        Interpolate unstructured D-D data.

        Parameters
        ----------
        points : 2-D ndarray of floats with shape (n, D), or length D tuple of 1-D ndarrays with shape (n,).
            Data point coordinates.
        values : ndarray of float or complex, shape (n,)
            Data values.
        xi : 2-D ndarray of floats with shape (m, D), or length D tuple of ndarrays broadcastable to the same shape.
            Points at which to interpolate data.
        method : {'linear', 'nearest', 'cubic'}, optional
            Method of interpolation. One of

            ``nearest``
              return the value at the data point closest to
              the point of interpolation. See `NearestNDInterpolator` for
              more details.

            ``linear``
              tessellate the input point set to N-D
              simplices, and interpolate linearly on each simplex. See
              `LinearNDInterpolator` for more details.

            ``cubic`` (1-D)
              return the value determined from a cubic
              spline.

            ``cubic`` (2-D)
              return the value determined from a
              piecewise cubic, continuously differentiable (C1), and
              approximately curvature-minimizing polynomial surface. See
              `CloughTocher2DInterpolator` for more details.
        fill_value : float, optional
            Value used to fill in for requested points outside of the
            convex hull of the input points. If not provided, then the
            default is ``nan``. This option has no effect for the
            'nearest' method.
        rescale : bool, optional
            Rescale points to unit cube before performing interpolation.
            This is useful if some of the input dimensions have
            incommensurable units and differ by many orders of magnitude.

            .. versionadded:: 0.14.0

        Returns
        -------
        ndarray
            Array of interpolated values.

        See Also
        --------
        LinearNDInterpolator :
            Piecewise linear interpolator in N dimensions.
        NearestNDInterpolator :
            Nearest-neighbor interpolator in N dimensions.
        CloughTocher2DInterpolator :
            Piecewise cubic, C1 smooth, curvature-minimizing interpolator in 2D.
        interpn : Interpolation on a regular grid or rectilinear grid.
        RegularGridInterpolator : Interpolator on a regular or rectilinear grid
                                  in arbitrary dimensions (`interpn` wraps this
                                  class).

        Notes
        -----

        .. versionadded:: 0.9

        .. note:: For data on a regular grid use `interpn` instead.

        Examples
        --------

        Suppose we want to interpolate the 2-D function

        >>> import numpy as np
        >>> def func(x, y):
        ...     return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2

        on a grid in [0, 1]x[0, 1]

        >>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j]

        but we only know its values at 1000 data points:

        >>> rng = np.random.default_rng()
        >>> points = rng.random((1000, 2))
        >>> values = func(points[:,0], points[:,1])

        This can be done with `griddata` -- below we try out all of the
        interpolation methods:

        >>> from scipy.interpolate import griddata
        >>> grid_z0 = griddata(points, values, (grid_x, grid_y), method='nearest')
        >>> grid_z1 = griddata(points, values, (grid_x, grid_y), method='linear')
        >>> grid_z2 = griddata(points, values, (grid_x, grid_y), method='cubic')

        One can see that the exact result is reproduced by all of the
        methods to some degree, but for this smooth function the piecewise
        cubic interpolant gives the best results:

        >>> import matplotlib.pyplot as plt
        >>> plt.subplot(221)
        >>> plt.imshow(func(grid_x, grid_y).T, extent=(0,1,0,1), origin='lower')
        >>> plt.plot(points[:,0], points[:,1], 'k.', ms=1)
        >>> plt.title('Original')
        >>> plt.subplot(222)
        >>> plt.imshow(grid_z0.T, extent=(0,1,0,1), origin='lower')
        >>> plt.title('Nearest')
        >>> plt.subplot(223)
        >>> plt.imshow(grid_z1.T, extent=(0,1,0,1), origin='lower')
        >>> plt.title('Linear')
        >>> plt.subplot(224)
        >>> plt.imshow(grid_z2.T, extent=(0,1,0,1), origin='lower')
        >>> plt.title('Cubic')
        >>> plt.gcf().set_size_inches(6, 6)
        >>> plt.show()

    insert(x, tck, m=1, per=0)
        Insert knots into a B-spline.

        Given the knots and coefficients of a B-spline representation, create a
        new B-spline with a knot inserted `m` times at point `x`.
        This is a wrapper around the FORTRAN routine insert of FITPACK.

        Parameters
        ----------
        x (u) : float
            A knot value at which to insert a new knot.  If `tck` was returned
            from ``splprep``, then the parameter values, u should be given.
        tck : a `BSpline` instance or a tuple
            If tuple, then it is expected to be a tuple (t,c,k) containing
            the vector of knots, the B-spline coefficients, and the degree of
            the spline.
        m : int, optional
            The number of times to insert the given knot (its multiplicity).
            Default is 1.
        per : int, optional
            If non-zero, the input spline is considered periodic.

        Returns
        -------
        BSpline instance or a tuple
            A new B-spline with knots t, coefficients c, and degree k.
            ``t(k+1) <= x <= t(n-k)``, where k is the degree of the spline.
            In case of a periodic spline (``per != 0``) there must be
            either at least k interior knots t(j) satisfying ``t(k+1)<t(j)<=x``
            or at least k interior knots t(j) satisfying ``x<=t(j)<t(n-k)``.
            A tuple is returned iff the input argument `tck` is a tuple, otherwise
            a BSpline object is constructed and returned.

        Notes
        -----
        Based on algorithms from [1]_ and [2]_.

        Manipulating the tck-tuples directly is not recommended. In new code,
        prefer using the `BSpline` objects, in particular `BSpline.insert_knot`
        method.

        See Also
        --------
        BSpline.insert_knot

        References
        ----------
        .. [1] W. Boehm, "Inserting new knots into b-spline curves.",
            Computer Aided Design, 12, p.199-201, 1980.
        .. [2] P. Dierckx, "Curve and surface fitting with splines, Monographs on
            Numerical Analysis", Oxford University Press, 1993.

        Examples
        --------
        You can insert knots into a B-spline.

        >>> from scipy.interpolate import splrep, insert
        >>> import numpy as np
        >>> x = np.linspace(0, 10, 5)
        >>> y = np.sin(x)
        >>> tck = splrep(x, y)
        >>> tck[0]
        array([ 0.,  0.,  0.,  0.,  5., 10., 10., 10., 10.])

        A knot is inserted:

        >>> tck_inserted = insert(3, tck)
        >>> tck_inserted[0]
        array([ 0.,  0.,  0.,  0.,  3.,  5., 10., 10., 10., 10.])

        Some knots are inserted:

        >>> tck_inserted2 = insert(8, tck, m=3)
        >>> tck_inserted2[0]
        array([ 0.,  0.,  0.,  0.,  5.,  8.,  8.,  8., 10., 10., 10., 10.])

    interpn(points, values, xi, method='linear', bounds_error=True, fill_value=nan)
        Multidimensional interpolation on regular or rectilinear grids.

        Strictly speaking, not all regular grids are supported - this function
        works on *rectilinear* grids, that is, a rectangular grid with even or
        uneven spacing.

        Parameters
        ----------
        points : tuple of ndarray of float, with shapes (m1, ), ..., (mn, )
            The points defining the regular grid in n dimensions. The points in
            each dimension (i.e. every elements of the points tuple) must be
            strictly ascending or descending.

        values : array_like, shape (m1, ..., mn, ...)
            The data on the regular grid in n dimensions. Complex data is
            accepted.

            .. deprecated:: 1.13.0
                Complex data is deprecated with ``method="pchip"`` and will raise an
                error in SciPy 1.15.0. This is because ``PchipInterpolator`` only
                works with real values. If you are trying to use the real components of
                the passed array, use ``np.real`` on ``values``.

        xi : ndarray of shape (..., ndim)
            The coordinates to sample the gridded data at

        method : str, optional
            The method of interpolation to perform. Supported are "linear",
            "nearest", "slinear", "cubic", "quintic", "pchip", and "splinef2d".
            "splinef2d" is only supported for 2-dimensional data.

        bounds_error : bool, optional
            If True, when interpolated values are requested outside of the
            domain of the input data, a ValueError is raised.
            If False, then `fill_value` is used.

        fill_value : number, optional
            If provided, the value to use for points outside of the
            interpolation domain. If None, values outside
            the domain are extrapolated.  Extrapolation is not supported by method
            "splinef2d".

        Returns
        -------
        values_x : ndarray, shape xi.shape[:-1] + values.shape[ndim:]
            Interpolated values at `xi`. See notes for behaviour when
            ``xi.ndim == 1``.

        See Also
        --------
        NearestNDInterpolator : Nearest neighbor interpolation on unstructured
                                data in N dimensions
        LinearNDInterpolator : Piecewise linear interpolant on unstructured data
                               in N dimensions
        RegularGridInterpolator : interpolation on a regular or rectilinear grid
                                  in arbitrary dimensions (`interpn` wraps this
                                  class).
        RectBivariateSpline : Bivariate spline approximation over a rectangular mesh
        scipy.ndimage.map_coordinates : interpolation on grids with equal spacing
                                        (suitable for e.g., N-D image resampling)

        Notes
        -----

        .. versionadded:: 0.14

        In the case that ``xi.ndim == 1`` a new axis is inserted into
        the 0 position of the returned array, values_x, so its shape is
        instead ``(1,) + values.shape[ndim:]``.

        If the input data is such that input dimensions have incommensurate
        units and differ by many orders of magnitude, the interpolant may have
        numerical artifacts. Consider rescaling the data before interpolation.

        Examples
        --------
        Evaluate a simple example function on the points of a regular 3-D grid:

        >>> import numpy as np
        >>> from scipy.interpolate import interpn
        >>> def value_func_3d(x, y, z):
        ...     return 2 * x + 3 * y - z
        >>> x = np.linspace(0, 4, 5)
        >>> y = np.linspace(0, 5, 6)
        >>> z = np.linspace(0, 6, 7)
        >>> points = (x, y, z)
        >>> values = value_func_3d(*np.meshgrid(*points, indexing='ij'))

        Evaluate the interpolating function at a point

        >>> point = np.array([2.21, 3.12, 1.15])
        >>> print(interpn(points, values, point))
        [12.63]

    krogh_interpolate(xi, yi, x, der=0, axis=0)
        Convenience function for polynomial interpolation.

        See `KroghInterpolator` for more details.

        Parameters
        ----------
        xi : array_like
            Interpolation points (known x-coordinates).
        yi : array_like
            Known y-coordinates, of shape ``(xi.size, R)``. Interpreted as
            vectors of length R, or scalars if R=1.
        x : array_like
            Point or points at which to evaluate the derivatives.
        der : int or list or None, optional
            How many derivatives to evaluate, or None for all potentially
            nonzero derivatives (that is, a number equal to the number
            of points), or a list of derivatives to evaluate. This number
            includes the function value as the '0th' derivative.
        axis : int, optional
            Axis in the `yi` array corresponding to the x-coordinate values.

        Returns
        -------
        d : ndarray
            If the interpolator's values are R-D then the
            returned array will be the number of derivatives by N by R.
            If `x` is a scalar, the middle dimension will be dropped; if
            the `yi` are scalars then the last dimension will be dropped.

        See Also
        --------
        KroghInterpolator : Krogh interpolator

        Notes
        -----
        Construction of the interpolating polynomial is a relatively expensive
        process. If you want to evaluate it repeatedly consider using the class
        KroghInterpolator (which is what this function uses).

        Examples
        --------
        We can interpolate 2D observed data using Krogh interpolation:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import krogh_interpolate
        >>> x_observed = np.linspace(0.0, 10.0, 11)
        >>> y_observed = np.sin(x_observed)
        >>> x = np.linspace(min(x_observed), max(x_observed), num=100)
        >>> y = krogh_interpolate(x_observed, y_observed, x)
        >>> plt.plot(x_observed, y_observed, "o", label="observation")
        >>> plt.plot(x, y, label="krogh interpolation")
        >>> plt.legend()
        >>> plt.show()

    lagrange(x, w)
        Return a Lagrange interpolating polynomial.

        Given two 1-D arrays `x` and `w,` returns the Lagrange interpolating
        polynomial through the points ``(x, w)``.

        Warning: This implementation is numerically unstable. Do not expect to
        be able to use more than about 20 points even if they are chosen optimally.

        Parameters
        ----------
        x : array_like
            `x` represents the x-coordinates of a set of datapoints.
        w : array_like
            `w` represents the y-coordinates of a set of datapoints, i.e., f(`x`).

        Returns
        -------
        lagrange : `numpy.poly1d` instance
            The Lagrange interpolating polynomial.

        Examples
        --------
        Interpolate :math:`f(x) = x^3` by 3 points.

        >>> import numpy as np
        >>> from scipy.interpolate import lagrange
        >>> x = np.array([0, 1, 2])
        >>> y = x**3
        >>> poly = lagrange(x, y)

        Since there are only 3 points, Lagrange polynomial has degree 2. Explicitly,
        it is given by

        .. math::

            \begin{aligned}
                L(x) &= 1\times \frac{x (x - 2)}{-1} + 8\times \frac{x (x-1)}{2} \\
                     &= x (-2 + 3x)
            \end{aligned}

        >>> from numpy.polynomial.polynomial import Polynomial
        >>> Polynomial(poly.coef[::-1]).coef
        array([ 0., -2.,  3.])

        >>> import matplotlib.pyplot as plt
        >>> x_new = np.arange(0, 2.1, 0.1)
        >>> plt.scatter(x, y, label='data')
        >>> plt.plot(x_new, Polynomial(poly.coef[::-1])(x_new), label='Polynomial')
        >>> plt.plot(x_new, 3*x_new**2 - 2*x_new + 0*x_new,
        ...          label=r"$3 x^2 - 2 x$", linestyle='-.')
        >>> plt.legend()
        >>> plt.show()

    make_interp_spline(x, y, k=3, t=None, bc_type=None, axis=0, check_finite=True)
        Compute the (coefficients of) interpolating B-spline.

        Parameters
        ----------
        x : array_like, shape (n,)
            Abscissas.
        y : array_like, shape (n, ...)
            Ordinates.
        k : int, optional
            B-spline degree. Default is cubic, ``k = 3``.
        t : array_like, shape (nt + k + 1,), optional.
            Knots.
            The number of knots needs to agree with the number of data points and
            the number of derivatives at the edges. Specifically, ``nt - n`` must
            equal ``len(deriv_l) + len(deriv_r)``.
        bc_type : 2-tuple or None
            Boundary conditions.
            Default is None, which means choosing the boundary conditions
            automatically. Otherwise, it must be a length-two tuple where the first
            element (``deriv_l``) sets the boundary conditions at ``x[0]`` and
            the second element (``deriv_r``) sets the boundary conditions at
            ``x[-1]``. Each of these must be an iterable of pairs
            ``(order, value)`` which gives the values of derivatives of specified
            orders at the given edge of the interpolation interval.
            Alternatively, the following string aliases are recognized:

            * ``"clamped"``: The first derivatives at the ends are zero. This is
               equivalent to ``bc_type=([(1, 0.0)], [(1, 0.0)])``.
            * ``"natural"``: The second derivatives at ends are zero. This is
              equivalent to ``bc_type=([(2, 0.0)], [(2, 0.0)])``.
            * ``"not-a-knot"`` (default): The first and second segments are the
              same polynomial. This is equivalent to having ``bc_type=None``.
            * ``"periodic"``: The values and the first ``k-1`` derivatives at the
              ends are equivalent.

        axis : int, optional
            Interpolation axis. Default is 0.
        check_finite : bool, optional
            Whether to check that the input arrays contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
            Default is True.

        Returns
        -------
        b : a BSpline object of the degree ``k`` and with knots ``t``.

        See Also
        --------
        BSpline : base class representing the B-spline objects
        CubicSpline : a cubic spline in the polynomial basis
        make_lsq_spline : a similar factory function for spline fitting
        UnivariateSpline : a wrapper over FITPACK spline fitting routines
        splrep : a wrapper over FITPACK spline fitting routines

        Examples
        --------

        Use cubic interpolation on Chebyshev nodes:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> def cheb_nodes(N):
        ...     jj = 2.*np.arange(N) + 1
        ...     x = np.cos(np.pi * jj / 2 / N)[::-1]
        ...     return x

        >>> x = cheb_nodes(20)
        >>> y = np.sqrt(1 - x**2)

        >>> from scipy.interpolate import BSpline, make_interp_spline
        >>> b = make_interp_spline(x, y)
        >>> np.allclose(b(x), y)
        True

        Note that the default is a cubic spline with a not-a-knot boundary condition

        >>> b.k
        3

        Here we use a 'natural' spline, with zero 2nd derivatives at edges:

        >>> l, r = [(2, 0.0)], [(2, 0.0)]
        >>> b_n = make_interp_spline(x, y, bc_type=(l, r))  # or, bc_type="natural"
        >>> np.allclose(b_n(x), y)
        True
        >>> x0, x1 = x[0], x[-1]
        >>> np.allclose([b_n(x0, 2), b_n(x1, 2)], [0, 0])
        True

        Interpolation of parametric curves is also supported. As an example, we
        compute a discretization of a snail curve in polar coordinates

        >>> phi = np.linspace(0, 2.*np.pi, 40)
        >>> r = 0.3 + np.cos(phi)
        >>> x, y = r*np.cos(phi), r*np.sin(phi)  # convert to Cartesian coordinates

        Build an interpolating curve, parameterizing it by the angle

        >>> spl = make_interp_spline(phi, np.c_[x, y])

        Evaluate the interpolant on a finer grid (note that we transpose the result
        to unpack it into a pair of x- and y-arrays)

        >>> phi_new = np.linspace(0, 2.*np.pi, 100)
        >>> x_new, y_new = spl(phi_new).T

        Plot the result

        >>> plt.plot(x, y, 'o')
        >>> plt.plot(x_new, y_new, '-')
        >>> plt.show()

        Build a B-spline curve with 2 dimensional y

        >>> x = np.linspace(0, 2*np.pi, 10)
        >>> y = np.array([np.sin(x), np.cos(x)])

        Periodic condition is satisfied because y coordinates of points on the ends
        are equivalent

        >>> ax = plt.axes(projection='3d')
        >>> xx = np.linspace(0, 2*np.pi, 100)
        >>> bspl = make_interp_spline(x, y, k=5, bc_type='periodic', axis=1)
        >>> ax.plot3D(xx, *bspl(xx))
        >>> ax.scatter3D(x, *y, color='red')
        >>> plt.show()

    make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True)
        Compute the (coefficients of) an LSQ (Least SQuared) based
        fitting B-spline.

        The result is a linear combination

        .. math::

                S(x) = \sum_j c_j B_j(x; t)

        of the B-spline basis elements, :math:`B_j(x; t)`, which minimizes

        .. math::

            \sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2

        Parameters
        ----------
        x : array_like, shape (m,)
            Abscissas.
        y : array_like, shape (m, ...)
            Ordinates.
        t : array_like, shape (n + k + 1,).
            Knots.
            Knots and data points must satisfy Schoenberg-Whitney conditions.
        k : int, optional
            B-spline degree. Default is cubic, ``k = 3``.
        w : array_like, shape (m,), optional
            Weights for spline fitting. Must be positive. If ``None``,
            then weights are all equal.
            Default is ``None``.
        axis : int, optional
            Interpolation axis. Default is zero.
        check_finite : bool, optional
            Whether to check that the input arrays contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
            Default is True.

        Returns
        -------
        b : a BSpline object of the degree ``k`` with knots ``t``.

        See Also
        --------
        BSpline : base class representing the B-spline objects
        make_interp_spline : a similar factory function for interpolating splines
        LSQUnivariateSpline : a FITPACK-based spline fitting routine
        splrep : a FITPACK-based fitting routine

        Notes
        -----
        The number of data points must be larger than the spline degree ``k``.

        Knots ``t`` must satisfy the Schoenberg-Whitney conditions,
        i.e., there must be a subset of data points ``x[j]`` such that
        ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.

        Examples
        --------
        Generate some noisy data:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> x = np.linspace(-3, 3, 50)
        >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)

        Now fit a smoothing cubic spline with a pre-defined internal knots.
        Here we make the knot vector (k+1)-regular by adding boundary knots:

        >>> from scipy.interpolate import make_lsq_spline, BSpline
        >>> t = [-1, 0, 1]
        >>> k = 3
        >>> t = np.r_[(x[0],)*(k+1),
        ...           t,
        ...           (x[-1],)*(k+1)]
        >>> spl = make_lsq_spline(x, y, t, k)

        For comparison, we also construct an interpolating spline for the same
        set of data:

        >>> from scipy.interpolate import make_interp_spline
        >>> spl_i = make_interp_spline(x, y)

        Plot both:

        >>> xs = np.linspace(-3, 3, 100)
        >>> plt.plot(x, y, 'ro', ms=5)
        >>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline')
        >>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline')
        >>> plt.legend(loc='best')
        >>> plt.show()

        **NaN handling**: If the input arrays contain ``nan`` values, the result is
        not useful since the underlying spline fitting routines cannot deal with
        ``nan``. A workaround is to use zero weights for not-a-number data points:

        >>> y[8] = np.nan
        >>> w = np.isnan(y)
        >>> y[w] = 0.
        >>> tck = make_lsq_spline(x, y, t, w=~w)

        Notice the need to replace a ``nan`` by a numerical value (precise value
        does not matter as long as the corresponding weight is zero.)

    make_smoothing_spline(x, y, w=None, lam=None)
        Compute the (coefficients of) smoothing cubic spline function using
        ``lam`` to control the tradeoff between the amount of smoothness of the
        curve and its proximity to the data. In case ``lam`` is None, using the
        GCV criteria [1] to find it.

        A smoothing spline is found as a solution to the regularized weighted
        linear regression problem:

        .. math::

            \sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2 +
            \lambda\int\limits_{x_1}^{x_n} (f^{(2)}(u))^2 d u

        where :math:`f` is a spline function, :math:`w` is a vector of weights and
        :math:`\lambda` is a regularization parameter.

        If ``lam`` is None, we use the GCV criteria to find an optimal
        regularization parameter, otherwise we solve the regularized weighted
        linear regression problem with given parameter. The parameter controls
        the tradeoff in the following way: the larger the parameter becomes, the
        smoother the function gets.

        Parameters
        ----------
        x : array_like, shape (n,)
            Abscissas. `n` must be at least 5.
        y : array_like, shape (n,)
            Ordinates. `n` must be at least 5.
        w : array_like, shape (n,), optional
            Vector of weights. Default is ``np.ones_like(x)``.
        lam : float, (:math:`\lambda \geq 0`), optional
            Regularization parameter. If ``lam`` is None, then it is found from
            the GCV criteria. Default is None.

        Returns
        -------
        func : a BSpline object.
            A callable representing a spline in the B-spline basis
            as a solution of the problem of smoothing splines using
            the GCV criteria [1] in case ``lam`` is None, otherwise using the
            given parameter ``lam``.

        Notes
        -----
        This algorithm is a clean room reimplementation of the algorithm
        introduced by Woltring in FORTRAN [2]. The original version cannot be used
        in SciPy source code because of the license issues. The details of the
        reimplementation are discussed here (available only in Russian) [4].

        If the vector of weights ``w`` is None, we assume that all the points are
        equal in terms of weights, and vector of weights is vector of ones.

        Note that in weighted residual sum of squares, weights are not squared:
        :math:`\sum\limits_{i=1}^n w_i\lvert y_i - f(x_i) \rvert^2` while in
        ``splrep`` the sum is built from the squared weights.

        In cases when the initial problem is ill-posed (for example, the product
        :math:`X^T W X` where :math:`X` is a design matrix is not a positive
        defined matrix) a ValueError is raised.

        References
        ----------
        .. [1] G. Wahba, "Estimating the smoothing parameter" in Spline models for
            observational data, Philadelphia, Pennsylvania: Society for Industrial
            and Applied Mathematics, 1990, pp. 45-65.
            :doi:`10.1137/1.9781611970128`
        .. [2] H. J. Woltring, A Fortran package for generalized, cross-validatory
            spline smoothing and differentiation, Advances in Engineering
            Software, vol. 8, no. 2, pp. 104-113, 1986.
            :doi:`10.1016/0141-1195(86)90098-7`
        .. [3] T. Hastie, J. Friedman, and R. Tisbshirani, "Smoothing Splines" in
            The elements of Statistical Learning: Data Mining, Inference, and
            prediction, New York: Springer, 2017, pp. 241-249.
            :doi:`10.1007/978-0-387-84858-7`
        .. [4] E. Zemlyanoy, "Generalized cross-validation smoothing splines",
            BSc thesis, 2022.
            `<https://www.hse.ru/ba/am/students/diplomas/620910604>`_ (in
            Russian)

        Examples
        --------
        Generate some noisy data

        >>> import numpy as np
        >>> np.random.seed(1234)
        >>> n = 200
        >>> def func(x):
        ...    return x**3 + x**2 * np.sin(4 * x)
        >>> x = np.sort(np.random.random_sample(n) * 4 - 2)
        >>> y = func(x) + np.random.normal(scale=1.5, size=n)

        Make a smoothing spline function

        >>> from scipy.interpolate import make_smoothing_spline
        >>> spl = make_smoothing_spline(x, y)

        Plot both

        >>> import matplotlib.pyplot as plt
        >>> grid = np.linspace(x[0], x[-1], 400)
        >>> plt.plot(grid, spl(grid), label='Spline')
        >>> plt.plot(grid, func(grid), label='Original function')
        >>> plt.scatter(x, y, marker='.')
        >>> plt.legend(loc='best')
        >>> plt.show()

    pade(an, m, n=None)
        Return Pade approximation to a polynomial as the ratio of two polynomials.

        Parameters
        ----------
        an : (N,) array_like
            Taylor series coefficients.
        m : int
            The order of the returned approximating polynomial `q`.
        n : int, optional
            The order of the returned approximating polynomial `p`. By default,
            the order is ``len(an)-1-m``.

        Returns
        -------
        p, q : Polynomial class
            The Pade approximation of the polynomial defined by `an` is
            ``p(x)/q(x)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.interpolate import pade
        >>> e_exp = [1.0, 1.0, 1.0/2.0, 1.0/6.0, 1.0/24.0, 1.0/120.0]
        >>> p, q = pade(e_exp, 2)

        >>> e_exp.reverse()
        >>> e_poly = np.poly1d(e_exp)

        Compare ``e_poly(x)`` and the Pade approximation ``p(x)/q(x)``

        >>> e_poly(1)
        2.7166666666666668

        >>> p(1)/q(1)
        2.7179487179487181

    pchip_interpolate(xi, yi, x, der=0, axis=0)
        Convenience function for pchip interpolation.

        xi and yi are arrays of values used to approximate some function f,
        with ``yi = f(xi)``. The interpolant uses monotonic cubic splines
        to find the value of new points x and the derivatives there.

        See `scipy.interpolate.PchipInterpolator` for details.

        Parameters
        ----------
        xi : array_like
            A sorted list of x-coordinates, of length N.
        yi : array_like
            A 1-D array of real values. `yi`'s length along the interpolation
            axis must be equal to the length of `xi`. If N-D array, use axis
            parameter to select correct axis.

            .. deprecated:: 1.13.0
                Complex data is deprecated and will raise an error in
                SciPy 1.15.0. If you are trying to use the real components of
                the passed array, use ``np.real`` on `yi`.

        x : scalar or array_like
            Of length M.
        der : int or list, optional
            Derivatives to extract. The 0th derivative can be included to
            return the function value.
        axis : int, optional
            Axis in the yi array corresponding to the x-coordinate values.

        Returns
        -------
        y : scalar or array_like
            The result, of length R or length M or M by R.

        See Also
        --------
        PchipInterpolator : PCHIP 1-D monotonic cubic interpolator.

        Examples
        --------
        We can interpolate 2D observed data using pchip interpolation:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import pchip_interpolate
        >>> x_observed = np.linspace(0.0, 10.0, 11)
        >>> y_observed = np.sin(x_observed)
        >>> x = np.linspace(min(x_observed), max(x_observed), num=100)
        >>> y = pchip_interpolate(x_observed, y_observed, x)
        >>> plt.plot(x_observed, y_observed, "o", label="observation")
        >>> plt.plot(x, y, label="pchip interpolation")
        >>> plt.legend()
        >>> plt.show()

    spalde(x, tck)
        Evaluate a B-spline and all its derivatives at one point (or set of points) up
        to order k (the degree of the spline), being 0 the spline itself.

        Parameters
        ----------
        x : array_like
            A point or a set of points at which to evaluate the derivatives.
            Note that ``t(k) <= x <= t(n-k+1)`` must hold for each `x`.
        tck : tuple
            A tuple (t,c,k) containing the vector of knots,
            the B-spline coefficients, and the degree of the spline whose
            derivatives to compute.

        Returns
        -------
        results : {ndarray, list of ndarrays}
            An array (or a list of arrays) containing all derivatives
            up to order k inclusive for each point `x`, being the first element the
            spline itself.

        See Also
        --------
        splprep, splrep, splint, sproot, splev, bisplrep, bisplev,
        UnivariateSpline, BivariateSpline

        References
        ----------
        .. [1] de Boor C : On calculating with b-splines, J. Approximation Theory
           6 (1972) 50-62.
        .. [2] Cox M.G. : The numerical evaluation of b-splines, J. Inst. Maths
           applics 10 (1972) 134-149.
        .. [3] Dierckx P. : Curve and surface fitting with splines, Monographs on
           Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        To calculate the derivatives of a B-spline there are several aproaches.
        In this example, we will demonstrate that `spalde` is equivalent to
        calling `splev` and `splder`.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import BSpline, spalde, splder, splev

        >>> # Store characteristic parameters of a B-spline
        >>> tck = ((-2, -2, -2, -2, -1, 0, 1, 2, 2, 2, 2),  # knots
        ...        (0, 0, 0, 6, 0, 0, 0),  # coefficients
        ...        3)  # degree (cubic)
        >>> # Instance a B-spline object
        >>> # `BSpline` objects are prefered, except for spalde()
        >>> bspl = BSpline(tck[0], tck[1], tck[2])
        >>> # Generate extra points to get a smooth curve
        >>> x = np.linspace(min(tck[0]), max(tck[0]), 100)

        Evaluate the curve and all derivatives

        >>> # The order of derivative must be less or equal to k, the degree of the spline
        >>> # Method 1: spalde()
        >>> f1_y_bsplin = [spalde(i, tck)[0] for i in x ]  # The B-spline itself
        >>> f1_y_deriv1 = [spalde(i, tck)[1] for i in x ]  # 1st derivative
        >>> f1_y_deriv2 = [spalde(i, tck)[2] for i in x ]  # 2nd derivative
        >>> f1_y_deriv3 = [spalde(i, tck)[3] for i in x ]  # 3rd derivative
        >>> # You can reach the same result by using `splev`and `splder`
        >>> f2_y_deriv3 = splev(x, bspl, der=3)
        >>> f3_y_deriv3 = splder(bspl, n=3)(x)

        >>> # Generate a figure with three axes for graphic comparison
        >>> fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(16, 5))
        >>> suptitle = fig.suptitle(f'Evaluate a B-spline and all derivatives')
        >>> # Plot B-spline and all derivatives using the three methods
        >>> orders = range(4)
        >>> linetypes = ['-', '--', '-.', ':']
        >>> labels = ['B-Spline', '1st deriv.', '2nd deriv.', '3rd deriv.']
        >>> functions = ['splev()', 'splder()', 'spalde()']
        >>> for order, linetype, label in zip(orders, linetypes, labels):
        ...     ax1.plot(x, splev(x, bspl, der=order), linetype, label=label)
        ...     ax2.plot(x, splder(bspl, n=order)(x), linetype, label=label)
        ...     ax3.plot(x, [spalde(i, tck)[order] for i in x], linetype, label=label)
        >>> for ax, function in zip((ax1, ax2, ax3), functions):
        ...     ax.set_title(function)
        ...     ax.legend()
        >>> plt.tight_layout()
        >>> plt.show()

    splantider(tck, n=1)
        Compute the spline for the antiderivative (integral) of a given spline.

        Parameters
        ----------
        tck : BSpline instance or a tuple of (t, c, k)
            Spline whose antiderivative to compute
        n : int, optional
            Order of antiderivative to evaluate. Default: 1

        Returns
        -------
        BSpline instance or a tuple of (t2, c2, k2)
            Spline of order k2=k+n representing the antiderivative of the input
            spline.
            A tuple is returned iff the input argument `tck` is a tuple, otherwise
            a BSpline object is constructed and returned.

        See Also
        --------
        splder, splev, spalde
        BSpline

        Notes
        -----
        The `splder` function is the inverse operation of this function.
        Namely, ``splder(splantider(tck))`` is identical to `tck`, modulo
        rounding error.

        .. versionadded:: 0.13.0

        Examples
        --------
        >>> from scipy.interpolate import splrep, splder, splantider, splev
        >>> import numpy as np
        >>> x = np.linspace(0, np.pi/2, 70)
        >>> y = 1 / np.sqrt(1 - 0.8*np.sin(x)**2)
        >>> spl = splrep(x, y)

        The derivative is the inverse operation of the antiderivative,
        although some floating point error accumulates:

        >>> splev(1.7, spl), splev(1.7, splder(splantider(spl)))
        (array(2.1565429877197317), array(2.1565429877201865))

        Antiderivative can be used to evaluate definite integrals:

        >>> ispl = splantider(spl)
        >>> splev(np.pi/2, ispl) - splev(0, ispl)
        2.2572053588768486

        This is indeed an approximation to the complete elliptic integral
        :math:`K(m) = \int_0^{\pi/2} [1 - m\sin^2 x]^{-1/2} dx`:

        >>> from scipy.special import ellipk
        >>> ellipk(0.8)
        2.2572053268208538

    splder(tck, n=1)
        Compute the spline representation of the derivative of a given spline

        Parameters
        ----------
        tck : BSpline instance or tuple
            BSpline instance or a tuple (t,c,k) containing the vector of knots,
            the B-spline coefficients, and the degree of the spline whose
            derivative to compute
        n : int, optional
            Order of derivative to evaluate. Default: 1

        Returns
        -------
        `BSpline` instance or tuple
            Spline of order k2=k-n representing the derivative
            of the input spline.
            A tuple is returned if the input argument `tck` is a tuple, otherwise
            a BSpline object is constructed and returned.

        See Also
        --------
        splantider, splev, spalde
        BSpline

        Notes
        -----

        .. versionadded:: 0.13.0

        Examples
        --------
        This can be used for finding maxima of a curve:

        >>> from scipy.interpolate import splrep, splder, sproot
        >>> import numpy as np
        >>> x = np.linspace(0, 10, 70)
        >>> y = np.sin(x)
        >>> spl = splrep(x, y, k=4)

        Now, differentiate the spline and find the zeros of the
        derivative. (NB: `sproot` only works for order 3 splines, so we
        fit an order 4 spline):

        >>> dspl = splder(spl)
        >>> sproot(dspl) / np.pi
        array([ 0.50000001,  1.5       ,  2.49999998])

        This agrees well with roots :math:`\pi/2 + n\pi` of
        :math:`\cos(x) = \sin'(x)`.

        A comparison between `splev`, `splder` and `spalde` to compute the derivatives of a
        B-spline can be found in the `spalde` examples section.

    splev(x, tck, der=0, ext=0)
        Evaluate a B-spline or its derivatives.

        Given the knots and coefficients of a B-spline representation, evaluate
        the value of the smoothing polynomial and its derivatives. This is a
        wrapper around the FORTRAN routines splev and splder of FITPACK.

        Parameters
        ----------
        x : array_like
            An array of points at which to return the value of the smoothed
            spline or its derivatives. If `tck` was returned from `splprep`,
            then the parameter values, u should be given.
        tck : BSpline instance or tuple
            If a tuple, then it should be a sequence of length 3 returned by
            `splrep` or `splprep` containing the knots, coefficients, and degree
            of the spline. (Also see Notes.)
        der : int, optional
            The order of derivative of the spline to compute (must be less than
            or equal to k, the degree of the spline).
        ext : int, optional
            Controls the value returned for elements of ``x`` not in the
            interval defined by the knot sequence.

            * if ext=0, return the extrapolated value.
            * if ext=1, return 0
            * if ext=2, raise a ValueError
            * if ext=3, return the boundary value.

            The default value is 0.

        Returns
        -------
        y : ndarray or list of ndarrays
            An array of values representing the spline function evaluated at
            the points in `x`.  If `tck` was returned from `splprep`, then this
            is a list of arrays representing the curve in an N-D space.

        See Also
        --------
        splprep, splrep, sproot, spalde, splint
        bisplrep, bisplev
        BSpline

        Notes
        -----
        Manipulating the tck-tuples directly is not recommended. In new code,
        prefer using `BSpline` objects.

        References
        ----------
        .. [1] C. de Boor, "On calculating with b-splines", J. Approximation
            Theory, 6, p.50-62, 1972.
        .. [2] M. G. Cox, "The numerical evaluation of b-splines", J. Inst. Maths
            Applics, 10, p.134-149, 1972.
        .. [3] P. Dierckx, "Curve and surface fitting with splines", Monographs
            on Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-interpolate_splXXX>`.

        A comparison between `splev`, `splder` and `spalde` to compute the derivatives of a
        B-spline can be found in the `spalde` examples section.

    splint(a, b, tck, full_output=0)
        Evaluate the definite integral of a B-spline between two given points.

        Parameters
        ----------
        a, b : float
            The end-points of the integration interval.
        tck : tuple or a BSpline instance
            If a tuple, then it should be a sequence of length 3, containing the
            vector of knots, the B-spline coefficients, and the degree of the
            spline (see `splev`).
        full_output : int, optional
            Non-zero to return optional output.

        Returns
        -------
        integral : float
            The resulting integral.
        wrk : ndarray
            An array containing the integrals of the normalized B-splines
            defined on the set of knots.
            (Only returned if `full_output` is non-zero)

        See Also
        --------
        splprep, splrep, sproot, spalde, splev
        bisplrep, bisplev
        BSpline

        Notes
        -----
        `splint` silently assumes that the spline function is zero outside the data
        interval (`a`, `b`).

        Manipulating the tck-tuples directly is not recommended. In new code,
        prefer using the `BSpline` objects.

        References
        ----------
        .. [1] P.W. Gaffney, The calculation of indefinite integrals of b-splines",
            J. Inst. Maths Applics, 17, p.37-41, 1976.
        .. [2] P. Dierckx, "Curve and surface fitting with splines", Monographs
            on Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-interpolate_splXXX>`.

    splprep(x, w=None, u=None, ub=None, ue=None, k=3, task=0, s=None, t=None, full_output=0, nest=None, per=0, quiet=1)
        Find the B-spline representation of an N-D curve.

        Given a list of N rank-1 arrays, `x`, which represent a curve in
        N-dimensional space parametrized by `u`, find a smooth approximating
        spline curve g(`u`). Uses the FORTRAN routine parcur from FITPACK.

        Parameters
        ----------
        x : array_like
            A list of sample vector arrays representing the curve.
        w : array_like, optional
            Strictly positive rank-1 array of weights the same length as `x[0]`.
            The weights are used in computing the weighted least-squares spline
            fit. If the errors in the `x` values have standard-deviation given by
            the vector d, then `w` should be 1/d. Default is ``ones(len(x[0]))``.
        u : array_like, optional
            An array of parameter values. If not given, these values are
            calculated automatically as ``M = len(x[0])``, where

                v[0] = 0

                v[i] = v[i-1] + distance(`x[i]`, `x[i-1]`)

                u[i] = v[i] / v[M-1]

        ub, ue : int, optional
            The end-points of the parameters interval.  Defaults to
            u[0] and u[-1].
        k : int, optional
            Degree of the spline. Cubic splines are recommended.
            Even values of `k` should be avoided especially with a small s-value.
            ``1 <= k <= 5``, default is 3.
        task : int, optional
            If task==0 (default), find t and c for a given smoothing factor, s.
            If task==1, find t and c for another value of the smoothing factor, s.
            There must have been a previous call with task=0 or task=1
            for the same set of data.
            If task=-1 find the weighted least square spline for a given set of
            knots, t.
        s : float, optional
            A smoothing condition.  The amount of smoothness is determined by
            satisfying the conditions: ``sum((w * (y - g))**2,axis=0) <= s``,
            where g(x) is the smoothed interpolation of (x,y).  The user can
            use `s` to control the trade-off between closeness and smoothness
            of fit.  Larger `s` means more smoothing while smaller values of `s`
            indicate less smoothing. Recommended values of `s` depend on the
            weights, w.  If the weights represent the inverse of the
            standard-deviation of y, then a good `s` value should be found in
            the range ``(m-sqrt(2*m),m+sqrt(2*m))``, where m is the number of
            data points in x, y, and w.
        t : array, optional
            The knots needed for ``task=-1``.
            There must be at least ``2*k+2`` knots.
        full_output : int, optional
            If non-zero, then return optional outputs.
        nest : int, optional
            An over-estimate of the total number of knots of the spline to
            help in determining the storage space.  By default nest=m/2.
            Always large enough is nest=m+k+1.
        per : int, optional
           If non-zero, data points are considered periodic with period
           ``x[m-1] - x[0]`` and a smooth periodic spline approximation is
           returned.  Values of ``y[m-1]`` and ``w[m-1]`` are not used.
        quiet : int, optional
             Non-zero to suppress messages.

        Returns
        -------
        tck : tuple
            A tuple, ``(t,c,k)`` containing the vector of knots, the B-spline
            coefficients, and the degree of the spline.
        u : array
            An array of the values of the parameter.
        fp : float
            The weighted sum of squared residuals of the spline approximation.
        ier : int
            An integer flag about splrep success.  Success is indicated
            if ier<=0. If ier in [1,2,3] an error occurred but was not raised.
            Otherwise an error is raised.
        msg : str
            A message corresponding to the integer flag, ier.

        See Also
        --------
        splrep, splev, sproot, spalde, splint,
        bisplrep, bisplev
        UnivariateSpline, BivariateSpline
        BSpline
        make_interp_spline

        Notes
        -----
        See `splev` for evaluation of the spline and its derivatives.
        The number of dimensions N must be smaller than 11.

        The number of coefficients in the `c` array is ``k+1`` less than the number
        of knots, ``len(t)``. This is in contrast with `splrep`, which zero-pads
        the array of coefficients to have the same length as the array of knots.
        These additional coefficients are ignored by evaluation routines, `splev`
        and `BSpline`.

        References
        ----------
        .. [1] P. Dierckx, "Algorithms for smoothing data with periodic and
            parametric splines, Computer Graphics and Image Processing",
            20 (1982) 171-184.
        .. [2] P. Dierckx, "Algorithms for smoothing data with periodic and
            parametric splines", report tw55, Dept. Computer Science,
            K.U.Leuven, 1981.
        .. [3] P. Dierckx, "Curve and surface fitting with splines", Monographs on
            Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        Generate a discretization of a limacon curve in the polar coordinates:

        >>> import numpy as np
        >>> phi = np.linspace(0, 2.*np.pi, 40)
        >>> r = 0.5 + np.cos(phi)         # polar coords
        >>> x, y = r * np.cos(phi), r * np.sin(phi)    # convert to cartesian

        And interpolate:

        >>> from scipy.interpolate import splprep, splev
        >>> tck, u = splprep([x, y], s=0)
        >>> new_points = splev(u, tck)

        Notice that (i) we force interpolation by using `s=0`,
        (ii) the parameterization, ``u``, is generated automatically.
        Now plot the result:

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, y, 'ro')
        >>> ax.plot(new_points[0], new_points[1], 'r-')
        >>> plt.show()

    splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0, per=0, quiet=1)
        Find the B-spline representation of a 1-D curve.

        Given the set of data points ``(x[i], y[i])`` determine a smooth spline
        approximation of degree k on the interval ``xb <= x <= xe``.

        Parameters
        ----------
        x, y : array_like
            The data points defining a curve ``y = f(x)``.
        w : array_like, optional
            Strictly positive rank-1 array of weights the same length as `x` and `y`.
            The weights are used in computing the weighted least-squares spline
            fit. If the errors in the `y` values have standard-deviation given by the
            vector ``d``, then `w` should be ``1/d``. Default is ``ones(len(x))``.
        xb, xe : float, optional
            The interval to fit.  If None, these default to ``x[0]`` and ``x[-1]``
            respectively.
        k : int, optional
            The degree of the spline fit. It is recommended to use cubic splines.
            Even values of `k` should be avoided especially with small `s` values.
            ``1 <= k <= 5``.
        task : {1, 0, -1}, optional
            If ``task==0``, find ``t`` and ``c`` for a given smoothing factor, `s`.

            If ``task==1`` find ``t`` and ``c`` for another value of the smoothing factor,
            `s`. There must have been a previous call with ``task=0`` or ``task=1`` for
            the same set of data (``t`` will be stored an used internally)

            If ``task=-1`` find the weighted least square spline for a given set of
            knots, ``t``. These should be interior knots as knots on the ends will be
            added automatically.
        s : float, optional
            A smoothing condition. The amount of smoothness is determined by
            satisfying the conditions: ``sum((w * (y - g))**2,axis=0) <= s`` where ``g(x)``
            is the smoothed interpolation of ``(x,y)``. The user can use `s` to control
            the tradeoff between closeness and smoothness of fit. Larger `s` means
            more smoothing while smaller values of `s` indicate less smoothing.
            Recommended values of `s` depend on the weights, `w`. If the weights
            represent the inverse of the standard-deviation of `y`, then a good `s`
            value should be found in the range ``(m-sqrt(2*m),m+sqrt(2*m))`` where ``m`` is
            the number of datapoints in `x`, `y`, and `w`. default : ``s=m-sqrt(2*m)`` if
            weights are supplied. ``s = 0.0`` (interpolating) if no weights are
            supplied.
        t : array_like, optional
            The knots needed for ``task=-1``. If given then task is automatically set
            to ``-1``.
        full_output : bool, optional
            If non-zero, then return optional outputs.
        per : bool, optional
            If non-zero, data points are considered periodic with period ``x[m-1]`` -
            ``x[0]`` and a smooth periodic spline approximation is returned. Values of
            ``y[m-1]`` and ``w[m-1]`` are not used.
            The default is zero, corresponding to boundary condition 'not-a-knot'.
        quiet : bool, optional
            Non-zero to suppress messages.

        Returns
        -------
        tck : tuple
            A tuple ``(t,c,k)`` containing the vector of knots, the B-spline
            coefficients, and the degree of the spline.
        fp : array, optional
            The weighted sum of squared residuals of the spline approximation.
        ier : int, optional
            An integer flag about splrep success. Success is indicated if ``ier<=0``.
            If ``ier in [1,2,3]``, an error occurred but was not raised. Otherwise an
            error is raised.
        msg : str, optional
            A message corresponding to the integer flag, `ier`.

        See Also
        --------
        UnivariateSpline, BivariateSpline
        splprep, splev, sproot, spalde, splint
        bisplrep, bisplev
        BSpline
        make_interp_spline

        Notes
        -----
        See `splev` for evaluation of the spline and its derivatives. Uses the
        FORTRAN routine ``curfit`` from FITPACK.

        The user is responsible for assuring that the values of `x` are unique.
        Otherwise, `splrep` will not return sensible results.

        If provided, knots `t` must satisfy the Schoenberg-Whitney conditions,
        i.e., there must be a subset of data points ``x[j]`` such that
        ``t[j] < x[j] < t[j+k+1]``, for ``j=0, 1,...,n-k-2``.

        This routine zero-pads the coefficients array ``c`` to have the same length
        as the array of knots ``t`` (the trailing ``k + 1`` coefficients are ignored
        by the evaluation routines, `splev` and `BSpline`.) This is in contrast with
        `splprep`, which does not zero-pad the coefficients.

        The default boundary condition is 'not-a-knot', i.e. the first and second
        segment at a curve end are the same polynomial. More boundary conditions are
        available in `CubicSpline`.

        References
        ----------
        Based on algorithms described in [1]_, [2]_, [3]_, and [4]_:

        .. [1] P. Dierckx, "An algorithm for smoothing, differentiation and
           integration of experimental data using spline functions",
           J.Comp.Appl.Maths 1 (1975) 165-184.
        .. [2] P. Dierckx, "A fast algorithm for smoothing data on a rectangular
           grid while using spline functions", SIAM J.Numer.Anal. 19 (1982)
           1286-1304.
        .. [3] P. Dierckx, "An improved algorithm for curve fitting with spline
           functions", report tw54, Dept. Computer Science,K.U. Leuven, 1981.
        .. [4] P. Dierckx, "Curve and surface fitting with splines", Monographs on
           Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------
        You can interpolate 1-D points with a B-spline curve.
        Further examples are given in
        :ref:`in the tutorial <tutorial-interpolate_splXXX>`.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.interpolate import splev, splrep
        >>> x = np.linspace(0, 10, 10)
        >>> y = np.sin(x)
        >>> spl = splrep(x, y)
        >>> x2 = np.linspace(0, 10, 200)
        >>> y2 = splev(x2, spl)
        >>> plt.plot(x, y, 'o', x2, y2)
        >>> plt.show()

    sproot(tck, mest=10)
        Find the roots of a cubic B-spline.

        Given the knots (>=8) and coefficients of a cubic B-spline return the
        roots of the spline.

        Parameters
        ----------
        tck : tuple or a BSpline object
            If a tuple, then it should be a sequence of length 3, containing the
            vector of knots, the B-spline coefficients, and the degree of the
            spline.
            The number of knots must be >= 8, and the degree must be 3.
            The knots must be a montonically increasing sequence.
        mest : int, optional
            An estimate of the number of zeros (Default is 10).

        Returns
        -------
        zeros : ndarray
            An array giving the roots of the spline.

        See Also
        --------
        splprep, splrep, splint, spalde, splev
        bisplrep, bisplev
        BSpline

        Notes
        -----
        Manipulating the tck-tuples directly is not recommended. In new code,
        prefer using the `BSpline` objects.

        References
        ----------
        .. [1] C. de Boor, "On calculating with b-splines", J. Approximation
            Theory, 6, p.50-62, 1972.
        .. [2] M. G. Cox, "The numerical evaluation of b-splines", J. Inst. Maths
            Applics, 10, p.134-149, 1972.
        .. [3] P. Dierckx, "Curve and surface fitting with splines", Monographs
            on Numerical Analysis, Oxford University Press, 1993.

        Examples
        --------

        For some data, this method may miss a root. This happens when one of
        the spline knots (which FITPACK places automatically) happens to
        coincide with the true root. A workaround is to convert to `PPoly`,
        which uses a different root-finding algorithm.

        For example,

        >>> x = [1.96, 1.97, 1.98, 1.99, 2.00, 2.01, 2.02, 2.03, 2.04, 2.05]
        >>> y = [-6.365470e-03, -4.790580e-03, -3.204320e-03, -1.607270e-03,
        ...      4.440892e-16,  1.616930e-03,  3.243000e-03,  4.877670e-03,
        ...      6.520430e-03,  8.170770e-03]
        >>> from scipy.interpolate import splrep, sproot, PPoly
        >>> tck = splrep(x, y, s=0)
        >>> sproot(tck)
        array([], dtype=float64)

        Converting to a PPoly object does find the roots at `x=2`:

        >>> ppoly = PPoly.from_spline(tck)
        >>> ppoly.roots(extrapolate=False)
        array([2.])


        Further examples are given :ref:`in the tutorial
        <tutorial-interpolate_splXXX>`.

DATA
    __all__ = ['Akima1DInterpolator', 'BPoly', 'BSpline', 'BarycentricInte...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\interpolate\__init__.py

scipy.io
Python Library Documentation: package scipy.io in scipy

NAME
    scipy.io

DESCRIPTION
    ==================================
    Input and output (:mod:`scipy.io`)
    ==================================

    .. currentmodule:: scipy.io

    SciPy has many modules, classes, and functions available to read data
    from and write data to a variety of file formats.

    .. seealso:: `NumPy IO routines <https://www.numpy.org/devdocs/reference/routines.io.html>`__

    MATLAB® files
    =============

    .. autosummary::
       :toctree: generated/

       loadmat - Read a MATLAB style mat file (version 4 through 7.1)
       savemat - Write a MATLAB style mat file (version 4 through 7.1)
       whosmat - List contents of a MATLAB style mat file (version 4 through 7.1)

    For low-level MATLAB reading and writing utilities, see `scipy.io.matlab`.

    IDL® files
    ==========

    .. autosummary::
       :toctree: generated/

       readsav - Read an IDL 'save' file

    Matrix Market files
    ===================

    .. autosummary::
       :toctree: generated/

       mminfo - Query matrix info from Matrix Market formatted file
       mmread - Read matrix from Matrix Market formatted file
       mmwrite - Write matrix to Matrix Market formatted file

    Unformatted Fortran files
    ===============================

    .. autosummary::
       :toctree: generated/

       FortranFile - A file object for unformatted sequential Fortran files
       FortranEOFError - Exception indicating the end of a well-formed file
       FortranFormattingError - Exception indicating an inappropriate end

    Netcdf
    ======

    .. autosummary::
       :toctree: generated/

       netcdf_file - A file object for NetCDF data
       netcdf_variable - A data object for the netcdf module

    Harwell-Boeing files
    ====================

    .. autosummary::
       :toctree: generated/

       hb_read   -- read H-B file
       hb_write  -- write H-B file

    Wav sound files (:mod:`scipy.io.wavfile`)
    =========================================

    .. module:: scipy.io.wavfile

    .. autosummary::
       :toctree: generated/

       read
       write
       WavFileWarning

    Arff files (:mod:`scipy.io.arff`)
    =================================

    .. module:: scipy.io.arff

    .. autosummary::
       :toctree: generated/

       loadarff
       MetaData
       ArffError
       ParseArffError

PACKAGE CONTENTS
    _fast_matrix_market (package)
    _fortran
    _harwell_boeing (package)
    _idl
    _mmio
    _netcdf
    _test_fortran
    arff (package)
    harwell_boeing
    idl
    matlab (package)
    mmio
    netcdf
    tests (package)
    wavfile

CLASSES
    builtins.OSError(builtins.Exception)
        scipy.io._fortran.FortranEOFError(builtins.TypeError, builtins.OSError)
        scipy.io._fortran.FortranFormattingError(builtins.TypeError, builtins.OSError)
    builtins.TypeError(builtins.Exception)
        scipy.io._fortran.FortranEOFError(builtins.TypeError, builtins.OSError)
        scipy.io._fortran.FortranFormattingError(builtins.TypeError, builtins.OSError)
    builtins.object
        scipy.io._fortran.FortranFile
        scipy.io._netcdf.netcdf_file
        scipy.io._netcdf.netcdf_variable

    class FortranEOFError(builtins.TypeError, builtins.OSError)
     |  Indicates that the file ended properly.
     |
     |  This error descends from TypeError because the code used to raise
     |  TypeError (and this was the only way to know that the file had
     |  ended) so users might have ``except TypeError:``.
     |
     |  Method resolution order:
     |      FortranEOFError
     |      builtins.TypeError
     |      builtins.OSError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.TypeError:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.TypeError:
     |
     |  __new__(*args, **kwargs) class method of builtins.TypeError
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.OSError:
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.OSError:
     |
     |  characters_written
     |
     |  errno
     |      POSIX exception code
     |
     |  filename
     |      exception filename
     |
     |  filename2
     |      second exception filename
     |
     |  strerror
     |      exception strerror
     |
     |  winerror
     |      Win32 exception code
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class FortranFile(builtins.object)
     |  FortranFile(filename, mode='r', header_dtype=<class 'numpy.uint32'>)
     |
     |  A file object for unformatted sequential files from Fortran code.
     |
     |  Parameters
     |  ----------
     |  filename : file or str
     |      Open file object or filename.
     |  mode : {'r', 'w'}, optional
     |      Read-write mode, default is 'r'.
     |  header_dtype : dtype, optional
     |      Data type of the header. Size and endianness must match the input/output file.
     |
     |  Notes
     |  -----
     |  These files are broken up into records of unspecified types. The size of
     |  each record is given at the start (although the size of this header is not
     |  standard) and the data is written onto disk without any formatting. Fortran
     |  compilers supporting the BACKSPACE statement will write a second copy of
     |  the size to facilitate backwards seeking.
     |
     |  This class only supports files written with both sizes for the record.
     |  It also does not support the subrecords used in Intel and gfortran compilers
     |  for records which are greater than 2GB with a 4-byte header.
     |
     |  An example of an unformatted sequential file in Fortran would be written as::
     |
     |      OPEN(1, FILE=myfilename, FORM='unformatted')
     |
     |      WRITE(1) myvariable
     |
     |  Since this is a non-standard file format, whose contents depend on the
     |  compiler and the endianness of the machine, caution is advised. Files from
     |  gfortran 4.8.0 and gfortran 4.1.2 on x86_64 are known to work.
     |
     |  Consider using Fortran direct-access files or files from the newer Stream
     |  I/O, which can be easily read by `numpy.fromfile`.
     |
     |  Examples
     |  --------
     |  To create an unformatted sequential Fortran file:
     |
     |  >>> from scipy.io import FortranFile
     |  >>> import numpy as np
     |  >>> f = FortranFile('test.unf', 'w')
     |  >>> f.write_record(np.array([1,2,3,4,5], dtype=np.int32))
     |  >>> f.write_record(np.linspace(0,1,20).reshape((5,4)).T)
     |  >>> f.close()
     |
     |  To read this file:
     |
     |  >>> f = FortranFile('test.unf', 'r')
     |  >>> print(f.read_ints(np.int32))
     |  [1 2 3 4 5]
     |  >>> print(f.read_reals(float).reshape((5,4), order="F"))
     |  [[0.         0.05263158 0.10526316 0.15789474]
     |   [0.21052632 0.26315789 0.31578947 0.36842105]
     |   [0.42105263 0.47368421 0.52631579 0.57894737]
     |   [0.63157895 0.68421053 0.73684211 0.78947368]
     |   [0.84210526 0.89473684 0.94736842 1.        ]]
     |  >>> f.close()
     |
     |  Or, in Fortran::
     |
     |      integer :: a(5), i
     |      double precision :: b(5,4)
     |      open(1, file='test.unf', form='unformatted')
     |      read(1) a
     |      read(1) b
     |      close(1)
     |      write(*,*) a
     |      do i = 1, 5
     |          write(*,*) b(i,:)
     |      end do
     |
     |  Methods defined here:
     |
     |  __enter__(self)
     |
     |  __exit__(self, type, value, tb)
     |
     |  __init__(self, filename, mode='r', header_dtype=<class 'numpy.uint32'>)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  close(self)
     |      Closes the file. It is unsupported to call any other methods off this
     |      object after closing it. Note that this class supports the 'with'
     |      statement in modern versions of Python, to call this automatically
     |
     |  read_ints(self, dtype='i4')
     |      Reads a record of a given type from the file, defaulting to an integer
     |      type (``INTEGER*4`` in Fortran).
     |
     |      Parameters
     |      ----------
     |      dtype : dtype, optional
     |          Data type specifying the size and endianness of the data.
     |
     |      Returns
     |      -------
     |      data : ndarray
     |          A 1-D array object.
     |
     |      See Also
     |      --------
     |      read_reals
     |      read_record
     |
     |  read_reals(self, dtype='f8')
     |      Reads a record of a given type from the file, defaulting to a floating
     |      point number (``real*8`` in Fortran).
     |
     |      Parameters
     |      ----------
     |      dtype : dtype, optional
     |          Data type specifying the size and endianness of the data.
     |
     |      Returns
     |      -------
     |      data : ndarray
     |          A 1-D array object.
     |
     |      See Also
     |      --------
     |      read_ints
     |      read_record
     |
     |  read_record(self, *dtypes, **kwargs)
     |      Reads a record of a given type from the file.
     |
     |      Parameters
     |      ----------
     |      *dtypes : dtypes, optional
     |          Data type(s) specifying the size and endianness of the data.
     |
     |      Returns
     |      -------
     |      data : ndarray
     |          A 1-D array object.
     |
     |      Raises
     |      ------
     |      FortranEOFError
     |          To signal that no further records are available
     |      FortranFormattingError
     |          To signal that the end of the file was encountered
     |          part-way through a record
     |
     |      Notes
     |      -----
     |      If the record contains a multidimensional array, you can specify
     |      the size in the dtype. For example::
     |
     |          INTEGER var(5,4)
     |
     |      can be read with::
     |
     |          read_record('(4,5)i4').T
     |
     |      Note that this function does **not** assume the file data is in Fortran
     |      column major order, so you need to (i) swap the order of dimensions
     |      when reading and (ii) transpose the resulting array.
     |
     |      Alternatively, you can read the data as a 1-D array and handle the
     |      ordering yourself. For example::
     |
     |          read_record('i4').reshape(5, 4, order='F')
     |
     |      For records that contain several variables or mixed types (as opposed
     |      to single scalar or array types), give them as separate arguments::
     |
     |          double precision :: a
     |          integer :: b
     |          write(1) a, b
     |
     |          record = f.read_record('<f4', '<i4')
     |          a = record[0]  # first number
     |          b = record[1]  # second number
     |
     |      and if any of the variables are arrays, the shape can be specified as
     |      the third item in the relevant dtype::
     |
     |          double precision :: a
     |          integer :: b(3,4)
     |          write(1) a, b
     |
     |          record = f.read_record('<f4', np.dtype(('<i4', (4, 3))))
     |          a = record[0]
     |          b = record[1].T
     |
     |      NumPy also supports a short syntax for this kind of type::
     |
     |          record = f.read_record('<f4', '(3,3)<i4')
     |
     |      See Also
     |      --------
     |      read_reals
     |      read_ints
     |
     |  write_record(self, *items)
     |      Write a record (including sizes) to the file.
     |
     |      Parameters
     |      ----------
     |      *items : array_like
     |          The data arrays to write.
     |
     |      Notes
     |      -----
     |      Writes data items to a file::
     |
     |          write_record(a.T, b.T, c.T, ...)
     |
     |          write(1) a, b, c, ...
     |
     |      Note that data in multidimensional arrays is written in
     |      row-major order --- to make them read correctly by Fortran
     |      programs, you need to transpose the arrays yourself when
     |      writing them.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class FortranFormattingError(builtins.TypeError, builtins.OSError)
     |  Indicates that the file ended mid-record.
     |
     |  Descends from TypeError for backward compatibility.
     |
     |  Method resolution order:
     |      FortranFormattingError
     |      builtins.TypeError
     |      builtins.OSError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.TypeError:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.TypeError:
     |
     |  __new__(*args, **kwargs) class method of builtins.TypeError
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.OSError:
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.OSError:
     |
     |  characters_written
     |
     |  errno
     |      POSIX exception code
     |
     |  filename
     |      exception filename
     |
     |  filename2
     |      second exception filename
     |
     |  strerror
     |      exception strerror
     |
     |  winerror
     |      Win32 exception code
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class netcdf_file(builtins.object)
     |  netcdf_file(filename, mode='r', mmap=None, version=1, maskandscale=False)
     |
     |  A file object for NetCDF data.
     |
     |  A `netcdf_file` object has two standard attributes: `dimensions` and
     |  `variables`. The values of both are dictionaries, mapping dimension
     |  names to their associated lengths and variable names to variables,
     |  respectively. Application programs should never modify these
     |  dictionaries.
     |
     |  All other attributes correspond to global attributes defined in the
     |  NetCDF file. Global file attributes are created by assigning to an
     |  attribute of the `netcdf_file` object.
     |
     |  Parameters
     |  ----------
     |  filename : string or file-like
     |      string -> filename
     |  mode : {'r', 'w', 'a'}, optional
     |      read-write-append mode, default is 'r'
     |  mmap : None or bool, optional
     |      Whether to mmap `filename` when reading.  Default is True
     |      when `filename` is a file name, False when `filename` is a
     |      file-like object. Note that when mmap is in use, data arrays
     |      returned refer directly to the mmapped data on disk, and the
     |      file cannot be closed as long as references to it exist.
     |  version : {1, 2}, optional
     |      version of netcdf to read / write, where 1 means *Classic
     |      format* and 2 means *64-bit offset format*.  Default is 1.  See
     |      `here <https://docs.unidata.ucar.edu/nug/current/netcdf_introduction.html#select_format>`__
     |      for more info.
     |  maskandscale : bool, optional
     |      Whether to automatically scale and/or mask data based on attributes.
     |      Default is False.
     |
     |  Notes
     |  -----
     |  The major advantage of this module over other modules is that it doesn't
     |  require the code to be linked to the NetCDF libraries. This module is
     |  derived from `pupynere <https://bitbucket.org/robertodealmeida/pupynere/>`_.
     |
     |  NetCDF files are a self-describing binary data format. The file contains
     |  metadata that describes the dimensions and variables in the file. More
     |  details about NetCDF files can be found `here
     |  <https://www.unidata.ucar.edu/software/netcdf/guide_toc.html>`__. There
     |  are three main sections to a NetCDF data structure:
     |
     |  1. Dimensions
     |  2. Variables
     |  3. Attributes
     |
     |  The dimensions section records the name and length of each dimension used
     |  by the variables. The variables would then indicate which dimensions it
     |  uses and any attributes such as data units, along with containing the data
     |  values for the variable. It is good practice to include a
     |  variable that is the same name as a dimension to provide the values for
     |  that axes. Lastly, the attributes section would contain additional
     |  information such as the name of the file creator or the instrument used to
     |  collect the data.
     |
     |  When writing data to a NetCDF file, there is often the need to indicate the
     |  'record dimension'. A record dimension is the unbounded dimension for a
     |  variable. For example, a temperature variable may have dimensions of
     |  latitude, longitude and time. If one wants to add more temperature data to
     |  the NetCDF file as time progresses, then the temperature variable should
     |  have the time dimension flagged as the record dimension.
     |
     |  In addition, the NetCDF file header contains the position of the data in
     |  the file, so access can be done in an efficient manner without loading
     |  unnecessary data into memory. It uses the ``mmap`` module to create
     |  Numpy arrays mapped to the data on disk, for the same purpose.
     |
     |  Note that when `netcdf_file` is used to open a file with mmap=True
     |  (default for read-only), arrays returned by it refer to data
     |  directly on the disk. The file should not be closed, and cannot be cleanly
     |  closed when asked, if such arrays are alive. You may want to copy data arrays
     |  obtained from mmapped Netcdf file if they are to be processed after the file
     |  is closed, see the example below.
     |
     |  Examples
     |  --------
     |  To create a NetCDF file:
     |
     |  >>> from scipy.io import netcdf_file
     |  >>> import numpy as np
     |  >>> f = netcdf_file('simple.nc', 'w')
     |  >>> f.history = 'Created for a test'
     |  >>> f.createDimension('time', 10)
     |  >>> time = f.createVariable('time', 'i', ('time',))
     |  >>> time[:] = np.arange(10)
     |  >>> time.units = 'days since 2008-01-01'
     |  >>> f.close()
     |
     |  Note the assignment of ``arange(10)`` to ``time[:]``.  Exposing the slice
     |  of the time variable allows for the data to be set in the object, rather
     |  than letting ``arange(10)`` overwrite the ``time`` variable.
     |
     |  To read the NetCDF file we just created:
     |
     |  >>> from scipy.io import netcdf_file
     |  >>> f = netcdf_file('simple.nc', 'r')
     |  >>> print(f.history)
     |  b'Created for a test'
     |  >>> time = f.variables['time']
     |  >>> print(time.units)
     |  b'days since 2008-01-01'
     |  >>> print(time.shape)
     |  (10,)
     |  >>> print(time[-1])
     |  9
     |
     |  NetCDF files, when opened read-only, return arrays that refer
     |  directly to memory-mapped data on disk:
     |
     |  >>> data = time[:]
     |
     |  If the data is to be processed after the file is closed, it needs
     |  to be copied to main memory:
     |
     |  >>> data = time[:].copy()
     |  >>> del time
     |  >>> f.close()
     |  >>> data.mean()
     |  4.5
     |
     |  A NetCDF file can also be used as context manager:
     |
     |  >>> from scipy.io import netcdf_file
     |  >>> with netcdf_file('simple.nc', 'r') as f:
     |  ...     print(f.history)
     |  b'Created for a test'
     |
     |  Methods defined here:
     |
     |  __del__ = close(self)
     |
     |  __enter__(self)
     |
     |  __exit__(self, type, value, traceback)
     |
     |  __init__(self, filename, mode='r', mmap=None, version=1, maskandscale=False)
     |      Initialize netcdf_file from fileobj (str or file-like).
     |
     |  __setattr__(self, attr, value)
     |      Implement setattr(self, name, value).
     |
     |  close(self)
     |      Closes the NetCDF file.
     |
     |  createDimension(self, name, length)
     |      Adds a dimension to the Dimension section of the NetCDF data structure.
     |
     |      Note that this function merely adds a new dimension that the variables can
     |      reference. The values for the dimension, if desired, should be added as
     |      a variable using `createVariable`, referring to this dimension.
     |
     |      Parameters
     |      ----------
     |      name : str
     |          Name of the dimension (Eg, 'lat' or 'time').
     |      length : int
     |          Length of the dimension.
     |
     |      See Also
     |      --------
     |      createVariable
     |
     |  createVariable(self, name, type, dimensions)
     |      Create an empty variable for the `netcdf_file` object, specifying its data
     |      type and the dimensions it uses.
     |
     |      Parameters
     |      ----------
     |      name : str
     |          Name of the new variable.
     |      type : dtype or str
     |          Data type of the variable.
     |      dimensions : sequence of str
     |          List of the dimension names used by the variable, in the desired order.
     |
     |      Returns
     |      -------
     |      variable : netcdf_variable
     |          The newly created ``netcdf_variable`` object.
     |          This object has also been added to the `netcdf_file` object as well.
     |
     |      See Also
     |      --------
     |      createDimension
     |
     |      Notes
     |      -----
     |      Any dimensions to be used by the variable should already exist in the
     |      NetCDF data structure or should be created by `createDimension` prior to
     |      creating the NetCDF variable.
     |
     |  flush(self)
     |      Perform a sync-to-disk flush if the `netcdf_file` object is in write mode.
     |
     |      See Also
     |      --------
     |      sync : Identical function
     |
     |  sync = flush(self)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class netcdf_variable(builtins.object)
     |  netcdf_variable(data, typecode, size, shape, dimensions, attributes=None, maskandscale=False)
     |
     |  A data object for netcdf files.
     |
     |  `netcdf_variable` objects are constructed by calling the method
     |  `netcdf_file.createVariable` on the `netcdf_file` object. `netcdf_variable`
     |  objects behave much like array objects defined in numpy, except that their
     |  data resides in a file. Data is read by indexing and written by assigning
     |  to an indexed subset; the entire array can be accessed by the index ``[:]``
     |  or (for scalars) by using the methods `getValue` and `assignValue`.
     |  `netcdf_variable` objects also have attribute `shape` with the same meaning
     |  as for arrays, but the shape cannot be modified. There is another read-only
     |  attribute `dimensions`, whose value is the tuple of dimension names.
     |
     |  All other attributes correspond to variable attributes defined in
     |  the NetCDF file. Variable attributes are created by assigning to an
     |  attribute of the `netcdf_variable` object.
     |
     |  Parameters
     |  ----------
     |  data : array_like
     |      The data array that holds the values for the variable.
     |      Typically, this is initialized as empty, but with the proper shape.
     |  typecode : dtype character code
     |      Desired data-type for the data array.
     |  size : int
     |      Desired element size for the data array.
     |  shape : sequence of ints
     |      The shape of the array. This should match the lengths of the
     |      variable's dimensions.
     |  dimensions : sequence of strings
     |      The names of the dimensions used by the variable. Must be in the
     |      same order of the dimension lengths given by `shape`.
     |  attributes : dict, optional
     |      Attribute values (any type) keyed by string names. These attributes
     |      become attributes for the netcdf_variable object.
     |  maskandscale : bool, optional
     |      Whether to automatically scale and/or mask data based on attributes.
     |      Default is False.
     |
     |
     |  Attributes
     |  ----------
     |  dimensions : list of str
     |      List of names of dimensions used by the variable object.
     |  isrec, shape
     |      Properties
     |
     |  See also
     |  --------
     |  isrec, shape
     |
     |  Methods defined here:
     |
     |  __getitem__(self, index)
     |
     |  __init__(self, data, typecode, size, shape, dimensions, attributes=None, maskandscale=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __setattr__(self, attr, value)
     |      Implement setattr(self, name, value).
     |
     |  __setitem__(self, index, data)
     |
     |  assignValue(self, value)
     |      Assign a scalar value to a `netcdf_variable` of length one.
     |
     |      Parameters
     |      ----------
     |      value : scalar
     |          Scalar value (of compatible type) to assign to a length-one netcdf
     |          variable. This value will be written to file.
     |
     |      Raises
     |      ------
     |      ValueError
     |          If the input is not a scalar, or if the destination is not a length-one
     |          netcdf variable.
     |
     |  getValue(self)
     |      Retrieve a scalar value from a `netcdf_variable` of length one.
     |
     |      Raises
     |      ------
     |      ValueError
     |          If the netcdf variable is an array of length greater than one,
     |          this exception will be raised.
     |
     |  itemsize(self)
     |      Return the itemsize of the variable.
     |
     |      Returns
     |      -------
     |      itemsize : int
     |          The element size of the variable (e.g., 8 for float64).
     |
     |  typecode(self)
     |      Return the typecode of the variable.
     |
     |      Returns
     |      -------
     |      typecode : char
     |          The character typecode of the variable (e.g., 'i' for int).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  isrec
     |      Returns whether the variable has a record dimension or not.
     |
     |      A record dimension is a dimension along which additional data could be
     |      easily appended in the netcdf data structure without much rewriting of
     |      the data file. This attribute is a read-only property of the
     |      `netcdf_variable`.
     |
     |  shape
     |      Returns the shape tuple of the data variable.
     |
     |      This is a read-only attribute and can not be modified in the
     |      same manner of other numpy arrays.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    hb_read(path_or_open_file)
        Read HB-format file.

        Parameters
        ----------
        path_or_open_file : path-like or file-like
            If a file-like object, it is used as-is. Otherwise, it is opened
            before reading.

        Returns
        -------
        data : scipy.sparse.csc_matrix instance
            The data read from the HB file as a sparse matrix.

        Notes
        -----
        At the moment not the full Harwell-Boeing format is supported. Supported
        features are:

            - assembled, non-symmetric, real matrices
            - integer for pointer/indices
            - exponential format for float values, and int format

        Examples
        --------
        We can read and write a harwell-boeing format file:

        >>> from scipy.io import hb_read, hb_write
        >>> from scipy.sparse import csr_array, eye
        >>> data = csr_array(eye(3))  # create a sparse array
        >>> hb_write("data.hb", data)  # write a hb file
        >>> print(hb_read("data.hb"))  # read a hb file
        (np.int32(0), np.int32(0))  1.0
        (np.int32(1), np.int32(1))  1.0
        (np.int32(2), np.int32(2))  1.0

    hb_write(path_or_open_file, m, hb_info=None)
        Write HB-format file.

        Parameters
        ----------
        path_or_open_file : path-like or file-like
            If a file-like object, it is used as-is. Otherwise, it is opened
            before writing.
        m : sparse-matrix
            the sparse matrix to write
        hb_info : HBInfo
            contains the meta-data for write

        Returns
        -------
        None

        Notes
        -----
        At the moment not the full Harwell-Boeing format is supported. Supported
        features are:

            - assembled, non-symmetric, real matrices
            - integer for pointer/indices
            - exponential format for float values, and int format

        Examples
        --------
        We can read and write a harwell-boeing format file:

        >>> from scipy.io import hb_read, hb_write
        >>> from scipy.sparse import csr_array, eye
        >>> data = csr_array(eye(3))  # create a sparse array
        >>> hb_write("data.hb", data)  # write a hb file
        >>> print(hb_read("data.hb"))  # read a hb file
        (np.int32(0), np.int32(0))  1.0
        (np.int32(1), np.int32(1))  1.0
        (np.int32(2), np.int32(2))  1.0

    loadmat(file_name, mdict=None, appendmat=True, **kwargs)
        Load MATLAB file.

        Parameters
        ----------
        file_name : str
           Name of the mat file (do not need .mat extension if
           appendmat==True). Can also pass open file-like object.
        mdict : dict, optional
            Dictionary in which to insert matfile variables.
        appendmat : bool, optional
           True to append the .mat extension to the end of the given
           filename, if not already present. Default is True.
        byte_order : str or None, optional
           None by default, implying byte order guessed from mat
           file. Otherwise can be one of ('native', '=', 'little', '<',
           'BIG', '>').
        mat_dtype : bool, optional
           If True, return arrays in same dtype as would be loaded into
           MATLAB (instead of the dtype with which they are saved).
        squeeze_me : bool, optional
           Whether to squeeze unit matrix dimensions or not.
        chars_as_strings : bool, optional
           Whether to convert char arrays to string arrays.
        matlab_compatible : bool, optional
           Returns matrices as would be loaded by MATLAB (implies
           squeeze_me=False, chars_as_strings=False, mat_dtype=True,
           struct_as_record=True).
        struct_as_record : bool, optional
           Whether to load MATLAB structs as NumPy record arrays, or as
           old-style NumPy arrays with dtype=object. Setting this flag to
           False replicates the behavior of scipy version 0.7.x (returning
           NumPy object arrays). The default setting is True, because it
           allows easier round-trip load and save of MATLAB files.
        verify_compressed_data_integrity : bool, optional
            Whether the length of compressed sequences in the MATLAB file
            should be checked, to ensure that they are not longer than we expect.
            It is advisable to enable this (the default) because overlong
            compressed sequences in MATLAB files generally indicate that the
            files have experienced some sort of corruption.
        variable_names : None or sequence
            If None (the default) - read all variables in file. Otherwise,
            `variable_names` should be a sequence of strings, giving names of the
            MATLAB variables to read from the file. The reader will skip any
            variable with a name not in this sequence, possibly saving some read
            processing.
        simplify_cells : False, optional
            If True, return a simplified dict structure (which is useful if the mat
            file contains cell arrays). Note that this only affects the structure
            of the result and not its contents (which is identical for both output
            structures). If True, this automatically sets `struct_as_record` to
            False and `squeeze_me` to True, which is required to simplify cells.

        Returns
        -------
        mat_dict : dict
           dictionary with variable names as keys, and loaded matrices as
           values.

        Notes
        -----
        v4 (Level 1.0), v6 and v7 to 7.2 matfiles are supported.

        You will need an HDF5 Python library to read MATLAB 7.3 format mat
        files. Because SciPy does not supply one, we do not implement the
        HDF5 / 7.3 interface here.

        Examples
        --------
        >>> from os.path import dirname, join as pjoin
        >>> import scipy.io as sio

        Get the filename for an example .mat file from the tests/data directory.

        >>> data_dir = pjoin(dirname(sio.__file__), 'matlab', 'tests', 'data')
        >>> mat_fname = pjoin(data_dir, 'testdouble_7.4_GLNX86.mat')

        Load the .mat file contents.

        >>> mat_contents = sio.loadmat(mat_fname)

        The result is a dictionary, one key/value pair for each variable:

        >>> sorted(mat_contents.keys())
        ['__globals__', '__header__', '__version__', 'testdouble']
        >>> mat_contents['testdouble']
        array([[0.        , 0.78539816, 1.57079633, 2.35619449, 3.14159265,
                3.92699082, 4.71238898, 5.49778714, 6.28318531]])

        By default SciPy reads MATLAB structs as structured NumPy arrays where the
        dtype fields are of type `object` and the names correspond to the MATLAB
        struct field names. This can be disabled by setting the optional argument
        `struct_as_record=False`.

        Get the filename for an example .mat file that contains a MATLAB struct
        called `teststruct` and load the contents.

        >>> matstruct_fname = pjoin(data_dir, 'teststruct_7.4_GLNX86.mat')
        >>> matstruct_contents = sio.loadmat(matstruct_fname)
        >>> teststruct = matstruct_contents['teststruct']
        >>> teststruct.dtype
        dtype([('stringfield', 'O'), ('doublefield', 'O'), ('complexfield', 'O')])

        The size of the structured array is the size of the MATLAB struct, not the
        number of elements in any particular field. The shape defaults to 2-D
        unless the optional argument `squeeze_me=True`, in which case all length 1
        dimensions are removed.

        >>> teststruct.size
        1
        >>> teststruct.shape
        (1, 1)

        Get the 'stringfield' of the first element in the MATLAB struct.

        >>> teststruct[0, 0]['stringfield']
        array(['Rats live on no evil star.'],
          dtype='<U26')

        Get the first element of the 'doublefield'.

        >>> teststruct['doublefield'][0, 0]
        array([[ 1.41421356,  2.71828183,  3.14159265]])

        Load the MATLAB struct, squeezing out length 1 dimensions, and get the item
        from the 'complexfield'.

        >>> matstruct_squeezed = sio.loadmat(matstruct_fname, squeeze_me=True)
        >>> matstruct_squeezed['teststruct'].shape
        ()
        >>> matstruct_squeezed['teststruct']['complexfield'].shape
        ()
        >>> matstruct_squeezed['teststruct']['complexfield'].item()
        array([ 1.41421356+1.41421356j,  2.71828183+2.71828183j,
            3.14159265+3.14159265j])

    mminfo(source)
        Return size and storage parameters from Matrix Market file-like 'source'.

        Parameters
        ----------
        source : str or file-like
            Matrix Market filename (extension .mtx) or open file-like object

        Returns
        -------
        rows : int
            Number of matrix rows.
        cols : int
            Number of matrix columns.
        entries : int
            Number of non-zero entries of a sparse matrix
            or rows*cols for a dense matrix.
        format : str
            Either 'coordinate' or 'array'.
        field : str
            Either 'real', 'complex', 'pattern', or 'integer'.
        symmetry : str
            Either 'general', 'symmetric', 'skew-symmetric', or 'hermitian'.

        Notes
        -----
        .. versionchanged:: 1.12.0
            C++ implementation.

        Examples
        --------
        >>> from io import StringIO
        >>> from scipy.io import mminfo

        >>> text = '''%%MatrixMarket matrix coordinate real general
        ...  5 5 7
        ...  2 3 1.0
        ...  3 4 2.0
        ...  3 5 3.0
        ...  4 1 4.0
        ...  4 2 5.0
        ...  4 3 6.0
        ...  4 4 7.0
        ... '''


        ``mminfo(source)`` returns the number of rows, number of columns,
        format, field type and symmetry attribute of the source file.

        >>> mminfo(StringIO(text))
        (5, 5, 7, 'coordinate', 'real', 'general')

    mmread(source)
        Reads the contents of a Matrix Market file-like 'source' into a matrix.

        Parameters
        ----------
        source : str or file-like
            Matrix Market filename (extensions .mtx, .mtz.gz)
            or open file-like object.

        Returns
        -------
        a : ndarray or coo_matrix
            Dense or sparse matrix depending on the matrix format in the
            Matrix Market file.

        Notes
        -----
        .. versionchanged:: 1.12.0
            C++ implementation.

        Examples
        --------
        >>> from io import StringIO
        >>> from scipy.io import mmread

        >>> text = '''%%MatrixMarket matrix coordinate real general
        ...  5 5 7
        ...  2 3 1.0
        ...  3 4 2.0
        ...  3 5 3.0
        ...  4 1 4.0
        ...  4 2 5.0
        ...  4 3 6.0
        ...  4 4 7.0
        ... '''

        ``mmread(source)`` returns the data as sparse matrix in COO format.

        >>> m = mmread(StringIO(text))
        >>> m
        <COOrdinate sparse matrix of dtype 'float64'
            with 7 stored elements and shape (5, 5)>
        >>> m.toarray()
        array([[0., 0., 0., 0., 0.],
               [0., 0., 1., 0., 0.],
               [0., 0., 0., 2., 3.],
               [4., 5., 6., 7., 0.],
               [0., 0., 0., 0., 0.]])

        This method is threaded.
        The default number of threads is equal to the number of CPUs in the system.
        Use `threadpoolctl <https://github.com/joblib/threadpoolctl>`_ to override:

        >>> import threadpoolctl
        >>>
        >>> with threadpoolctl.threadpool_limits(limits=2):
        ...     m = mmread(StringIO(text))

    mmwrite(target, a, comment=None, field=None, precision=None, symmetry='AUTO')
        Writes the sparse or dense array `a` to Matrix Market file-like `target`.

        Parameters
        ----------
        target : str or file-like
            Matrix Market filename (extension .mtx) or open file-like object.
        a : array like
            Sparse or dense 2-D array.
        comment : str, optional
            Comments to be prepended to the Matrix Market file.
        field : None or str, optional
            Either 'real', 'complex', 'pattern', or 'integer'.
        precision : None or int, optional
            Number of digits to display for real or complex values.
        symmetry : None or str, optional
            Either 'AUTO', 'general', 'symmetric', 'skew-symmetric', or 'hermitian'.
            If symmetry is None the symmetry type of 'a' is determined by its
            values. If symmetry is 'AUTO' the symmetry type of 'a' is either
            determined or set to 'general', at mmwrite's discretion.

        Returns
        -------
        None

        Notes
        -----
        .. versionchanged:: 1.12.0
            C++ implementation.

        Examples
        --------
        >>> from io import BytesIO
        >>> import numpy as np
        >>> from scipy.sparse import coo_matrix
        >>> from scipy.io import mmwrite

        Write a small NumPy array to a matrix market file.  The file will be
        written in the ``'array'`` format.

        >>> a = np.array([[1.0, 0, 0, 0], [0, 2.5, 0, 6.25]])
        >>> target = BytesIO()
        >>> mmwrite(target, a)
        >>> print(target.getvalue().decode('latin1'))
        %%MatrixMarket matrix array real general
        %
        2 4
        1
        0
        0
        2.5
        0
        0
        0
        6.25

        Add a comment to the output file, and set the precision to 3.

        >>> target = BytesIO()
        >>> mmwrite(target, a, comment='\n Some test data.\n', precision=3)
        >>> print(target.getvalue().decode('latin1'))
        %%MatrixMarket matrix array real general
        %
        % Some test data.
        %
        2 4
        1.00e+00
        0.00e+00
        0.00e+00
        2.50e+00
        0.00e+00
        0.00e+00
        0.00e+00
        6.25e+00

        Convert to a sparse matrix before calling ``mmwrite``.  This will
        result in the output format being ``'coordinate'`` rather than
        ``'array'``.

        >>> target = BytesIO()
        >>> mmwrite(target, coo_matrix(a), precision=3)
        >>> print(target.getvalue().decode('latin1'))
        %%MatrixMarket matrix coordinate real general
        %
        2 4 3
        1 1 1.00e+00
        2 2 2.50e+00
        2 4 6.25e+00

        Write a complex Hermitian array to a matrix market file.  Note that
        only six values are actually written to the file; the other values
        are implied by the symmetry.

        >>> z = np.array([[3, 1+2j, 4-3j], [1-2j, 1, -5j], [4+3j, 5j, 2.5]])
        >>> z
        array([[ 3. +0.j,  1. +2.j,  4. -3.j],
               [ 1. -2.j,  1. +0.j, -0. -5.j],
               [ 4. +3.j,  0. +5.j,  2.5+0.j]])

        >>> target = BytesIO()
        >>> mmwrite(target, z, precision=2)
        >>> print(target.getvalue().decode('latin1'))
        %%MatrixMarket matrix array complex hermitian
        %
        3 3
        3.0e+00 0.0e+00
        1.0e+00 -2.0e+00
        4.0e+00 3.0e+00
        1.0e+00 0.0e+00
        0.0e+00 5.0e+00
        2.5e+00 0.0e+00

        This method is threaded.
        The default number of threads is equal to the number of CPUs in the system.
        Use `threadpoolctl <https://github.com/joblib/threadpoolctl>`_ to override:

        >>> import threadpoolctl
        >>>
        >>> target = BytesIO()
        >>> with threadpoolctl.threadpool_limits(limits=2):
        ...     mmwrite(target, a)

    readsav(file_name, idict=None, python_dict=False, uncompressed_file_name=None, verbose=False)
        Read an IDL .sav file.

        Parameters
        ----------
        file_name : str
            Name of the IDL save file.
        idict : dict, optional
            Dictionary in which to insert .sav file variables.
        python_dict : bool, optional
            By default, the object return is not a Python dictionary, but a
            case-insensitive dictionary with item, attribute, and call access
            to variables. To get a standard Python dictionary, set this option
            to True.
        uncompressed_file_name : str, optional
            This option only has an effect for .sav files written with the
            /compress option. If a file name is specified, compressed .sav
            files are uncompressed to this file. Otherwise, readsav will use
            the `tempfile` module to determine a temporary filename
            automatically, and will remove the temporary file upon successfully
            reading it in.
        verbose : bool, optional
            Whether to print out information about the save file, including
            the records read, and available variables.

        Returns
        -------
        idl_dict : AttrDict or dict
            If `python_dict` is set to False (default), this function returns a
            case-insensitive dictionary with item, attribute, and call access
            to variables. If `python_dict` is set to True, this function
            returns a Python dictionary with all variable names in lowercase.
            If `idict` was specified, then variables are written to the
            dictionary specified, and the updated dictionary is returned.

        Examples
        --------
        >>> from os.path import dirname, join as pjoin
        >>> import scipy.io as sio
        >>> from scipy.io import readsav

        Get the filename for an example .sav file from the tests/data directory.

        >>> data_dir = pjoin(dirname(sio.__file__), 'tests', 'data')
        >>> sav_fname = pjoin(data_dir, 'array_float32_1d.sav')

        Load the .sav file contents.

        >>> sav_data = readsav(sav_fname)

        Get keys of the .sav file contents.

        >>> print(sav_data.keys())
        dict_keys(['array1d'])

        Access a content with a key.

        >>> print(sav_data['array1d'])
        [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
         0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
         0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
         0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
         0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
         0. 0. 0.]

    savemat(file_name, mdict, appendmat=True, format='5', long_field_names=False, do_compression=False, oned_as='row')
        Save a dictionary of names and arrays into a MATLAB-style .mat file.

        This saves the array objects in the given dictionary to a MATLAB-
        style .mat file.

        Parameters
        ----------
        file_name : str or file-like object
            Name of the .mat file (.mat extension not needed if ``appendmat ==
            True``).
            Can also pass open file_like object.
        mdict : dict
            Dictionary from which to save matfile variables.
        appendmat : bool, optional
            True (the default) to append the .mat extension to the end of the
            given filename, if not already present.
        format : {'5', '4'}, string, optional
            '5' (the default) for MATLAB 5 and up (to 7.2),
            '4' for MATLAB 4 .mat files.
        long_field_names : bool, optional
            False (the default) - maximum field name length in a structure is
            31 characters which is the documented maximum length.
            True - maximum field name length in a structure is 63 characters
            which works for MATLAB 7.6+.
        do_compression : bool, optional
            Whether or not to compress matrices on write. Default is False.
        oned_as : {'row', 'column'}, optional
            If 'column', write 1-D NumPy arrays as column vectors.
            If 'row', write 1-D NumPy arrays as row vectors.

        Examples
        --------
        >>> from scipy.io import savemat
        >>> import numpy as np
        >>> a = np.arange(20)
        >>> mdic = {"a": a, "label": "experiment"}
        >>> mdic
        {'a': array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
            17, 18, 19]),
        'label': 'experiment'}
        >>> savemat("matlab_matrix.mat", mdic)

    whosmat(file_name, appendmat=True, **kwargs)
        List variables inside a MATLAB file.

        Parameters
        ----------
        file_name : str
           Name of the mat file (do not need .mat extension if
           appendmat==True) Can also pass open file-like object.
        appendmat : bool, optional
           True to append the .mat extension to the end of the given
           filename, if not already present. Default is True.
        byte_order : str or None, optional
           None by default, implying byte order guessed from mat
           file. Otherwise can be one of ('native', '=', 'little', '<',
           'BIG', '>').
        mat_dtype : bool, optional
           If True, return arrays in same dtype as would be loaded into
           MATLAB (instead of the dtype with which they are saved).
        squeeze_me : bool, optional
           Whether to squeeze unit matrix dimensions or not.
        chars_as_strings : bool, optional
           Whether to convert char arrays to string arrays.
        matlab_compatible : bool, optional
           Returns matrices as would be loaded by MATLAB (implies
           squeeze_me=False, chars_as_strings=False, mat_dtype=True,
           struct_as_record=True).
        struct_as_record : bool, optional
           Whether to load MATLAB structs as NumPy record arrays, or as
           old-style NumPy arrays with dtype=object. Setting this flag to
           False replicates the behavior of SciPy version 0.7.x (returning
           numpy object arrays). The default setting is True, because it
           allows easier round-trip load and save of MATLAB files.

        Returns
        -------
        variables : list of tuples
            A list of tuples, where each tuple holds the matrix name (a string),
            its shape (tuple of ints), and its data class (a string).
            Possible data classes are: int8, uint8, int16, uint16, int32, uint32,
            int64, uint64, single, double, cell, struct, object, char, sparse,
            function, opaque, logical, unknown.

        Notes
        -----
        v4 (Level 1.0), v6 and v7 to 7.2 matfiles are supported.

        You will need an HDF5 python library to read matlab 7.3 format mat
        files (e.g. h5py). Because SciPy does not supply one, we do not implement the
        HDF5 / 7.3 interface here.

        .. versionadded:: 0.12.0

        Examples
        --------
        >>> from io import BytesIO
        >>> import numpy as np
        >>> from scipy.io import savemat, whosmat

        Create some arrays, and use `savemat` to write them to a ``BytesIO``
        instance.

        >>> a = np.array([[10, 20, 30], [11, 21, 31]], dtype=np.int32)
        >>> b = np.geomspace(1, 10, 5)
        >>> f = BytesIO()
        >>> savemat(f, {'a': a, 'b': b})

        Use `whosmat` to inspect ``f``.  Each tuple in the output list gives
        the name, shape and data type of the array in ``f``.

        >>> whosmat(f)
        [('a', (2, 3), 'int32'), ('b', (1, 5), 'double')]

DATA
    __all__ = ['FortranEOFError', 'FortranFile', 'FortranFormattingError',...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\io\__init__.py

scipy.linalg
Python Library Documentation: package scipy.linalg in scipy

NAME
    scipy.linalg

DESCRIPTION
    ====================================
    Linear algebra (:mod:`scipy.linalg`)
    ====================================

    .. currentmodule:: scipy.linalg

    .. toctree::
       :hidden:

       linalg.blas
       linalg.cython_blas
       linalg.cython_lapack
       linalg.interpolative
       linalg.lapack

    Linear algebra functions.

    .. eventually, we should replace the numpy.linalg HTML link with just `numpy.linalg`

    .. seealso::

       `numpy.linalg <https://www.numpy.org/devdocs/reference/routines.linalg.html>`__
       for more linear algebra functions. Note that
       although `scipy.linalg` imports most of them, identically named
       functions from `scipy.linalg` may offer more or slightly differing
       functionality.


    Basics
    ======

    .. autosummary::
       :toctree: generated/

       inv - Find the inverse of a square matrix
       solve - Solve a linear system of equations
       solve_banded - Solve a banded linear system
       solveh_banded - Solve a Hermitian or symmetric banded system
       solve_circulant - Solve a circulant system
       solve_triangular - Solve a triangular matrix
       solve_toeplitz - Solve a toeplitz matrix
       matmul_toeplitz - Multiply a Toeplitz matrix with an array.
       det - Find the determinant of a square matrix
       norm - Matrix and vector norm
       lstsq - Solve a linear least-squares problem
       pinv - Pseudo-inverse (Moore-Penrose) using lstsq
       pinvh - Pseudo-inverse of hermitian matrix
       kron - Kronecker product of two arrays
       khatri_rao - Khatri-Rao product of two arrays
       orthogonal_procrustes - Solve an orthogonal Procrustes problem
       matrix_balance - Balance matrix entries with a similarity transformation
       subspace_angles - Compute the subspace angles between two matrices
       bandwidth - Return the lower and upper bandwidth of an array
       issymmetric - Check if a square 2D array is symmetric
       ishermitian - Check if a square 2D array is Hermitian
       LinAlgError
       LinAlgWarning

    Eigenvalue Problems
    ===================

    .. autosummary::
       :toctree: generated/

       eig - Find the eigenvalues and eigenvectors of a square matrix
       eigvals - Find just the eigenvalues of a square matrix
       eigh - Find the e-vals and e-vectors of a Hermitian or symmetric matrix
       eigvalsh - Find just the eigenvalues of a Hermitian or symmetric matrix
       eig_banded - Find the eigenvalues and eigenvectors of a banded matrix
       eigvals_banded - Find just the eigenvalues of a banded matrix
       eigh_tridiagonal - Find the eigenvalues and eigenvectors of a tridiagonal matrix
       eigvalsh_tridiagonal - Find just the eigenvalues of a tridiagonal matrix

    Decompositions
    ==============

    .. autosummary::
       :toctree: generated/

       lu - LU decomposition of a matrix
       lu_factor - LU decomposition returning unordered matrix and pivots
       lu_solve - Solve Ax=b using back substitution with output of lu_factor
       svd - Singular value decomposition of a matrix
       svdvals - Singular values of a matrix
       diagsvd - Construct matrix of singular values from output of svd
       orth - Construct orthonormal basis for the range of A using svd
       null_space - Construct orthonormal basis for the null space of A using svd
       ldl - LDL.T decomposition of a Hermitian or a symmetric matrix.
       cholesky - Cholesky decomposition of a matrix
       cholesky_banded - Cholesky decomp. of a sym. or Hermitian banded matrix
       cho_factor - Cholesky decomposition for use in solving a linear system
       cho_solve - Solve previously factored linear system
       cho_solve_banded - Solve previously factored banded linear system
       polar - Compute the polar decomposition.
       qr - QR decomposition of a matrix
       qr_multiply - QR decomposition and multiplication by Q
       qr_update - Rank k QR update
       qr_delete - QR downdate on row or column deletion
       qr_insert - QR update on row or column insertion
       rq - RQ decomposition of a matrix
       qz - QZ decomposition of a pair of matrices
       ordqz - QZ decomposition of a pair of matrices with reordering
       schur - Schur decomposition of a matrix
       rsf2csf - Real to complex Schur form
       hessenberg - Hessenberg form of a matrix
       cdf2rdf - Complex diagonal form to real diagonal block form
       cossin - Cosine sine decomposition of a unitary or orthogonal matrix

    .. seealso::

       `scipy.linalg.interpolative` -- Interpolative matrix decompositions


    Matrix Functions
    ================

    .. autosummary::
       :toctree: generated/

       expm - Matrix exponential
       logm - Matrix logarithm
       cosm - Matrix cosine
       sinm - Matrix sine
       tanm - Matrix tangent
       coshm - Matrix hyperbolic cosine
       sinhm - Matrix hyperbolic sine
       tanhm - Matrix hyperbolic tangent
       signm - Matrix sign
       sqrtm - Matrix square root
       funm - Evaluating an arbitrary matrix function
       expm_frechet - Frechet derivative of the matrix exponential
       expm_cond - Relative condition number of expm in the Frobenius norm
       fractional_matrix_power - Fractional matrix power


    Matrix Equation Solvers
    =======================

    .. autosummary::
       :toctree: generated/

       solve_sylvester - Solve the Sylvester matrix equation
       solve_continuous_are - Solve the continuous-time algebraic Riccati equation
       solve_discrete_are - Solve the discrete-time algebraic Riccati equation
       solve_continuous_lyapunov - Solve the continuous-time Lyapunov equation
       solve_discrete_lyapunov - Solve the discrete-time Lyapunov equation


    Sketches and Random Projections
    ===============================

    .. autosummary::
       :toctree: generated/

       clarkson_woodruff_transform - Applies the Clarkson Woodruff Sketch (a.k.a CountMin Sketch)

    Special Matrices
    ================

    .. autosummary::
       :toctree: generated/

       block_diag - Construct a block diagonal matrix from submatrices
       circulant - Circulant matrix
       companion - Companion matrix
       convolution_matrix - Convolution matrix
       dft - Discrete Fourier transform matrix
       fiedler - Fiedler matrix
       fiedler_companion - Fiedler companion matrix
       hadamard - Hadamard matrix of order 2**n
       hankel - Hankel matrix
       helmert - Helmert matrix
       hilbert - Hilbert matrix
       invhilbert - Inverse Hilbert matrix
       leslie - Leslie matrix
       pascal - Pascal matrix
       invpascal - Inverse Pascal matrix
       toeplitz - Toeplitz matrix

    Low-level routines
    ==================

    .. autosummary::
       :toctree: generated/

       get_blas_funcs
       get_lapack_funcs
       find_best_blas_type

    .. seealso::

       `scipy.linalg.blas` -- Low-level BLAS functions

       `scipy.linalg.lapack` -- Low-level LAPACK functions

       `scipy.linalg.cython_blas` -- Low-level BLAS functions for Cython

       `scipy.linalg.cython_lapack` -- Low-level LAPACK functions for Cython

PACKAGE CONTENTS
    _basic
    _cythonized_array_utils
    _decomp
    _decomp_cholesky
    _decomp_cossin
    _decomp_ldl
    _decomp_lu
    _decomp_lu_cython
    _decomp_polar
    _decomp_qr
    _decomp_qz
    _decomp_schur
    _decomp_svd
    _decomp_update
    _expm_frechet
    _fblas
    _flapack
    _interpolative
    _interpolative_backend
    _matfuncs
    _matfuncs_expm
    _matfuncs_inv_ssq
    _matfuncs_sqrtm
    _matfuncs_sqrtm_triu
    _misc
    _procrustes
    _sketches
    _solve_toeplitz
    _solvers
    _special_matrices
    _testutils
    basic
    blas
    cython_blas
    cython_lapack
    decomp
    decomp_cholesky
    decomp_lu
    decomp_qr
    decomp_schur
    decomp_svd
    interpolative
    lapack
    matfuncs
    misc
    special_matrices
    tests (package)

CLASSES
    builtins.RuntimeWarning(builtins.Warning)
        scipy.linalg._misc.LinAlgWarning
    builtins.ValueError(builtins.Exception)
        numpy.linalg.LinAlgError

    class LinAlgError(builtins.ValueError)
     |  Generic Python-exception-derived object raised by linalg functions.
     |
     |  General purpose exception class, derived from Python's ValueError
     |  class, programmatically raised in linalg functions when a Linear
     |  Algebra-related condition would prevent further correct execution of the
     |  function.
     |
     |  Parameters
     |  ----------
     |  None
     |
     |  Examples
     |  --------
     |  >>> from numpy import linalg as LA
     |  >>> LA.inv(np.zeros((2,2)))
     |  Traceback (most recent call last):
     |    File "<stdin>", line 1, in <module>
     |    File "...linalg.py", line 350,
     |      in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype)))
     |    File "...linalg.py", line 249,
     |      in solve
     |      raise LinAlgError('Singular matrix')
     |  numpy.linalg.LinAlgError: Singular matrix
     |
     |  Method resolution order:
     |      LinAlgError
     |      builtins.ValueError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.ValueError:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.ValueError:
     |
     |  __new__(*args, **kwargs) class method of builtins.ValueError
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class LinAlgWarning(builtins.RuntimeWarning)
     |  The warning emitted when a linear algebra related operation is close
     |  to fail conditions of the algorithm or loss of accuracy is expected.
     |
     |  Method resolution order:
     |      LinAlgWarning
     |      builtins.RuntimeWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.RuntimeWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

FUNCTIONS
    bandwidth(a)
        bandwidth(a)
        Return the lower and upper bandwidth of a 2D numeric array.

            Parameters
            ----------
            a : ndarray
                Input array of size (N, M)

            Returns
            -------
            lu : tuple
                2-tuple of ints indicating the lower and upper bandwidth. A zero
                denotes no sub- or super-diagonal on that side (triangular), and,
                say for N rows (N-1) means that side is full. Same example applies
                to the upper triangular part with (M-1).

            Raises
            ------
            TypeError
                If the dtype of the array is not supported, in particular, NumPy
                float16, float128 and complex256 dtypes.

            Notes
            -----
            This helper function simply runs over the array looking for the nonzero
            entries whether there exists a banded structure in the array or not. Hence,
            the performance depends on the density of nonzero entries and also
            memory-layout. Fortran- or C- contiguous arrays are handled best and
            otherwise suffers from extra random memory access cost.

            The strategy is to look for only untested band elements in the upper
            and lower triangular parts separately; depending on the memory layout
            we scan row-wise or column-wise. Moreover, say we are scanning rows
            and in the 6th row, 4th entry is nonzero then, on the succeeding rows
            the horizontal search is done only up to that band entries since we know
            that band is occupied. Therefore, a completely dense matrix scan cost is
            in the order of n.

            Examples
            --------
            >>> import numpy as np
            >>> from scipy.linalg import bandwidth
            >>> A = np.array([[3., 0., 0., 0., 0.],
            ...               [0., 4., 0., 0., 0.],
            ...               [0., 0., 5., 1., 0.],
            ...               [8., 0., 0., 6., 2.],
            ...               [0., 9., 0., 0., 7.]])
            >>> bandwidth(A)
            (3, 1)

    block_diag(*arrs)
        Create a block diagonal matrix from provided arrays.

        Given the inputs `A`, `B` and `C`, the output will have these
        arrays arranged on the diagonal::

            [[A, 0, 0],
             [0, B, 0],
             [0, 0, C]]

        Parameters
        ----------
        A, B, C, ... : array_like, up to 2-D
            Input arrays.  A 1-D array or array_like sequence of length `n` is
            treated as a 2-D array with shape ``(1,n)``.

        Returns
        -------
        D : ndarray
            Array with `A`, `B`, `C`, ... on the diagonal. `D` has the
            same dtype as `A`.

        Notes
        -----
        If all the input arrays are square, the output is known as a
        block diagonal matrix.

        Empty sequences (i.e., array-likes of zero size) will not be ignored.
        Noteworthy, both [] and [[]] are treated as matrices with shape ``(1,0)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import block_diag
        >>> A = [[1, 0],
        ...      [0, 1]]
        >>> B = [[3, 4, 5],
        ...      [6, 7, 8]]
        >>> C = [[7]]
        >>> P = np.zeros((2, 0), dtype='int32')
        >>> block_diag(A, B, C)
        array([[1, 0, 0, 0, 0, 0],
               [0, 1, 0, 0, 0, 0],
               [0, 0, 3, 4, 5, 0],
               [0, 0, 6, 7, 8, 0],
               [0, 0, 0, 0, 0, 7]])
        >>> block_diag(A, P, B, C)
        array([[1, 0, 0, 0, 0, 0],
               [0, 1, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 3, 4, 5, 0],
               [0, 0, 6, 7, 8, 0],
               [0, 0, 0, 0, 0, 7]])
        >>> block_diag(1.0, [2, 3], [[4, 5], [6, 7]])
        array([[ 1.,  0.,  0.,  0.,  0.],
               [ 0.,  2.,  3.,  0.,  0.],
               [ 0.,  0.,  0.,  4.,  5.],
               [ 0.,  0.,  0.,  6.,  7.]])

    cdf2rdf(w, v)
        Converts complex eigenvalues ``w`` and eigenvectors ``v`` to real
        eigenvalues in a block diagonal form ``wr`` and the associated real
        eigenvectors ``vr``, such that::

            vr @ wr = X @ vr

        continues to hold, where ``X`` is the original array for which ``w`` and
        ``v`` are the eigenvalues and eigenvectors.

        .. versionadded:: 1.1.0

        Parameters
        ----------
        w : (..., M) array_like
            Complex or real eigenvalues, an array or stack of arrays

            Conjugate pairs must not be interleaved, else the wrong result
            will be produced. So ``[1+1j, 1, 1-1j]`` will give a correct result,
            but ``[1+1j, 2+1j, 1-1j, 2-1j]`` will not.

        v : (..., M, M) array_like
            Complex or real eigenvectors, a square array or stack of square arrays.

        Returns
        -------
        wr : (..., M, M) ndarray
            Real diagonal block form of eigenvalues
        vr : (..., M, M) ndarray
            Real eigenvectors associated with ``wr``

        See Also
        --------
        eig : Eigenvalues and right eigenvectors for non-symmetric arrays
        rsf2csf : Convert real Schur form to complex Schur form

        Notes
        -----
        ``w``, ``v`` must be the eigenstructure for some *real* matrix ``X``.
        For example, obtained by ``w, v = scipy.linalg.eig(X)`` or
        ``w, v = numpy.linalg.eig(X)`` in which case ``X`` can also represent
        stacked arrays.

        .. versionadded:: 1.1.0

        Examples
        --------
        >>> import numpy as np
        >>> X = np.array([[1, 2, 3], [0, 4, 5], [0, -5, 4]])
        >>> X
        array([[ 1,  2,  3],
               [ 0,  4,  5],
               [ 0, -5,  4]])

        >>> from scipy import linalg
        >>> w, v = linalg.eig(X)
        >>> w
        array([ 1.+0.j,  4.+5.j,  4.-5.j])
        >>> v
        array([[ 1.00000+0.j     , -0.01906-0.40016j, -0.01906+0.40016j],
               [ 0.00000+0.j     ,  0.00000-0.64788j,  0.00000+0.64788j],
               [ 0.00000+0.j     ,  0.64788+0.j     ,  0.64788-0.j     ]])

        >>> wr, vr = linalg.cdf2rdf(w, v)
        >>> wr
        array([[ 1.,  0.,  0.],
               [ 0.,  4.,  5.],
               [ 0., -5.,  4.]])
        >>> vr
        array([[ 1.     ,  0.40016, -0.01906],
               [ 0.     ,  0.64788,  0.     ],
               [ 0.     ,  0.     ,  0.64788]])

        >>> vr @ wr
        array([[ 1.     ,  1.69593,  1.9246 ],
               [ 0.     ,  2.59153,  3.23942],
               [ 0.     , -3.23942,  2.59153]])
        >>> X @ vr
        array([[ 1.     ,  1.69593,  1.9246 ],
               [ 0.     ,  2.59153,  3.23942],
               [ 0.     , -3.23942,  2.59153]])

    cho_factor(a, lower=False, overwrite_a=False, check_finite=True)
        Compute the Cholesky decomposition of a matrix, to use in cho_solve

        Returns a matrix containing the Cholesky decomposition,
        ``A = L L*`` or ``A = U* U`` of a Hermitian positive-definite matrix `a`.
        The return value can be directly used as the first parameter to cho_solve.

        .. warning::
            The returned matrix also contains random data in the entries not
            used by the Cholesky decomposition. If you need to zero these
            entries, use the function `cholesky` instead.

        Parameters
        ----------
        a : (M, M) array_like
            Matrix to be decomposed
        lower : bool, optional
            Whether to compute the upper or lower triangular Cholesky factorization
            (Default: upper-triangular)
        overwrite_a : bool, optional
            Whether to overwrite data in a (may improve performance)
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        c : (M, M) ndarray
            Matrix whose upper or lower triangle contains the Cholesky factor
            of `a`. Other parts of the matrix contain random data.
        lower : bool
            Flag indicating whether the factor is in the lower or upper triangle

        Raises
        ------
        LinAlgError
            Raised if decomposition fails.

        See Also
        --------
        cho_solve : Solve a linear set equations using the Cholesky factorization
                    of a matrix.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cho_factor
        >>> A = np.array([[9, 3, 1, 5], [3, 7, 5, 1], [1, 5, 9, 2], [5, 1, 2, 6]])
        >>> c, low = cho_factor(A)
        >>> c
        array([[3.        , 1.        , 0.33333333, 1.66666667],
               [3.        , 2.44948974, 1.90515869, -0.27216553],
               [1.        , 5.        , 2.29330749, 0.8559528 ],
               [5.        , 1.        , 2.        , 1.55418563]])
        >>> np.allclose(np.triu(c).T @ np. triu(c) - A, np.zeros((4, 4)))
        True

    cho_solve(c_and_lower, b, overwrite_b=False, check_finite=True)
        Solve the linear equations A x = b, given the Cholesky factorization of A.

        Parameters
        ----------
        (c, lower) : tuple, (array, bool)
            Cholesky factorization of a, as given by cho_factor
        b : array
            Right-hand side
        overwrite_b : bool, optional
            Whether to overwrite data in b (may improve performance)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : array
            The solution to the system A x = b

        See Also
        --------
        cho_factor : Cholesky factorization of a matrix

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cho_factor, cho_solve
        >>> A = np.array([[9, 3, 1, 5], [3, 7, 5, 1], [1, 5, 9, 2], [5, 1, 2, 6]])
        >>> c, low = cho_factor(A)
        >>> x = cho_solve((c, low), [1, 1, 1, 1])
        >>> np.allclose(A @ x - [1, 1, 1, 1], np.zeros(4))
        True

    cho_solve_banded(cb_and_lower, b, overwrite_b=False, check_finite=True)
        Solve the linear equations ``A x = b``, given the Cholesky factorization of
        the banded Hermitian ``A``.

        Parameters
        ----------
        (cb, lower) : tuple, (ndarray, bool)
            `cb` is the Cholesky factorization of A, as given by cholesky_banded.
            `lower` must be the same value that was given to cholesky_banded.
        b : array_like
            Right-hand side
        overwrite_b : bool, optional
            If True, the function will overwrite the values in `b`.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : array
            The solution to the system A x = b

        See Also
        --------
        cholesky_banded : Cholesky factorization of a banded matrix

        Notes
        -----

        .. versionadded:: 0.8.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cholesky_banded, cho_solve_banded
        >>> Ab = np.array([[0, 0, 1j, 2, 3j], [0, -1, -2, 3, 4], [9, 8, 7, 6, 9]])
        >>> A = np.diag(Ab[0,2:], k=2) + np.diag(Ab[1,1:], k=1)
        >>> A = A + A.conj().T + np.diag(Ab[2, :])
        >>> c = cholesky_banded(Ab)
        >>> x = cho_solve_banded((c, False), np.ones(5))
        >>> np.allclose(A @ x - np.ones(5), np.zeros(5))
        True

    cholesky(a, lower=False, overwrite_a=False, check_finite=True)
        Compute the Cholesky decomposition of a matrix.

        Returns the Cholesky decomposition, :math:`A = L L^*` or
        :math:`A = U^* U` of a Hermitian positive-definite matrix A.

        Parameters
        ----------
        a : (M, M) array_like
            Matrix to be decomposed
        lower : bool, optional
            Whether to compute the upper- or lower-triangular Cholesky
            factorization.  Default is upper-triangular.
        overwrite_a : bool, optional
            Whether to overwrite data in `a` (may improve performance).
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        c : (M, M) ndarray
            Upper- or lower-triangular Cholesky factor of `a`.

        Raises
        ------
        LinAlgError : if decomposition fails.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cholesky
        >>> a = np.array([[1,-2j],[2j,5]])
        >>> L = cholesky(a, lower=True)
        >>> L
        array([[ 1.+0.j,  0.+0.j],
               [ 0.+2.j,  1.+0.j]])
        >>> L @ L.T.conj()
        array([[ 1.+0.j,  0.-2.j],
               [ 0.+2.j,  5.+0.j]])

    cholesky_banded(ab, overwrite_ab=False, lower=False, check_finite=True)
        Cholesky decompose a banded Hermitian positive-definite matrix

        The matrix a is stored in ab either in lower-diagonal or upper-
        diagonal ordered form::

            ab[u + i - j, j] == a[i,j]        (if upper form; i <= j)
            ab[    i - j, j] == a[i,j]        (if lower form; i >= j)

        Example of ab (shape of a is (6,6), u=2)::

            upper form:
            *   *   a02 a13 a24 a35
            *   a01 a12 a23 a34 a45
            a00 a11 a22 a33 a44 a55

            lower form:
            a00 a11 a22 a33 a44 a55
            a10 a21 a32 a43 a54 *
            a20 a31 a42 a53 *   *

        Parameters
        ----------
        ab : (u + 1, M) array_like
            Banded matrix
        overwrite_ab : bool, optional
            Discard data in ab (may enhance performance)
        lower : bool, optional
            Is the matrix in the lower form. (Default is upper form)
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        c : (u + 1, M) ndarray
            Cholesky factorization of a, in the same banded format as ab

        See Also
        --------
        cho_solve_banded :
            Solve a linear set equations, given the Cholesky factorization
            of a banded Hermitian.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cholesky_banded
        >>> from numpy import allclose, zeros, diag
        >>> Ab = np.array([[0, 0, 1j, 2, 3j], [0, -1, -2, 3, 4], [9, 8, 7, 6, 9]])
        >>> A = np.diag(Ab[0,2:], k=2) + np.diag(Ab[1,1:], k=1)
        >>> A = A + A.conj().T + np.diag(Ab[2, :])
        >>> c = cholesky_banded(Ab)
        >>> C = np.diag(c[0, 2:], k=2) + np.diag(c[1, 1:], k=1) + np.diag(c[2, :])
        >>> np.allclose(C.conj().T @ C - A, np.zeros((5, 5)))
        True

    circulant(c)
        Construct a circulant matrix.

        Parameters
        ----------
        c : (N,) array_like
            1-D array, the first column of the matrix.

        Returns
        -------
        A : (N, N) ndarray
            A circulant matrix whose first column is `c`.

        See Also
        --------
        toeplitz : Toeplitz matrix
        hankel : Hankel matrix
        solve_circulant : Solve a circulant system.

        Notes
        -----
        .. versionadded:: 0.8.0

        Examples
        --------
        >>> from scipy.linalg import circulant
        >>> circulant([1, 2, 3])
        array([[1, 3, 2],
               [2, 1, 3],
               [3, 2, 1]])

    clarkson_woodruff_transform(input_matrix, sketch_size, seed=None)
        Applies a Clarkson-Woodruff Transform/sketch to the input matrix.

        Given an input_matrix ``A`` of size ``(n, d)``, compute a matrix ``A'`` of
        size (sketch_size, d) so that

        .. math:: \|Ax\| \approx \|A'x\|

        with high probability via the Clarkson-Woodruff Transform, otherwise
        known as the CountSketch matrix.

        Parameters
        ----------
        input_matrix : array_like
            Input matrix, of shape ``(n, d)``.
        sketch_size : int
            Number of rows for the sketch.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

        Returns
        -------
        A' : array_like
            Sketch of the input matrix ``A``, of size ``(sketch_size, d)``.

        Notes
        -----
        To make the statement

        .. math:: \|Ax\| \approx \|A'x\|

        precise, observe the following result which is adapted from the
        proof of Theorem 14 of [2]_ via Markov's Inequality. If we have
        a sketch size ``sketch_size=k`` which is at least

        .. math:: k \geq \frac{2}{\epsilon^2\delta}

        Then for any fixed vector ``x``,

        .. math:: \|Ax\| = (1\pm\epsilon)\|A'x\|

        with probability at least one minus delta.

        This implementation takes advantage of sparsity: computing
        a sketch takes time proportional to ``A.nnz``. Data ``A`` which
        is in ``scipy.sparse.csc_matrix`` format gives the quickest
        computation time for sparse input.

        >>> import numpy as np
        >>> from scipy import linalg
        >>> from scipy import sparse
        >>> rng = np.random.default_rng()
        >>> n_rows, n_columns, density, sketch_n_rows = 15000, 100, 0.01, 200
        >>> A = sparse.rand(n_rows, n_columns, density=density, format='csc')
        >>> B = sparse.rand(n_rows, n_columns, density=density, format='csr')
        >>> C = sparse.rand(n_rows, n_columns, density=density, format='coo')
        >>> D = rng.standard_normal((n_rows, n_columns))
        >>> SA = linalg.clarkson_woodruff_transform(A, sketch_n_rows) # fastest
        >>> SB = linalg.clarkson_woodruff_transform(B, sketch_n_rows) # fast
        >>> SC = linalg.clarkson_woodruff_transform(C, sketch_n_rows) # slower
        >>> SD = linalg.clarkson_woodruff_transform(D, sketch_n_rows) # slowest

        That said, this method does perform well on dense inputs, just slower
        on a relative scale.

        References
        ----------
        .. [1] Kenneth L. Clarkson and David P. Woodruff. Low rank approximation
               and regression in input sparsity time. In STOC, 2013.
        .. [2] David P. Woodruff. Sketching as a tool for numerical linear algebra.
               In Foundations and Trends in Theoretical Computer Science, 2014.

        Examples
        --------
        Create a big dense matrix ``A`` for the example:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> n_rows, n_columns  = 15000, 100
        >>> rng = np.random.default_rng()
        >>> A = rng.standard_normal((n_rows, n_columns))

        Apply the transform to create a new matrix with 200 rows:

        >>> sketch_n_rows = 200
        >>> sketch = linalg.clarkson_woodruff_transform(A, sketch_n_rows, seed=rng)
        >>> sketch.shape
        (200, 100)

        Now with high probability, the true norm is close to the sketched norm
        in absolute value.

        >>> linalg.norm(A)
        1224.2812927123198
        >>> linalg.norm(sketch)
        1226.518328407333

        Similarly, applying our sketch preserves the solution to a linear
        regression of :math:`\min \|Ax - b\|`.

        >>> b = rng.standard_normal(n_rows)
        >>> x = linalg.lstsq(A, b)[0]
        >>> Ab = np.hstack((A, b.reshape(-1, 1)))
        >>> SAb = linalg.clarkson_woodruff_transform(Ab, sketch_n_rows, seed=rng)
        >>> SA, Sb = SAb[:, :-1], SAb[:, -1]
        >>> x_sketched = linalg.lstsq(SA, Sb)[0]

        As with the matrix norm example, ``linalg.norm(A @ x - b)`` is close
        to ``linalg.norm(A @ x_sketched - b)`` with high probability.

        >>> linalg.norm(A @ x - b)
        122.83242365433877
        >>> linalg.norm(A @ x_sketched - b)
        166.58473879945151

    companion(a)
        Create a companion matrix.

        Create the companion matrix [1]_ associated with the polynomial whose
        coefficients are given in `a`.

        Parameters
        ----------
        a : (N,) array_like
            1-D array of polynomial coefficients. The length of `a` must be
            at least two, and ``a[0]`` must not be zero.

        Returns
        -------
        c : (N-1, N-1) ndarray
            The first row of `c` is ``-a[1:]/a[0]``, and the first
            sub-diagonal is all ones.  The data-type of the array is the same
            as the data-type of ``1.0*a[0]``.

        Raises
        ------
        ValueError
            If any of the following are true: a) ``a.ndim != 1``;
            b) ``a.size < 2``; c) ``a[0] == 0``.

        Notes
        -----
        .. versionadded:: 0.8.0

        References
        ----------
        .. [1] R. A. Horn & C. R. Johnson, *Matrix Analysis*.  Cambridge, UK:
            Cambridge University Press, 1999, pp. 146-7.

        Examples
        --------
        >>> from scipy.linalg import companion
        >>> companion([1, -10, 31, -30])
        array([[ 10., -31.,  30.],
               [  1.,   0.,   0.],
               [  0.,   1.,   0.]])

    convolution_matrix(a, n, mode='full')
        Construct a convolution matrix.

        Constructs the Toeplitz matrix representing one-dimensional
        convolution [1]_.  See the notes below for details.

        Parameters
        ----------
        a : (m,) array_like
            The 1-D array to convolve.
        n : int
            The number of columns in the resulting matrix.  It gives the length
            of the input to be convolved with `a`.  This is analogous to the
            length of `v` in ``numpy.convolve(a, v)``.
        mode : str
            This is analogous to `mode` in ``numpy.convolve(v, a, mode)``.
            It must be one of ('full', 'valid', 'same').
            See below for how `mode` determines the shape of the result.

        Returns
        -------
        A : (k, n) ndarray
            The convolution matrix whose row count `k` depends on `mode`::

                =======  =========================
                 mode    k
                =======  =========================
                'full'   m + n -1
                'same'   max(m, n)
                'valid'  max(m, n) - min(m, n) + 1
                =======  =========================

        See Also
        --------
        toeplitz : Toeplitz matrix

        Notes
        -----
        The code::

            A = convolution_matrix(a, n, mode)

        creates a Toeplitz matrix `A` such that ``A @ v`` is equivalent to
        using ``convolve(a, v, mode)``.  The returned array always has `n`
        columns.  The number of rows depends on the specified `mode`, as
        explained above.

        In the default 'full' mode, the entries of `A` are given by::

            A[i, j] == (a[i-j] if (0 <= (i-j) < m) else 0)

        where ``m = len(a)``.  Suppose, for example, the input array is
        ``[x, y, z]``.  The convolution matrix has the form::

            [x, 0, 0, ..., 0, 0]
            [y, x, 0, ..., 0, 0]
            [z, y, x, ..., 0, 0]
            ...
            [0, 0, 0, ..., x, 0]
            [0, 0, 0, ..., y, x]
            [0, 0, 0, ..., z, y]
            [0, 0, 0, ..., 0, z]

        In 'valid' mode, the entries of `A` are given by::

            A[i, j] == (a[i-j+m-1] if (0 <= (i-j+m-1) < m) else 0)

        This corresponds to a matrix whose rows are the subset of those from
        the 'full' case where all the coefficients in `a` are contained in the
        row.  For input ``[x, y, z]``, this array looks like::

            [z, y, x, 0, 0, ..., 0, 0, 0]
            [0, z, y, x, 0, ..., 0, 0, 0]
            [0, 0, z, y, x, ..., 0, 0, 0]
            ...
            [0, 0, 0, 0, 0, ..., x, 0, 0]
            [0, 0, 0, 0, 0, ..., y, x, 0]
            [0, 0, 0, 0, 0, ..., z, y, x]

        In the 'same' mode, the entries of `A` are given by::

            d = (m - 1) // 2
            A[i, j] == (a[i-j+d] if (0 <= (i-j+d) < m) else 0)

        The typical application of the 'same' mode is when one has a signal of
        length `n` (with `n` greater than ``len(a)``), and the desired output
        is a filtered signal that is still of length `n`.

        For input ``[x, y, z]``, this array looks like::

            [y, x, 0, 0, ..., 0, 0, 0]
            [z, y, x, 0, ..., 0, 0, 0]
            [0, z, y, x, ..., 0, 0, 0]
            [0, 0, z, y, ..., 0, 0, 0]
            ...
            [0, 0, 0, 0, ..., y, x, 0]
            [0, 0, 0, 0, ..., z, y, x]
            [0, 0, 0, 0, ..., 0, z, y]

        .. versionadded:: 1.5.0

        References
        ----------
        .. [1] "Convolution", https://en.wikipedia.org/wiki/Convolution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import convolution_matrix
        >>> A = convolution_matrix([-1, 4, -2], 5, mode='same')
        >>> A
        array([[ 4, -1,  0,  0,  0],
               [-2,  4, -1,  0,  0],
               [ 0, -2,  4, -1,  0],
               [ 0,  0, -2,  4, -1],
               [ 0,  0,  0, -2,  4]])

        Compare multiplication by `A` with the use of `numpy.convolve`.

        >>> x = np.array([1, 2, 0, -3, 0.5])
        >>> A @ x
        array([  2. ,   6. ,  -1. , -12.5,   8. ])

        Verify that ``A @ x`` produced the same result as applying the
        convolution function.

        >>> np.convolve([-1, 4, -2], x, mode='same')
        array([  2. ,   6. ,  -1. , -12.5,   8. ])

        For comparison to the case ``mode='same'`` shown above, here are the
        matrices produced by ``mode='full'`` and ``mode='valid'`` for the
        same coefficients and size.

        >>> convolution_matrix([-1, 4, -2], 5, mode='full')
        array([[-1,  0,  0,  0,  0],
               [ 4, -1,  0,  0,  0],
               [-2,  4, -1,  0,  0],
               [ 0, -2,  4, -1,  0],
               [ 0,  0, -2,  4, -1],
               [ 0,  0,  0, -2,  4],
               [ 0,  0,  0,  0, -2]])

        >>> convolution_matrix([-1, 4, -2], 5, mode='valid')
        array([[-2,  4, -1,  0,  0],
               [ 0, -2,  4, -1,  0],
               [ 0,  0, -2,  4, -1]])

    coshm(A)
        Compute the hyperbolic matrix cosine.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array.

        Returns
        -------
        coshm : (N, N) ndarray
            Hyperbolic matrix cosine of `A`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import tanhm, sinhm, coshm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> c = coshm(a)
        >>> c
        array([[ 11.24592233,  38.76236492],
               [ 12.92078831,  50.00828725]])

        Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

        >>> t = tanhm(a)
        >>> s = sinhm(a)
        >>> t - s.dot(np.linalg.inv(c))
        array([[  2.72004641e-15,   4.55191440e-15],
               [  0.00000000e+00,  -5.55111512e-16]])

    cosm(A)
        Compute the matrix cosine.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array

        Returns
        -------
        cosm : (N, N) ndarray
            Matrix cosine of A

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import expm, sinm, cosm

        Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
        applied to a matrix:

        >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
        >>> expm(1j*a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
        >>> cosm(a) + 1j*sinm(a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

    cossin(X, p=None, q=None, separate=False, swap_sign=False, compute_u=True, compute_vh=True)
        Compute the cosine-sine (CS) decomposition of an orthogonal/unitary matrix.

        X is an ``(m, m)`` orthogonal/unitary matrix, partitioned as the following
        where upper left block has the shape of ``(p, q)``::

                                       ┌                   ┐
                                       │ I  0  0 │ 0  0  0 │
            ┌           ┐   ┌         ┐│ 0  C  0 │ 0 -S  0 │┌         ┐*
            │ X11 │ X12 │   │ U1 │    ││ 0  0  0 │ 0  0 -I ││ V1 │    │
            │ ────┼──── │ = │────┼────││─────────┼─────────││────┼────│
            │ X21 │ X22 │   │    │ U2 ││ 0  0  0 │ I  0  0 ││    │ V2 │
            └           ┘   └         ┘│ 0  S  0 │ 0  C  0 │└         ┘
                                       │ 0  0  I │ 0  0  0 │
                                       └                   ┘

        ``U1``, ``U2``, ``V1``, ``V2`` are square orthogonal/unitary matrices of
        dimensions ``(p,p)``, ``(m-p,m-p)``, ``(q,q)``, and ``(m-q,m-q)``
        respectively, and ``C`` and ``S`` are ``(r, r)`` nonnegative diagonal
        matrices satisfying ``C^2 + S^2 = I`` where ``r = min(p, m-p, q, m-q)``.

        Moreover, the rank of the identity matrices are ``min(p, q) - r``,
        ``min(p, m - q) - r``, ``min(m - p, q) - r``, and ``min(m - p, m - q) - r``
        respectively.

        X can be supplied either by itself and block specifications p, q or its
        subblocks in an iterable from which the shapes would be derived. See the
        examples below.

        Parameters
        ----------
        X : array_like, iterable
            complex unitary or real orthogonal matrix to be decomposed, or iterable
            of subblocks ``X11``, ``X12``, ``X21``, ``X22``, when ``p``, ``q`` are
            omitted.
        p : int, optional
            Number of rows of the upper left block ``X11``, used only when X is
            given as an array.
        q : int, optional
            Number of columns of the upper left block ``X11``, used only when X is
            given as an array.
        separate : bool, optional
            if ``True``, the low level components are returned instead of the
            matrix factors, i.e. ``(u1,u2)``, ``theta``, ``(v1h,v2h)`` instead of
            ``u``, ``cs``, ``vh``.
        swap_sign : bool, optional
            if ``True``, the ``-S``, ``-I`` block will be the bottom left,
            otherwise (by default) they will be in the upper right block.
        compute_u : bool, optional
            if ``False``, ``u`` won't be computed and an empty array is returned.
        compute_vh : bool, optional
            if ``False``, ``vh`` won't be computed and an empty array is returned.

        Returns
        -------
        u : ndarray
            When ``compute_u=True``, contains the block diagonal orthogonal/unitary
            matrix consisting of the blocks ``U1`` (``p`` x ``p``) and ``U2``
            (``m-p`` x ``m-p``) orthogonal/unitary matrices. If ``separate=True``,
            this contains the tuple of ``(U1, U2)``.
        cs : ndarray
            The cosine-sine factor with the structure described above.
             If ``separate=True``, this contains the ``theta`` array containing the
             angles in radians.
        vh : ndarray
            When ``compute_vh=True`, contains the block diagonal orthogonal/unitary
            matrix consisting of the blocks ``V1H`` (``q`` x ``q``) and ``V2H``
            (``m-q`` x ``m-q``) orthogonal/unitary matrices. If ``separate=True``,
            this contains the tuple of ``(V1H, V2H)``.

        References
        ----------
        .. [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
               Algorithms, 50(1):33-65, 2009.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import cossin
        >>> from scipy.stats import unitary_group
        >>> x = unitary_group.rvs(4)
        >>> u, cs, vdh = cossin(x, p=2, q=2)
        >>> np.allclose(x, u @ cs @ vdh)
        True

        Same can be entered via subblocks without the need of ``p`` and ``q``. Also
        let's skip the computation of ``u``

        >>> ue, cs, vdh = cossin((x[:2, :2], x[:2, 2:], x[2:, :2], x[2:, 2:]),
        ...                      compute_u=False)
        >>> print(ue)
        []
        >>> np.allclose(x, u @ cs @ vdh)
        True

    det(a, overwrite_a=False, check_finite=True)
        Compute the determinant of a matrix

        The determinant is a scalar that is a function of the associated square
        matrix coefficients. The determinant value is zero for singular matrices.

        Parameters
        ----------
        a : (..., M, M) array_like
            Input array to compute determinants for.
        overwrite_a : bool, optional
            Allow overwriting data in a (may enhance performance).
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        det : (...) float or complex
            Determinant of `a`. For stacked arrays, a scalar is returned for each
            (m, m) slice in the last two dimensions of the input. For example, an
            input of shape (p, q, m, m) will produce a result of shape (p, q). If
            all dimensions are 1 a scalar is returned regardless of ndim.

        Notes
        -----
        The determinant is computed by performing an LU factorization of the
        input with LAPACK routine 'getrf', and then calculating the product of
        diagonal entries of the U factor.

        Even the input array is single precision (float32 or complex64), the result
        will be returned in double precision (float64 or complex128) to prevent
        overflows.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])  # A singular matrix
        >>> linalg.det(a)
        0.0
        >>> b = np.array([[0,2,3], [4,5,6], [7,8,9]])
        >>> linalg.det(b)
        3.0
        >>> # An array with the shape (3, 2, 2, 2)
        >>> c = np.array([[[[1., 2.], [3., 4.]],
        ...                [[5., 6.], [7., 8.]]],
        ...               [[[9., 10.], [11., 12.]],
        ...                [[13., 14.], [15., 16.]]],
        ...               [[[17., 18.], [19., 20.]],
        ...                [[21., 22.], [23., 24.]]]])
        >>> linalg.det(c)  # The resulting shape is (3, 2)
        array([[-2., -2.],
               [-2., -2.],
               [-2., -2.]])
        >>> linalg.det(c[0, 0])  # Confirm the (0, 0) slice, [[1, 2], [3, 4]]
        -2.0

    dft(n, scale=None)
        Discrete Fourier transform matrix.

        Create the matrix that computes the discrete Fourier transform of a
        sequence [1]_. The nth primitive root of unity used to generate the
        matrix is exp(-2*pi*i/n), where i = sqrt(-1).

        Parameters
        ----------
        n : int
            Size the matrix to create.
        scale : str, optional
            Must be None, 'sqrtn', or 'n'.
            If `scale` is 'sqrtn', the matrix is divided by `sqrt(n)`.
            If `scale` is 'n', the matrix is divided by `n`.
            If `scale` is None (the default), the matrix is not normalized, and the
            return value is simply the Vandermonde matrix of the roots of unity.

        Returns
        -------
        m : (n, n) ndarray
            The DFT matrix.

        Notes
        -----
        When `scale` is None, multiplying a vector by the matrix returned by
        `dft` is mathematically equivalent to (but much less efficient than)
        the calculation performed by `scipy.fft.fft`.

        .. versionadded:: 0.14.0

        References
        ----------
        .. [1] "DFT matrix", https://en.wikipedia.org/wiki/DFT_matrix

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import dft
        >>> np.set_printoptions(precision=2, suppress=True)  # for compact output
        >>> m = dft(5)
        >>> m
        array([[ 1.  +0.j  ,  1.  +0.j  ,  1.  +0.j  ,  1.  +0.j  ,  1.  +0.j  ],
               [ 1.  +0.j  ,  0.31-0.95j, -0.81-0.59j, -0.81+0.59j,  0.31+0.95j],
               [ 1.  +0.j  , -0.81-0.59j,  0.31+0.95j,  0.31-0.95j, -0.81+0.59j],
               [ 1.  +0.j  , -0.81+0.59j,  0.31-0.95j,  0.31+0.95j, -0.81-0.59j],
               [ 1.  +0.j  ,  0.31+0.95j, -0.81+0.59j, -0.81-0.59j,  0.31-0.95j]])
        >>> x = np.array([1, 2, 3, 0, 3])
        >>> m @ x  # Compute the DFT of x
        array([ 9.  +0.j  ,  0.12-0.81j, -2.12+3.44j, -2.12-3.44j,  0.12+0.81j])

        Verify that ``m @ x`` is the same as ``fft(x)``.

        >>> from scipy.fft import fft
        >>> fft(x)     # Same result as m @ x
        array([ 9.  +0.j  ,  0.12-0.81j, -2.12+3.44j, -2.12-3.44j,  0.12+0.81j])

    diagsvd(s, M, N)
        Construct the sigma matrix in SVD from singular values and size M, N.

        Parameters
        ----------
        s : (M,) or (N,) array_like
            Singular values
        M : int
            Size of the matrix whose singular values are `s`.
        N : int
            Size of the matrix whose singular values are `s`.

        Returns
        -------
        S : (M, N) ndarray
            The S-matrix in the singular value decomposition

        See Also
        --------
        svd : Singular value decomposition of a matrix
        svdvals : Compute singular values of a matrix.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import diagsvd
        >>> vals = np.array([1, 2, 3])  # The array representing the computed svd
        >>> diagsvd(vals, 3, 4)
        array([[1, 0, 0, 0],
               [0, 2, 0, 0],
               [0, 0, 3, 0]])
        >>> diagsvd(vals, 4, 3)
        array([[1, 0, 0],
               [0, 2, 0],
               [0, 0, 3],
               [0, 0, 0]])

    eig(a, b=None, left=False, right=True, overwrite_a=False, overwrite_b=False, check_finite=True, homogeneous_eigvals=False)
        Solve an ordinary or generalized eigenvalue problem of a square matrix.

        Find eigenvalues w and right or left eigenvectors of a general matrix::

            a   vr[:,i] = w[i]        b   vr[:,i]
            a.H vl[:,i] = w[i].conj() b.H vl[:,i]

        where ``.H`` is the Hermitian conjugation.

        Parameters
        ----------
        a : (M, M) array_like
            A complex or real matrix whose eigenvalues and eigenvectors
            will be computed.
        b : (M, M) array_like, optional
            Right-hand side matrix in a generalized eigenvalue problem.
            Default is None, identity matrix is assumed.
        left : bool, optional
            Whether to calculate and return left eigenvectors.  Default is False.
        right : bool, optional
            Whether to calculate and return right eigenvectors.  Default is True.
        overwrite_a : bool, optional
            Whether to overwrite `a`; may improve performance.  Default is False.
        overwrite_b : bool, optional
            Whether to overwrite `b`; may improve performance.  Default is False.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        homogeneous_eigvals : bool, optional
            If True, return the eigenvalues in homogeneous coordinates.
            In this case ``w`` is a (2, M) array so that::

                w[1,i] a vr[:,i] = w[0,i] b vr[:,i]

            Default is False.

        Returns
        -------
        w : (M,) or (2, M) double or complex ndarray
            The eigenvalues, each repeated according to its
            multiplicity. The shape is (M,) unless
            ``homogeneous_eigvals=True``.
        vl : (M, M) double or complex ndarray
            The left eigenvector corresponding to the eigenvalue
            ``w[i]`` is the column ``vl[:,i]``. Only returned if ``left=True``.
            The left eigenvector is not normalized.
        vr : (M, M) double or complex ndarray
            The normalized right eigenvector corresponding to the eigenvalue
            ``w[i]`` is the column ``vr[:,i]``.  Only returned if ``right=True``.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge.

        See Also
        --------
        eigvals : eigenvalues of general arrays
        eigh : Eigenvalues and right eigenvectors for symmetric/Hermitian arrays.
        eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
            band matrices
        eigh_tridiagonal : eigenvalues and right eiegenvectors for
            symmetric/Hermitian tridiagonal matrices

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[0., -1.], [1., 0.]])
        >>> linalg.eigvals(a)
        array([0.+1.j, 0.-1.j])

        >>> b = np.array([[0., 1.], [1., 1.]])
        >>> linalg.eigvals(a, b)
        array([ 1.+0.j, -1.+0.j])

        >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
        >>> linalg.eigvals(a, homogeneous_eigvals=True)
        array([[3.+0.j, 8.+0.j, 7.+0.j],
               [1.+0.j, 1.+0.j, 1.+0.j]])

        >>> a = np.array([[0., -1.], [1., 0.]])
        >>> linalg.eigvals(a) == linalg.eig(a)[0]
        array([ True,  True])
        >>> linalg.eig(a, left=True, right=False)[1] # normalized left eigenvector
        array([[-0.70710678+0.j        , -0.70710678-0.j        ],
               [-0.        +0.70710678j, -0.        -0.70710678j]])
        >>> linalg.eig(a, left=False, right=True)[1] # normalized right eigenvector
        array([[0.70710678+0.j        , 0.70710678-0.j        ],
               [0.        -0.70710678j, 0.        +0.70710678j]])

    eig_banded(a_band, lower=False, eigvals_only=False, overwrite_a_band=False, select='a', select_range=None, max_ev=0, check_finite=True)
        Solve real symmetric or complex Hermitian band matrix eigenvalue problem.

        Find eigenvalues w and optionally right eigenvectors v of a::

            a v[:,i] = w[i] v[:,i]
            v.H v    = identity

        The matrix a is stored in a_band either in lower diagonal or upper
        diagonal ordered form:

            a_band[u + i - j, j] == a[i,j]        (if upper form; i <= j)
            a_band[    i - j, j] == a[i,j]        (if lower form; i >= j)

        where u is the number of bands above the diagonal.

        Example of a_band (shape of a is (6,6), u=2)::

            upper form:
            *   *   a02 a13 a24 a35
            *   a01 a12 a23 a34 a45
            a00 a11 a22 a33 a44 a55

            lower form:
            a00 a11 a22 a33 a44 a55
            a10 a21 a32 a43 a54 *
            a20 a31 a42 a53 *   *

        Cells marked with * are not used.

        Parameters
        ----------
        a_band : (u+1, M) array_like
            The bands of the M by M matrix a.
        lower : bool, optional
            Is the matrix in the lower form. (Default is upper form)
        eigvals_only : bool, optional
            Compute only the eigenvalues and no eigenvectors.
            (Default: calculate also eigenvectors)
        overwrite_a_band : bool, optional
            Discard data in a_band (may enhance performance)
        select : {'a', 'v', 'i'}, optional
            Which eigenvalues to calculate

            ======  ========================================
            select  calculated
            ======  ========================================
            'a'     All eigenvalues
            'v'     Eigenvalues in the interval (min, max]
            'i'     Eigenvalues with indices min <= i <= max
            ======  ========================================
        select_range : (min, max), optional
            Range of selected eigenvalues
        max_ev : int, optional
            For select=='v', maximum number of eigenvalues expected.
            For other values of select, has no meaning.

            In doubt, leave this parameter untouched.

        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        w : (M,) ndarray
            The eigenvalues, in ascending order, each repeated according to its
            multiplicity.
        v : (M, M) float or complex ndarray
            The normalized eigenvector corresponding to the eigenvalue w[i] is
            the column v[:,i]. Only returned if ``eigvals_only=False``.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge.

        See Also
        --------
        eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
        eig : eigenvalues and right eigenvectors of general arrays.
        eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
        eigh_tridiagonal : eigenvalues and right eigenvectors for
            symmetric/Hermitian tridiagonal matrices

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import eig_banded
        >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
        >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
        >>> w, v = eig_banded(Ab, lower=True)
        >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
        True
        >>> w = eig_banded(Ab, lower=True, eigvals_only=True)
        >>> w
        array([-4.26200532, -2.22987175,  3.95222349, 12.53965359])

        Request only the eigenvalues between ``[-3, 4]``

        >>> w, v = eig_banded(Ab, lower=True, select='v', select_range=[-3, 4])
        >>> w
        array([-2.22987175,  3.95222349])

    eigh(a, b=None, *, lower=True, eigvals_only=False, overwrite_a=False, overwrite_b=False, type=1, check_finite=True, subset_by_index=None, subset_by_value=None, driver=None)
        Solve a standard or generalized eigenvalue problem for a complex
        Hermitian or real symmetric matrix.

        Find eigenvalues array ``w`` and optionally eigenvectors array ``v`` of
        array ``a``, where ``b`` is positive definite such that for every
        eigenvalue λ (i-th entry of w) and its eigenvector ``vi`` (i-th column of
        ``v``) satisfies::

                          a @ vi = λ * b @ vi
            vi.conj().T @ a @ vi = λ
            vi.conj().T @ b @ vi = 1

        In the standard problem, ``b`` is assumed to be the identity matrix.

        Parameters
        ----------
        a : (M, M) array_like
            A complex Hermitian or real symmetric matrix whose eigenvalues and
            eigenvectors will be computed.
        b : (M, M) array_like, optional
            A complex Hermitian or real symmetric definite positive matrix in.
            If omitted, identity matrix is assumed.
        lower : bool, optional
            Whether the pertinent array data is taken from the lower or upper
            triangle of ``a`` and, if applicable, ``b``. (Default: lower)
        eigvals_only : bool, optional
            Whether to calculate only eigenvalues and no eigenvectors.
            (Default: both are calculated)
        subset_by_index : iterable, optional
            If provided, this two-element iterable defines the start and the end
            indices of the desired eigenvalues (ascending order and 0-indexed).
            To return only the second smallest to fifth smallest eigenvalues,
            ``[1, 4]`` is used. ``[n-3, n-1]`` returns the largest three. Only
            available with "evr", "evx", and "gvx" drivers. The entries are
            directly converted to integers via ``int()``.
        subset_by_value : iterable, optional
            If provided, this two-element iterable defines the half-open interval
            ``(a, b]`` that, if any, only the eigenvalues between these values
            are returned. Only available with "evr", "evx", and "gvx" drivers. Use
            ``np.inf`` for the unconstrained ends.
        driver : str, optional
            Defines which LAPACK driver should be used. Valid options are "ev",
            "evd", "evr", "evx" for standard problems and "gv", "gvd", "gvx" for
            generalized (where b is not None) problems. See the Notes section.
            The default for standard problems is "evr". For generalized problems,
            "gvd" is used for full set, and "gvx" for subset requested cases.
        type : int, optional
            For the generalized problems, this keyword specifies the problem type
            to be solved for ``w`` and ``v`` (only takes 1, 2, 3 as possible
            inputs)::

                1 =>     a @ v = w @ b @ v
                2 => a @ b @ v = w @ v
                3 => b @ a @ v = w @ v

            This keyword is ignored for standard problems.
        overwrite_a : bool, optional
            Whether to overwrite data in ``a`` (may improve performance). Default
            is False.
        overwrite_b : bool, optional
            Whether to overwrite data in ``b`` (may improve performance). Default
            is False.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        w : (N,) ndarray
            The N (N<=M) selected eigenvalues, in ascending order, each
            repeated according to its multiplicity.
        v : (M, N) ndarray
            The normalized eigenvector corresponding to the eigenvalue ``w[i]`` is
            the column ``v[:,i]``. Only returned if ``eigvals_only=False``.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge, an error occurred, or
            b matrix is not definite positive. Note that if input matrices are
            not symmetric or Hermitian, no error will be reported but results will
            be wrong.

        See Also
        --------
        eigvalsh : eigenvalues of symmetric or Hermitian arrays
        eig : eigenvalues and right eigenvectors for non-symmetric arrays
        eigh_tridiagonal : eigenvalues and right eiegenvectors for
            symmetric/Hermitian tridiagonal matrices

        Notes
        -----
        This function does not check the input array for being Hermitian/symmetric
        in order to allow for representing arrays with only their upper/lower
        triangular parts. Also, note that even though not taken into account,
        finiteness check applies to the whole array and unaffected by "lower"
        keyword.

        This function uses LAPACK drivers for computations in all possible keyword
        combinations, prefixed with ``sy`` if arrays are real and ``he`` if
        complex, e.g., a float array with "evr" driver is solved via
        "syevr", complex arrays with "gvx" driver problem is solved via "hegvx"
        etc.

        As a brief summary, the slowest and the most robust driver is the
        classical ``<sy/he>ev`` which uses symmetric QR. ``<sy/he>evr`` is seen as
        the optimal choice for the most general cases. However, there are certain
        occasions that ``<sy/he>evd`` computes faster at the expense of more
        memory usage. ``<sy/he>evx``, while still being faster than ``<sy/he>ev``,
        often performs worse than the rest except when very few eigenvalues are
        requested for large arrays though there is still no performance guarantee.

        Note that the underlying LAPACK algorithms are different depending on whether
        `eigvals_only` is True or False --- thus the eigenvalues may differ
        depending on whether eigenvectors are requested or not. The difference is
        generally of the order of machine epsilon times the largest eigenvalue,
        so is likely only visible for zero or nearly zero eigenvalues.

        For the generalized problem, normalization with respect to the given
        type argument::

                type 1 and 3 :      v.conj().T @ a @ v = w
                type 2       : inv(v).conj().T @ a @ inv(v) = w

                type 1 or 2  :      v.conj().T @ b @ v  = I
                type 3       : v.conj().T @ inv(b) @ v  = I


        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import eigh
        >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
        >>> w, v = eigh(A)
        >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
        True

        Request only the eigenvalues

        >>> w = eigh(A, eigvals_only=True)

        Request eigenvalues that are less than 10.

        >>> A = np.array([[34, -4, -10, -7, 2],
        ...               [-4, 7, 2, 12, 0],
        ...               [-10, 2, 44, 2, -19],
        ...               [-7, 12, 2, 79, -34],
        ...               [2, 0, -19, -34, 29]])
        >>> eigh(A, eigvals_only=True, subset_by_value=[-np.inf, 10])
        array([6.69199443e-07, 9.11938152e+00])

        Request the second smallest eigenvalue and its eigenvector

        >>> w, v = eigh(A, subset_by_index=[1, 1])
        >>> w
        array([9.11938152])
        >>> v.shape  # only a single column is returned
        (5, 1)

    eigh_tridiagonal(d, e, eigvals_only=False, select='a', select_range=None, check_finite=True, tol=0.0, lapack_driver='auto')
        Solve eigenvalue problem for a real symmetric tridiagonal matrix.

        Find eigenvalues `w` and optionally right eigenvectors `v` of ``a``::

            a v[:,i] = w[i] v[:,i]
            v.H v    = identity

        For a real symmetric matrix ``a`` with diagonal elements `d` and
        off-diagonal elements `e`.

        Parameters
        ----------
        d : ndarray, shape (ndim,)
            The diagonal elements of the array.
        e : ndarray, shape (ndim-1,)
            The off-diagonal elements of the array.
        eigvals_only : bool, optional
            Compute only the eigenvalues and no eigenvectors.
            (Default: calculate also eigenvectors)
        select : {'a', 'v', 'i'}, optional
            Which eigenvalues to calculate

            ======  ========================================
            select  calculated
            ======  ========================================
            'a'     All eigenvalues
            'v'     Eigenvalues in the interval (min, max]
            'i'     Eigenvalues with indices min <= i <= max
            ======  ========================================
        select_range : (min, max), optional
            Range of selected eigenvalues
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        tol : float
            The absolute tolerance to which each eigenvalue is required
            (only used when 'stebz' is the `lapack_driver`).
            An eigenvalue (or cluster) is considered to have converged if it
            lies in an interval of this width. If <= 0. (default),
            the value ``eps*|a|`` is used where eps is the machine precision,
            and ``|a|`` is the 1-norm of the matrix ``a``.
        lapack_driver : str
            LAPACK function to use, can be 'auto', 'stemr', 'stebz', 'sterf',
            or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
            and 'stebz' otherwise. When 'stebz' is used to find the eigenvalues and
            ``eigvals_only=False``, then a second LAPACK call (to ``?STEIN``) is
            used to find the corresponding eigenvectors. 'sterf' can only be
            used when ``eigvals_only=True`` and ``select='a'``. 'stev' can only
            be used when ``select='a'``.

        Returns
        -------
        w : (M,) ndarray
            The eigenvalues, in ascending order, each repeated according to its
            multiplicity.
        v : (M, M) ndarray
            The normalized eigenvector corresponding to the eigenvalue ``w[i]`` is
            the column ``v[:,i]``. Only returned if ``eigvals_only=False``.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge.

        See Also
        --------
        eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
            matrices
        eig : eigenvalues and right eigenvectors for non-symmetric arrays
        eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
        eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
            band matrices

        Notes
        -----
        This function makes use of LAPACK ``S/DSTEMR`` routines.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import eigh_tridiagonal
        >>> d = 3*np.ones(4)
        >>> e = -1*np.ones(3)
        >>> w, v = eigh_tridiagonal(d, e)
        >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
        >>> np.allclose(A @ v - v @ np.diag(w), np.zeros((4, 4)))
        True

    eigvals(a, b=None, overwrite_a=False, check_finite=True, homogeneous_eigvals=False)
        Compute eigenvalues from an ordinary or generalized eigenvalue problem.

        Find eigenvalues of a general matrix::

            a   vr[:,i] = w[i]        b   vr[:,i]

        Parameters
        ----------
        a : (M, M) array_like
            A complex or real matrix whose eigenvalues and eigenvectors
            will be computed.
        b : (M, M) array_like, optional
            Right-hand side matrix in a generalized eigenvalue problem.
            If omitted, identity matrix is assumed.
        overwrite_a : bool, optional
            Whether to overwrite data in a (may improve performance)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities
            or NaNs.
        homogeneous_eigvals : bool, optional
            If True, return the eigenvalues in homogeneous coordinates.
            In this case ``w`` is a (2, M) array so that::

                w[1,i] a vr[:,i] = w[0,i] b vr[:,i]

            Default is False.

        Returns
        -------
        w : (M,) or (2, M) double or complex ndarray
            The eigenvalues, each repeated according to its multiplicity
            but not in any specific order. The shape is (M,) unless
            ``homogeneous_eigvals=True``.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge

        See Also
        --------
        eig : eigenvalues and right eigenvectors of general arrays.
        eigvalsh : eigenvalues of symmetric or Hermitian arrays
        eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
        eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
            matrices

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[0., -1.], [1., 0.]])
        >>> linalg.eigvals(a)
        array([0.+1.j, 0.-1.j])

        >>> b = np.array([[0., 1.], [1., 1.]])
        >>> linalg.eigvals(a, b)
        array([ 1.+0.j, -1.+0.j])

        >>> a = np.array([[3., 0., 0.], [0., 8., 0.], [0., 0., 7.]])
        >>> linalg.eigvals(a, homogeneous_eigvals=True)
        array([[3.+0.j, 8.+0.j, 7.+0.j],
               [1.+0.j, 1.+0.j, 1.+0.j]])

    eigvals_banded(a_band, lower=False, overwrite_a_band=False, select='a', select_range=None, check_finite=True)
        Solve real symmetric or complex Hermitian band matrix eigenvalue problem.

        Find eigenvalues w of a::

            a v[:,i] = w[i] v[:,i]
            v.H v    = identity

        The matrix a is stored in a_band either in lower diagonal or upper
        diagonal ordered form:

            a_band[u + i - j, j] == a[i,j]        (if upper form; i <= j)
            a_band[    i - j, j] == a[i,j]        (if lower form; i >= j)

        where u is the number of bands above the diagonal.

        Example of a_band (shape of a is (6,6), u=2)::

            upper form:
            *   *   a02 a13 a24 a35
            *   a01 a12 a23 a34 a45
            a00 a11 a22 a33 a44 a55

            lower form:
            a00 a11 a22 a33 a44 a55
            a10 a21 a32 a43 a54 *
            a20 a31 a42 a53 *   *

        Cells marked with * are not used.

        Parameters
        ----------
        a_band : (u+1, M) array_like
            The bands of the M by M matrix a.
        lower : bool, optional
            Is the matrix in the lower form. (Default is upper form)
        overwrite_a_band : bool, optional
            Discard data in a_band (may enhance performance)
        select : {'a', 'v', 'i'}, optional
            Which eigenvalues to calculate

            ======  ========================================
            select  calculated
            ======  ========================================
            'a'     All eigenvalues
            'v'     Eigenvalues in the interval (min, max]
            'i'     Eigenvalues with indices min <= i <= max
            ======  ========================================
        select_range : (min, max), optional
            Range of selected eigenvalues
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        w : (M,) ndarray
            The eigenvalues, in ascending order, each repeated according to its
            multiplicity.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge.

        See Also
        --------
        eig_banded : eigenvalues and right eigenvectors for symmetric/Hermitian
            band matrices
        eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
            matrices
        eigvals : eigenvalues of general arrays
        eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
        eig : eigenvalues and right eigenvectors for non-symmetric arrays

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import eigvals_banded
        >>> A = np.array([[1, 5, 2, 0], [5, 2, 5, 2], [2, 5, 3, 5], [0, 2, 5, 4]])
        >>> Ab = np.array([[1, 2, 3, 4], [5, 5, 5, 0], [2, 2, 0, 0]])
        >>> w = eigvals_banded(Ab, lower=True)
        >>> w
        array([-4.26200532, -2.22987175,  3.95222349, 12.53965359])

    eigvalsh(a, b=None, *, lower=True, overwrite_a=False, overwrite_b=False, type=1, check_finite=True, subset_by_index=None, subset_by_value=None, driver=None)
        Solves a standard or generalized eigenvalue problem for a complex
        Hermitian or real symmetric matrix.

        Find eigenvalues array ``w`` of array ``a``, where ``b`` is positive
        definite such that for every eigenvalue λ (i-th entry of w) and its
        eigenvector vi (i-th column of v) satisfies::

                          a @ vi = λ * b @ vi
            vi.conj().T @ a @ vi = λ
            vi.conj().T @ b @ vi = 1

        In the standard problem, b is assumed to be the identity matrix.

        Parameters
        ----------
        a : (M, M) array_like
            A complex Hermitian or real symmetric matrix whose eigenvalues will
            be computed.
        b : (M, M) array_like, optional
            A complex Hermitian or real symmetric definite positive matrix in.
            If omitted, identity matrix is assumed.
        lower : bool, optional
            Whether the pertinent array data is taken from the lower or upper
            triangle of ``a`` and, if applicable, ``b``. (Default: lower)
        overwrite_a : bool, optional
            Whether to overwrite data in ``a`` (may improve performance). Default
            is False.
        overwrite_b : bool, optional
            Whether to overwrite data in ``b`` (may improve performance). Default
            is False.
        type : int, optional
            For the generalized problems, this keyword specifies the problem type
            to be solved for ``w`` and ``v`` (only takes 1, 2, 3 as possible
            inputs)::

                1 =>     a @ v = w @ b @ v
                2 => a @ b @ v = w @ v
                3 => b @ a @ v = w @ v

            This keyword is ignored for standard problems.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        subset_by_index : iterable, optional
            If provided, this two-element iterable defines the start and the end
            indices of the desired eigenvalues (ascending order and 0-indexed).
            To return only the second smallest to fifth smallest eigenvalues,
            ``[1, 4]`` is used. ``[n-3, n-1]`` returns the largest three. Only
            available with "evr", "evx", and "gvx" drivers. The entries are
            directly converted to integers via ``int()``.
        subset_by_value : iterable, optional
            If provided, this two-element iterable defines the half-open interval
            ``(a, b]`` that, if any, only the eigenvalues between these values
            are returned. Only available with "evr", "evx", and "gvx" drivers. Use
            ``np.inf`` for the unconstrained ends.
        driver : str, optional
            Defines which LAPACK driver should be used. Valid options are "ev",
            "evd", "evr", "evx" for standard problems and "gv", "gvd", "gvx" for
            generalized (where b is not None) problems. See the Notes section of
            `scipy.linalg.eigh`.

        Returns
        -------
        w : (N,) ndarray
            The N (N<=M) selected eigenvalues, in ascending order, each
            repeated according to its multiplicity.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge, an error occurred, or
            b matrix is not definite positive. Note that if input matrices are
            not symmetric or Hermitian, no error will be reported but results will
            be wrong.

        See Also
        --------
        eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays
        eigvals : eigenvalues of general arrays
        eigvals_banded : eigenvalues for symmetric/Hermitian band matrices
        eigvalsh_tridiagonal : eigenvalues of symmetric/Hermitian tridiagonal
            matrices

        Notes
        -----
        This function does not check the input array for being Hermitian/symmetric
        in order to allow for representing arrays with only their upper/lower
        triangular parts.

        This function serves as a one-liner shorthand for `scipy.linalg.eigh` with
        the option ``eigvals_only=True`` to get the eigenvalues and not the
        eigenvectors. Here it is kept as a legacy convenience. It might be
        beneficial to use the main function to have full control and to be a bit
        more pythonic.

        Examples
        --------
        For more examples see `scipy.linalg.eigh`.

        >>> import numpy as np
        >>> from scipy.linalg import eigvalsh
        >>> A = np.array([[6, 3, 1, 5], [3, 0, 5, 1], [1, 5, 6, 2], [5, 1, 2, 2]])
        >>> w = eigvalsh(A)
        >>> w
        array([-3.74637491, -0.76263923,  6.08502336, 12.42399079])

    eigvalsh_tridiagonal(d, e, select='a', select_range=None, check_finite=True, tol=0.0, lapack_driver='auto')
        Solve eigenvalue problem for a real symmetric tridiagonal matrix.

        Find eigenvalues `w` of ``a``::

            a v[:,i] = w[i] v[:,i]
            v.H v    = identity

        For a real symmetric matrix ``a`` with diagonal elements `d` and
        off-diagonal elements `e`.

        Parameters
        ----------
        d : ndarray, shape (ndim,)
            The diagonal elements of the array.
        e : ndarray, shape (ndim-1,)
            The off-diagonal elements of the array.
        select : {'a', 'v', 'i'}, optional
            Which eigenvalues to calculate

            ======  ========================================
            select  calculated
            ======  ========================================
            'a'     All eigenvalues
            'v'     Eigenvalues in the interval (min, max]
            'i'     Eigenvalues with indices min <= i <= max
            ======  ========================================
        select_range : (min, max), optional
            Range of selected eigenvalues
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        tol : float
            The absolute tolerance to which each eigenvalue is required
            (only used when ``lapack_driver='stebz'``).
            An eigenvalue (or cluster) is considered to have converged if it
            lies in an interval of this width. If <= 0. (default),
            the value ``eps*|a|`` is used where eps is the machine precision,
            and ``|a|`` is the 1-norm of the matrix ``a``.
        lapack_driver : str
            LAPACK function to use, can be 'auto', 'stemr', 'stebz',  'sterf',
            or 'stev'. When 'auto' (default), it will use 'stemr' if ``select='a'``
            and 'stebz' otherwise. 'sterf' and 'stev' can only be used when
            ``select='a'``.

        Returns
        -------
        w : (M,) ndarray
            The eigenvalues, in ascending order, each repeated according to its
            multiplicity.

        Raises
        ------
        LinAlgError
            If eigenvalue computation does not converge.

        See Also
        --------
        eigh_tridiagonal : eigenvalues and right eiegenvectors for
            symmetric/Hermitian tridiagonal matrices

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import eigvalsh_tridiagonal, eigvalsh
        >>> d = 3*np.ones(4)
        >>> e = -1*np.ones(3)
        >>> w = eigvalsh_tridiagonal(d, e)
        >>> A = np.diag(d) + np.diag(e, k=1) + np.diag(e, k=-1)
        >>> w2 = eigvalsh(A)  # Verify with other eigenvalue routines
        >>> np.allclose(w - w2, np.zeros(4))
        True

    expm(A)
        Compute the matrix exponential of an array.

        Parameters
        ----------
        A : ndarray
            Input with last two dimensions are square ``(..., n, n)``.

        Returns
        -------
        eA : ndarray
            The resulting matrix exponential with the same shape of ``A``

        Notes
        -----
        Implements the algorithm given in [1], which is essentially a Pade
        approximation with a variable order that is decided based on the array
        data.

        For input with size ``n``, the memory usage is in the worst case in the
        order of ``8*(n**2)``. If the input data is not of single and double
        precision of real and complex dtypes, it is copied to a new array.

        For cases ``n >= 400``, the exact 1-norm computation cost, breaks even with
        1-norm estimation and from that point on the estimation scheme given in
        [2] is used to decide on the approximation order.

        References
        ----------
        .. [1] Awad H. Al-Mohy and Nicholas J. Higham, (2009), "A New Scaling
               and Squaring Algorithm for the Matrix Exponential", SIAM J. Matrix
               Anal. Appl. 31(3):970-989, :doi:`10.1137/09074721X`

        .. [2] Nicholas J. Higham and Francoise Tisseur (2000), "A Block Algorithm
               for Matrix 1-Norm Estimation, with an Application to 1-Norm
               Pseudospectra." SIAM J. Matrix Anal. Appl. 21(4):1185-1201,
               :doi:`10.1137/S0895479899356080`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import expm, sinm, cosm

        Matrix version of the formula exp(0) = 1:

        >>> expm(np.zeros((3, 2, 2)))
        array([[[1., 0.],
                [0., 1.]],
        <BLANKLINE>
               [[1., 0.],
                [0., 1.]],
        <BLANKLINE>
               [[1., 0.],
                [0., 1.]]])

        Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
        applied to a matrix:

        >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
        >>> expm(1j*a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
        >>> cosm(a) + 1j*sinm(a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

    expm_cond(A, check_finite=True)
        Relative condition number of the matrix exponential in the Frobenius norm.

        Parameters
        ----------
        A : 2-D array_like
            Square input matrix with shape (N, N).
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        kappa : float
            The relative condition number of the matrix exponential
            in the Frobenius norm

        See Also
        --------
        expm : Compute the exponential of a matrix.
        expm_frechet : Compute the Frechet derivative of the matrix exponential.

        Notes
        -----
        A faster estimate for the condition number in the 1-norm
        has been published but is not yet implemented in SciPy.

        .. versionadded:: 0.14.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import expm_cond
        >>> A = np.array([[-0.3, 0.2, 0.6], [0.6, 0.3, -0.1], [-0.7, 1.2, 0.9]])
        >>> k = expm_cond(A)
        >>> k
        1.7787805864469866

    expm_frechet(A, E, method=None, compute_expm=True, check_finite=True)
        Frechet derivative of the matrix exponential of A in the direction E.

        Parameters
        ----------
        A : (N, N) array_like
            Matrix of which to take the matrix exponential.
        E : (N, N) array_like
            Matrix direction in which to take the Frechet derivative.
        method : str, optional
            Choice of algorithm. Should be one of

            - `SPS` (default)
            - `blockEnlarge`

        compute_expm : bool, optional
            Whether to compute also `expm_A` in addition to `expm_frechet_AE`.
            Default is True.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        expm_A : ndarray
            Matrix exponential of A.
        expm_frechet_AE : ndarray
            Frechet derivative of the matrix exponential of A in the direction E.
        For ``compute_expm = False``, only `expm_frechet_AE` is returned.

        See Also
        --------
        expm : Compute the exponential of a matrix.

        Notes
        -----
        This section describes the available implementations that can be selected
        by the `method` parameter. The default method is *SPS*.

        Method *blockEnlarge* is a naive algorithm.

        Method *SPS* is Scaling-Pade-Squaring [1]_.
        It is a sophisticated implementation which should take
        only about 3/8 as much time as the naive implementation.
        The asymptotics are the same.

        .. versionadded:: 0.13.0

        References
        ----------
        .. [1] Awad H. Al-Mohy and Nicholas J. Higham (2009)
               Computing the Frechet Derivative of the Matrix Exponential,
               with an application to Condition Number Estimation.
               SIAM Journal On Matrix Analysis and Applications.,
               30 (4). pp. 1639-1657. ISSN 1095-7162

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> rng = np.random.default_rng()

        >>> A = rng.standard_normal((3, 3))
        >>> E = rng.standard_normal((3, 3))
        >>> expm_A, expm_frechet_AE = linalg.expm_frechet(A, E)
        >>> expm_A.shape, expm_frechet_AE.shape
        ((3, 3), (3, 3))

        Create a 6x6 matrix containing [[A, E], [0, A]]:

        >>> M = np.zeros((6, 6))
        >>> M[:3, :3] = A
        >>> M[:3, 3:] = E
        >>> M[3:, 3:] = A

        >>> expm_M = linalg.expm(M)
        >>> np.allclose(expm_A, expm_M[:3, :3])
        True
        >>> np.allclose(expm_frechet_AE, expm_M[:3, 3:])
        True

    fiedler(a)
        Returns a symmetric Fiedler matrix

        Given an sequence of numbers `a`, Fiedler matrices have the structure
        ``F[i, j] = np.abs(a[i] - a[j])``, and hence zero diagonals and nonnegative
        entries. A Fiedler matrix has a dominant positive eigenvalue and other
        eigenvalues are negative. Although not valid generally, for certain inputs,
        the inverse and the determinant can be derived explicitly as given in [1]_.

        Parameters
        ----------
        a : (n,) array_like
            coefficient array

        Returns
        -------
        F : (n, n) ndarray

        See Also
        --------
        circulant, toeplitz

        Notes
        -----

        .. versionadded:: 1.3.0

        References
        ----------
        .. [1] J. Todd, "Basic Numerical Mathematics: Vol.2 : Numerical Algebra",
            1977, Birkhauser, :doi:`10.1007/978-3-0348-7286-7`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import det, inv, fiedler
        >>> a = [1, 4, 12, 45, 77]
        >>> n = len(a)
        >>> A = fiedler(a)
        >>> A
        array([[ 0,  3, 11, 44, 76],
               [ 3,  0,  8, 41, 73],
               [11,  8,  0, 33, 65],
               [44, 41, 33,  0, 32],
               [76, 73, 65, 32,  0]])

        The explicit formulas for determinant and inverse seem to hold only for
        monotonically increasing/decreasing arrays. Note the tridiagonal structure
        and the corners.

        >>> Ai = inv(A)
        >>> Ai[np.abs(Ai) < 1e-12] = 0.  # cleanup the numerical noise for display
        >>> Ai
        array([[-0.16008772,  0.16666667,  0.        ,  0.        ,  0.00657895],
               [ 0.16666667, -0.22916667,  0.0625    ,  0.        ,  0.        ],
               [ 0.        ,  0.0625    , -0.07765152,  0.01515152,  0.        ],
               [ 0.        ,  0.        ,  0.01515152, -0.03077652,  0.015625  ],
               [ 0.00657895,  0.        ,  0.        ,  0.015625  , -0.00904605]])
        >>> det(A)
        15409151.999999998
        >>> (-1)**(n-1) * 2**(n-2) * np.diff(a).prod() * (a[-1] - a[0])
        15409152

    fiedler_companion(a)
        Returns a Fiedler companion matrix

        Given a polynomial coefficient array ``a``, this function forms a
        pentadiagonal matrix with a special structure whose eigenvalues coincides
        with the roots of ``a``.

        Parameters
        ----------
        a : (N,) array_like
            1-D array of polynomial coefficients in descending order with a nonzero
            leading coefficient. For ``N < 2``, an empty array is returned.

        Returns
        -------
        c : (N-1, N-1) ndarray
            Resulting companion matrix

        See Also
        --------
        companion

        Notes
        -----
        Similar to `companion` the leading coefficient should be nonzero. In the case
        the leading coefficient is not 1, other coefficients are rescaled before
        the array generation. To avoid numerical issues, it is best to provide a
        monic polynomial.

        .. versionadded:: 1.3.0

        References
        ----------
        .. [1] M. Fiedler, " A note on companion matrices", Linear Algebra and its
            Applications, 2003, :doi:`10.1016/S0024-3795(03)00548-2`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import fiedler_companion, eigvals
        >>> p = np.poly(np.arange(1, 9, 2))  # [1., -16., 86., -176., 105.]
        >>> fc = fiedler_companion(p)
        >>> fc
        array([[  16.,  -86.,    1.,    0.],
               [   1.,    0.,    0.,    0.],
               [   0.,  176.,    0., -105.],
               [   0.,    1.,    0.,    0.]])
        >>> eigvals(fc)
        array([7.+0.j, 5.+0.j, 3.+0.j, 1.+0.j])

    find_best_blas_type(arrays=(), dtype=None)
        Find best-matching BLAS/LAPACK type.

        Arrays are used to determine the optimal prefix of BLAS routines.

        Parameters
        ----------
        arrays : sequence of ndarrays, optional
            Arrays can be given to determine optimal prefix of BLAS
            routines. If not given, double-precision routines will be
            used, otherwise the most generic type in arrays will be used.
        dtype : str or dtype, optional
            Data-type specifier. Not used if `arrays` is non-empty.

        Returns
        -------
        prefix : str
            BLAS/LAPACK prefix character.
        dtype : dtype
            Inferred Numpy data type.
        prefer_fortran : bool
            Whether to prefer Fortran order routines over C order.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.linalg.blas as bla
        >>> rng = np.random.default_rng()
        >>> a = rng.random((10,15))
        >>> b = np.asfortranarray(a)  # Change the memory layout order
        >>> bla.find_best_blas_type((a,))
        ('d', dtype('float64'), False)
        >>> bla.find_best_blas_type((a*1j,))
        ('z', dtype('complex128'), False)
        >>> bla.find_best_blas_type((b,))
        ('d', dtype('float64'), True)

    fractional_matrix_power(A, t)
        Compute the fractional power of a matrix.

        Proceeds according to the discussion in section (6) of [1]_.

        Parameters
        ----------
        A : (N, N) array_like
            Matrix whose fractional power to evaluate.
        t : float
            Fractional power.

        Returns
        -------
        X : (N, N) array_like
            The fractional power of the matrix.

        References
        ----------
        .. [1] Nicholas J. Higham and Lijing lin (2011)
               "A Schur-Pade Algorithm for Fractional Powers of a Matrix."
               SIAM Journal on Matrix Analysis and Applications,
               32 (3). pp. 1056-1078. ISSN 0895-4798

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import fractional_matrix_power
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> b = fractional_matrix_power(a, 0.5)
        >>> b
        array([[ 0.75592895,  1.13389342],
               [ 0.37796447,  1.88982237]])
        >>> np.dot(b, b)      # Verify square root
        array([[ 1.,  3.],
               [ 1.,  4.]])

    funm(A, func, disp=True)
        Evaluate a matrix function specified by a callable.

        Returns the value of matrix-valued function ``f`` at `A`. The
        function ``f`` is an extension of the scalar-valued function `func`
        to matrices.

        Parameters
        ----------
        A : (N, N) array_like
            Matrix at which to evaluate the function
        func : callable
            Callable object that evaluates a scalar function f.
            Must be vectorized (eg. using vectorize).
        disp : bool, optional
            Print warning if error in the result is estimated large
            instead of returning estimated error. (Default: True)

        Returns
        -------
        funm : (N, N) ndarray
            Value of the matrix function specified by func evaluated at `A`
        errest : float
            (if disp == False)

            1-norm of the estimated error, ||err||_1 / ||A||_1

        Notes
        -----
        This function implements the general algorithm based on Schur decomposition
        (Algorithm 9.1.1. in [1]_).

        If the input matrix is known to be diagonalizable, then relying on the
        eigendecomposition is likely to be faster. For example, if your matrix is
        Hermitian, you can do

        >>> from scipy.linalg import eigh
        >>> def funm_herm(a, func, check_finite=False):
        ...     w, v = eigh(a, check_finite=check_finite)
        ...     ## if you further know that your matrix is positive semidefinite,
        ...     ## you can optionally guard against precision errors by doing
        ...     # w = np.maximum(w, 0)
        ...     w = func(w)
        ...     return (v * w).dot(v.conj().T)

        References
        ----------
        .. [1] Gene H. Golub, Charles F. van Loan, Matrix Computations 4th ed.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import funm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> funm(a, lambda x: x*x)
        array([[  4.,  15.],
               [  5.,  19.]])
        >>> a.dot(a)
        array([[  4.,  15.],
               [  5.,  19.]])

    get_blas_funcs(names, arrays=(), dtype=None, ilp64=False)
        Return available BLAS function objects from names.

        Arrays are used to determine the optimal prefix of BLAS routines.

        Parameters
        ----------
        names : str or sequence of str
            Name(s) of BLAS functions without type prefix.

        arrays : sequence of ndarrays, optional
            Arrays can be given to determine optimal prefix of BLAS
            routines. If not given, double-precision routines will be
            used, otherwise the most generic type in arrays will be used.

        dtype : str or dtype, optional
            Data-type specifier. Not used if `arrays` is non-empty.

        ilp64 : {True, False, 'preferred'}, optional
            Whether to return ILP64 routine variant.
            Choosing 'preferred' returns ILP64 routine if available,
            and otherwise the 32-bit routine. Default: False

        Returns
        -------
        funcs : list
            List containing the found function(s).


        Notes
        -----
        This routine automatically chooses between Fortran/C
        interfaces. Fortran code is used whenever possible for arrays with
        column major order. In all other cases, C code is preferred.

        In BLAS, the naming convention is that all functions start with a
        type prefix, which depends on the type of the principal
        matrix. These can be one of {'s', 'd', 'c', 'z'} for the NumPy
        types {float32, float64, complex64, complex128} respectively.
        The code and the dtype are stored in attributes `typecode` and `dtype`
        of the returned functions.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.linalg as LA
        >>> rng = np.random.default_rng()
        >>> a = rng.random((3,2))
        >>> x_gemv = LA.get_blas_funcs('gemv', (a,))
        >>> x_gemv.typecode
        'd'
        >>> x_gemv = LA.get_blas_funcs('gemv',(a*1j,))
        >>> x_gemv.typecode
        'z'

    get_lapack_funcs(names, arrays=(), dtype=None, ilp64=False)
        Return available LAPACK function objects from names.

        Arrays are used to determine the optimal prefix of LAPACK routines.

        Parameters
        ----------
        names : str or sequence of str
            Name(s) of LAPACK functions without type prefix.

        arrays : sequence of ndarrays, optional
            Arrays can be given to determine optimal prefix of LAPACK
            routines. If not given, double-precision routines will be
            used, otherwise the most generic type in arrays will be used.

        dtype : str or dtype, optional
            Data-type specifier. Not used if `arrays` is non-empty.

        ilp64 : {True, False, 'preferred'}, optional
            Whether to return ILP64 routine variant.
            Choosing 'preferred' returns ILP64 routine if available, and
            otherwise the 32-bit routine. Default: False

        Returns
        -------
        funcs : list
            List containing the found function(s).

        Notes
        -----
        This routine automatically chooses between Fortran/C
        interfaces. Fortran code is used whenever possible for arrays with
        column major order. In all other cases, C code is preferred.

        In LAPACK, the naming convention is that all functions start with a
        type prefix, which depends on the type of the principal
        matrix. These can be one of {'s', 'd', 'c', 'z'} for the NumPy
        types {float32, float64, complex64, complex128} respectively, and
        are stored in attribute ``typecode`` of the returned functions.

        Examples
        --------
        Suppose we would like to use '?lange' routine which computes the selected
        norm of an array. We pass our array in order to get the correct 'lange'
        flavor.

        >>> import numpy as np
        >>> import scipy.linalg as LA
        >>> rng = np.random.default_rng()

        >>> a = rng.random((3,2))
        >>> x_lange = LA.get_lapack_funcs('lange', (a,))
        >>> x_lange.typecode
        'd'
        >>> x_lange = LA.get_lapack_funcs('lange',(a*1j,))
        >>> x_lange.typecode
        'z'

        Several LAPACK routines work best when its internal WORK array has
        the optimal size (big enough for fast computation and small enough to
        avoid waste of memory). This size is determined also by a dedicated query
        to the function which is often wrapped as a standalone function and
        commonly denoted as ``###_lwork``. Below is an example for ``?sysv``

        >>> a = rng.random((1000, 1000))
        >>> b = rng.random((1000, 1)) * 1j
        >>> # We pick up zsysv and zsysv_lwork due to b array
        ... xsysv, xlwork = LA.get_lapack_funcs(('sysv', 'sysv_lwork'), (a, b))
        >>> opt_lwork, _ = xlwork(a.shape[0])  # returns a complex for 'z' prefix
        >>> udut, ipiv, x, info = xsysv(a, b, lwork=int(opt_lwork.real))

    hadamard(n, dtype=<class 'int'>)
        Construct an Hadamard matrix.

        Constructs an n-by-n Hadamard matrix, using Sylvester's
        construction. `n` must be a power of 2.

        Parameters
        ----------
        n : int
            The order of the matrix. `n` must be a power of 2.
        dtype : dtype, optional
            The data type of the array to be constructed.

        Returns
        -------
        H : (n, n) ndarray
            The Hadamard matrix.

        Notes
        -----
        .. versionadded:: 0.8.0

        Examples
        --------
        >>> from scipy.linalg import hadamard
        >>> hadamard(2, dtype=complex)
        array([[ 1.+0.j,  1.+0.j],
               [ 1.+0.j, -1.-0.j]])
        >>> hadamard(4)
        array([[ 1,  1,  1,  1],
               [ 1, -1,  1, -1],
               [ 1,  1, -1, -1],
               [ 1, -1, -1,  1]])

    hankel(c, r=None)
        Construct a Hankel matrix.

        The Hankel matrix has constant anti-diagonals, with `c` as its
        first column and `r` as its last row. If `r` is not given, then
        `r = zeros_like(c)` is assumed.

        Parameters
        ----------
        c : array_like
            First column of the matrix. Whatever the actual shape of `c`, it
            will be converted to a 1-D array.
        r : array_like, optional
            Last row of the matrix. If None, ``r = zeros_like(c)`` is assumed.
            r[0] is ignored; the last row of the returned matrix is
            ``[c[-1], r[1:]]``. Whatever the actual shape of `r`, it will be
            converted to a 1-D array.

        Returns
        -------
        A : (len(c), len(r)) ndarray
            The Hankel matrix. Dtype is the same as ``(c[0] + r[0]).dtype``.

        See Also
        --------
        toeplitz : Toeplitz matrix
        circulant : circulant matrix

        Examples
        --------
        >>> from scipy.linalg import hankel
        >>> hankel([1, 17, 99])
        array([[ 1, 17, 99],
               [17, 99,  0],
               [99,  0,  0]])
        >>> hankel([1,2,3,4], [4,7,7,8,9])
        array([[1, 2, 3, 4, 7],
               [2, 3, 4, 7, 7],
               [3, 4, 7, 7, 8],
               [4, 7, 7, 8, 9]])

    helmert(n, full=False)
        Create an Helmert matrix of order `n`.

        This has applications in statistics, compositional or simplicial analysis,
        and in Aitchison geometry.

        Parameters
        ----------
        n : int
            The size of the array to create.
        full : bool, optional
            If True the (n, n) ndarray will be returned.
            Otherwise the submatrix that does not include the first
            row will be returned.
            Default: False.

        Returns
        -------
        M : ndarray
            The Helmert matrix.
            The shape is (n, n) or (n-1, n) depending on the `full` argument.

        Examples
        --------
        >>> from scipy.linalg import helmert
        >>> helmert(5, full=True)
        array([[ 0.4472136 ,  0.4472136 ,  0.4472136 ,  0.4472136 ,  0.4472136 ],
               [ 0.70710678, -0.70710678,  0.        ,  0.        ,  0.        ],
               [ 0.40824829,  0.40824829, -0.81649658,  0.        ,  0.        ],
               [ 0.28867513,  0.28867513,  0.28867513, -0.8660254 ,  0.        ],
               [ 0.2236068 ,  0.2236068 ,  0.2236068 ,  0.2236068 , -0.89442719]])

    hessenberg(a, calc_q=False, overwrite_a=False, check_finite=True)
        Compute Hessenberg form of a matrix.

        The Hessenberg decomposition is::

            A = Q H Q^H

        where `Q` is unitary/orthogonal and `H` has only zero elements below
        the first sub-diagonal.

        Parameters
        ----------
        a : (M, M) array_like
            Matrix to bring into Hessenberg form.
        calc_q : bool, optional
            Whether to compute the transformation matrix.  Default is False.
        overwrite_a : bool, optional
            Whether to overwrite `a`; may improve performance.
            Default is False.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        H : (M, M) ndarray
            Hessenberg form of `a`.
        Q : (M, M) ndarray
            Unitary/orthogonal similarity transformation matrix ``A = Q H Q^H``.
            Only returned if ``calc_q=True``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import hessenberg
        >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
        >>> H, Q = hessenberg(A, calc_q=True)
        >>> H
        array([[  2.        , -11.65843866,   1.42005301,   0.25349066],
               [ -9.94987437,  14.53535354,  -5.31022304,   2.43081618],
               [  0.        ,  -1.83299243,   0.38969961,  -0.51527034],
               [  0.        ,   0.        ,  -3.83189513,   1.07494686]])
        >>> np.allclose(Q @ H @ Q.conj().T - A, np.zeros((4, 4)))
        True

    hilbert(n)
        Create a Hilbert matrix of order `n`.

        Returns the `n` by `n` array with entries `h[i,j] = 1 / (i + j + 1)`.

        Parameters
        ----------
        n : int
            The size of the array to create.

        Returns
        -------
        h : (n, n) ndarray
            The Hilbert matrix.

        See Also
        --------
        invhilbert : Compute the inverse of a Hilbert matrix.

        Notes
        -----
        .. versionadded:: 0.10.0

        Examples
        --------
        >>> from scipy.linalg import hilbert
        >>> hilbert(3)
        array([[ 1.        ,  0.5       ,  0.33333333],
               [ 0.5       ,  0.33333333,  0.25      ],
               [ 0.33333333,  0.25      ,  0.2       ]])

    inv(a, overwrite_a=False, check_finite=True)
        Compute the inverse of a matrix.

        Parameters
        ----------
        a : array_like
            Square matrix to be inverted.
        overwrite_a : bool, optional
            Discard data in `a` (may improve performance). Default is False.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        ainv : ndarray
            Inverse of the matrix `a`.

        Raises
        ------
        LinAlgError
            If `a` is singular.
        ValueError
            If `a` is not square, or not 2D.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[1., 2.], [3., 4.]])
        >>> linalg.inv(a)
        array([[-2. ,  1. ],
               [ 1.5, -0.5]])
        >>> np.dot(a, linalg.inv(a))
        array([[ 1.,  0.],
               [ 0.,  1.]])

    invhilbert(n, exact=False)
        Compute the inverse of the Hilbert matrix of order `n`.

        The entries in the inverse of a Hilbert matrix are integers. When `n`
        is greater than 14, some entries in the inverse exceed the upper limit
        of 64 bit integers. The `exact` argument provides two options for
        dealing with these large integers.

        Parameters
        ----------
        n : int
            The order of the Hilbert matrix.
        exact : bool, optional
            If False, the data type of the array that is returned is np.float64,
            and the array is an approximation of the inverse.
            If True, the array is the exact integer inverse array. To represent
            the exact inverse when n > 14, the returned array is an object array
            of long integers. For n <= 14, the exact inverse is returned as an
            array with data type np.int64.

        Returns
        -------
        invh : (n, n) ndarray
            The data type of the array is np.float64 if `exact` is False.
            If `exact` is True, the data type is either np.int64 (for n <= 14)
            or object (for n > 14). In the latter case, the objects in the
            array will be long integers.

        See Also
        --------
        hilbert : Create a Hilbert matrix.

        Notes
        -----
        .. versionadded:: 0.10.0

        Examples
        --------
        >>> from scipy.linalg import invhilbert
        >>> invhilbert(4)
        array([[   16.,  -120.,   240.,  -140.],
               [ -120.,  1200., -2700.,  1680.],
               [  240., -2700.,  6480., -4200.],
               [ -140.,  1680., -4200.,  2800.]])
        >>> invhilbert(4, exact=True)
        array([[   16,  -120,   240,  -140],
               [ -120,  1200, -2700,  1680],
               [  240, -2700,  6480, -4200],
               [ -140,  1680, -4200,  2800]], dtype=int64)
        >>> invhilbert(16)[7,7]
        4.2475099528537506e+19
        >>> invhilbert(16, exact=True)[7,7]
        42475099528537378560

    invpascal(n, kind='symmetric', exact=True)
        Returns the inverse of the n x n Pascal matrix.

        The Pascal matrix is a matrix containing the binomial coefficients as
        its elements.

        Parameters
        ----------
        n : int
            The size of the matrix to create; that is, the result is an n x n
            matrix.
        kind : str, optional
            Must be one of 'symmetric', 'lower', or 'upper'.
            Default is 'symmetric'.
        exact : bool, optional
            If `exact` is True, the result is either an array of type
            ``numpy.int64`` (if `n` <= 35) or an object array of Python integers.
            If `exact` is False, the coefficients in the matrix are computed using
            `scipy.special.comb` with `exact=False`. The result will be a floating
            point array, and for large `n`, the values in the array will not be the
            exact coefficients.

        Returns
        -------
        invp : (n, n) ndarray
            The inverse of the Pascal matrix.

        See Also
        --------
        pascal

        Notes
        -----

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] "Pascal matrix", https://en.wikipedia.org/wiki/Pascal_matrix
        .. [2] Cohen, A. M., "The inverse of a Pascal matrix", Mathematical
               Gazette, 59(408), pp. 111-112, 1975.

        Examples
        --------
        >>> from scipy.linalg import invpascal, pascal
        >>> invp = invpascal(5)
        >>> invp
        array([[  5, -10,  10,  -5,   1],
               [-10,  30, -35,  19,  -4],
               [ 10, -35,  46, -27,   6],
               [ -5,  19, -27,  17,  -4],
               [  1,  -4,   6,  -4,   1]])

        >>> p = pascal(5)
        >>> p.dot(invp)
        array([[ 1.,  0.,  0.,  0.,  0.],
               [ 0.,  1.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  1.,  0.],
               [ 0.,  0.,  0.,  0.,  1.]])

        An example of the use of `kind` and `exact`:

        >>> invpascal(5, kind='lower', exact=False)
        array([[ 1., -0.,  0., -0.,  0.],
               [-1.,  1., -0.,  0., -0.],
               [ 1., -2.,  1., -0.,  0.],
               [-1.,  3., -3.,  1., -0.],
               [ 1., -4.,  6., -4.,  1.]])

    ishermitian(a, atol=None, rtol=None)
        ishermitian(a, atol=None, rtol=None)
        Check if a square 2D array is Hermitian.

            Parameters
            ----------
            a : ndarray
                Input array of size (N, N)

            atol : float, optional
                Absolute error bound

            rtol : float, optional
                Relative error bound

            Returns
            -------
            her : bool
                Returns True if the array Hermitian.

            Raises
            ------
            TypeError
                If the dtype of the array is not supported, in particular, NumPy
                float16, float128 and complex256 dtypes.

            See Also
            --------
            issymmetric : Check if a square 2D array is symmetric

            Notes
            -----
            For square empty arrays the result is returned True by convention.

            `numpy.inf` will be treated as a number, that is to say ``[[1, inf],
            [inf, 2]]`` will return ``True``. On the other hand `numpy.nan` is never
            symmetric, say, ``[[1, nan], [nan, 2]]`` will return ``False``.

            When ``atol`` and/or ``rtol`` are set to , then the comparison is performed
            by `numpy.allclose` and the tolerance values are passed to it. Otherwise an
            exact comparison against zero is performed by internal functions. Hence
            performance can improve or degrade depending on the size and dtype of the
            array. If one of ``atol`` or ``rtol`` given the other one is automatically
            set to zero.

            Examples
            --------
            >>> import numpy as np
            >>> from scipy.linalg import ishermitian
            >>> A = np.arange(9).reshape(3, 3)
            >>> A = A + A.T
            >>> ishermitian(A)
            True
            >>> A = np.array([[1., 2. + 3.j], [2. - 3.j, 4.]])
            >>> ishermitian(A)
            True
            >>> Ac = np.array([[1. + 1.j, 3.j], [3.j, 2.]])
            >>> ishermitian(Ac)  # not Hermitian but symmetric
            False
            >>> Af = np.array([[0, 1 + 1j], [1 - (1+1e-12)*1j, 0]])
            >>> ishermitian(Af)
            False
            >>> ishermitian(Af, atol=5e-11) # almost hermitian with atol
            True

    issymmetric(a, atol=None, rtol=None)
        issymmetric(a, atol=None, rtol=None)
        Check if a square 2D array is symmetric.

            Parameters
            ----------
            a : ndarray
                Input array of size (N, N).

            atol : float, optional
                Absolute error bound

            rtol : float, optional
                Relative error bound

            Returns
            -------
            sym : bool
                Returns True if the array symmetric.

            Raises
            ------
            TypeError
                If the dtype of the array is not supported, in particular, NumPy
                float16, float128 and complex256 dtypes for exact comparisons.

            See Also
            --------
            ishermitian : Check if a square 2D array is Hermitian

            Notes
            -----
            For square empty arrays the result is returned True by convention. Complex
            valued arrays are tested for symmetricity and not for being Hermitian (see
            examples)

            The diagonal of the array is not scanned. Thus if there are infs, NaNs or
            similar problematic entries on the diagonal, they will be ignored. However,
            `numpy.inf` will be treated as a number, that is to say ``[[1, inf],
            [inf, 2]]`` will return ``True``. On the other hand `numpy.nan` is never
            symmetric, say, ``[[1, nan], [nan, 2]]`` will return ``False``.

            When ``atol`` and/or ``rtol`` are set to , then the comparison is performed
            by `numpy.allclose` and the tolerance values are passed to it. Otherwise an
            exact comparison against zero is performed by internal functions. Hence
            performance can improve or degrade depending on the size and dtype of the
            array. If one of ``atol`` or ``rtol`` given the other one is automatically
            set to zero.

            Examples
            --------
            >>> import numpy as np
            >>> from scipy.linalg import issymmetric
            >>> A = np.arange(9).reshape(3, 3)
            >>> A = A + A.T
            >>> issymmetric(A)
            True
            >>> Ac = np.array([[1. + 1.j, 3.j], [3.j, 2.]])
            >>> issymmetric(Ac)  # not Hermitian but symmetric
            True

    khatri_rao(a, b)
        Khatri-rao product

        A column-wise Kronecker product of two matrices

        Parameters
        ----------
        a : (n, k) array_like
            Input array
        b : (m, k) array_like
            Input array

        Returns
        -------
        c:  (n*m, k) ndarray
            Khatri-rao product of `a` and `b`.

        See Also
        --------
        kron : Kronecker product

        Notes
        -----
        The mathematical definition of the Khatri-Rao product is:

        .. math::

            (A_{ij}  \bigotimes B_{ij})_{ij}

        which is the Kronecker product of every column of A and B, e.g.::

            c = np.vstack([np.kron(a[:, k], b[:, k]) for k in range(b.shape[1])]).T

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[1, 2, 3], [4, 5, 6]])
        >>> b = np.array([[3, 4, 5], [6, 7, 8], [2, 3, 9]])
        >>> linalg.khatri_rao(a, b)
        array([[ 3,  8, 15],
               [ 6, 14, 24],
               [ 2,  6, 27],
               [12, 20, 30],
               [24, 35, 48],
               [ 8, 15, 54]])

    kron(a, b)
        Kronecker product.

        The result is the block matrix::

            a[0,0]*b    a[0,1]*b  ... a[0,-1]*b
            a[1,0]*b    a[1,1]*b  ... a[1,-1]*b
            ...
            a[-1,0]*b   a[-1,1]*b ... a[-1,-1]*b

        Parameters
        ----------
        a : (M, N) ndarray
            Input array
        b : (P, Q) ndarray
            Input array

        Returns
        -------
        A : (M*P, N*Q) ndarray
            Kronecker product of `a` and `b`.

        Examples
        --------
        >>> from numpy import array
        >>> from scipy.linalg import kron
        >>> kron(array([[1,2],[3,4]]), array([[1,1,1]]))
        array([[1, 1, 1, 2, 2, 2],
               [3, 3, 3, 4, 4, 4]])

    ldl(A, lower=True, hermitian=True, overwrite_a=False, check_finite=True)
        Computes the LDLt or Bunch-Kaufman factorization of a symmetric/
        hermitian matrix.

        This function returns a block diagonal matrix D consisting blocks of size
        at most 2x2 and also a possibly permuted unit lower triangular matrix
        ``L`` such that the factorization ``A = L D L^H`` or ``A = L D L^T``
        holds. If `lower` is False then (again possibly permuted) upper
        triangular matrices are returned as outer factors.

        The permutation array can be used to triangularize the outer factors
        simply by a row shuffle, i.e., ``lu[perm, :]`` is an upper/lower
        triangular matrix. This is also equivalent to multiplication with a
        permutation matrix ``P.dot(lu)``, where ``P`` is a column-permuted
        identity matrix ``I[:, perm]``.

        Depending on the value of the boolean `lower`, only upper or lower
        triangular part of the input array is referenced. Hence, a triangular
        matrix on entry would give the same result as if the full matrix is
        supplied.

        Parameters
        ----------
        A : array_like
            Square input array
        lower : bool, optional
            This switches between the lower and upper triangular outer factors of
            the factorization. Lower triangular (``lower=True``) is the default.
        hermitian : bool, optional
            For complex-valued arrays, this defines whether ``A = A.conj().T`` or
            ``A = A.T`` is assumed. For real-valued arrays, this switch has no
            effect.
        overwrite_a : bool, optional
            Allow overwriting data in `A` (may enhance performance). The default
            is False.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        lu : ndarray
            The (possibly) permuted upper/lower triangular outer factor of the
            factorization.
        d : ndarray
            The block diagonal multiplier of the factorization.
        perm : ndarray
            The row-permutation index array that brings lu into triangular form.

        Raises
        ------
        ValueError
            If input array is not square.
        ComplexWarning
            If a complex-valued array with nonzero imaginary parts on the
            diagonal is given and hermitian is set to True.

        See Also
        --------
        cholesky, lu

        Notes
        -----
        This function uses ``?SYTRF`` routines for symmetric matrices and
        ``?HETRF`` routines for Hermitian matrices from LAPACK. See [1]_ for
        the algorithm details.

        Depending on the `lower` keyword value, only lower or upper triangular
        part of the input array is referenced. Moreover, this keyword also defines
        the structure of the outer factors of the factorization.

        .. versionadded:: 1.1.0

        References
        ----------
        .. [1] J.R. Bunch, L. Kaufman, Some stable methods for calculating
           inertia and solving symmetric linear systems, Math. Comput. Vol.31,
           1977. :doi:`10.2307/2005787`

        Examples
        --------
        Given an upper triangular array ``a`` that represents the full symmetric
        array with its entries, obtain ``l``, 'd' and the permutation vector `perm`:

        >>> import numpy as np
        >>> from scipy.linalg import ldl
        >>> a = np.array([[2, -1, 3], [0, 2, 0], [0, 0, 1]])
        >>> lu, d, perm = ldl(a, lower=0) # Use the upper part
        >>> lu
        array([[ 0. ,  0. ,  1. ],
               [ 0. ,  1. , -0.5],
               [ 1. ,  1. ,  1.5]])
        >>> d
        array([[-5. ,  0. ,  0. ],
               [ 0. ,  1.5,  0. ],
               [ 0. ,  0. ,  2. ]])
        >>> perm
        array([2, 1, 0])
        >>> lu[perm, :]
        array([[ 1. ,  1. ,  1.5],
               [ 0. ,  1. , -0.5],
               [ 0. ,  0. ,  1. ]])
        >>> lu.dot(d).dot(lu.T)
        array([[ 2., -1.,  3.],
               [-1.,  2.,  0.],
               [ 3.,  0.,  1.]])

    leslie(f, s)
        Create a Leslie matrix.

        Given the length n array of fecundity coefficients `f` and the length
        n-1 array of survival coefficients `s`, return the associated Leslie
        matrix.

        Parameters
        ----------
        f : (N,) array_like
            The "fecundity" coefficients.
        s : (N-1,) array_like
            The "survival" coefficients, has to be 1-D.  The length of `s`
            must be one less than the length of `f`, and it must be at least 1.

        Returns
        -------
        L : (N, N) ndarray
            The array is zero except for the first row,
            which is `f`, and the first sub-diagonal, which is `s`.
            The data-type of the array will be the data-type of ``f[0]+s[0]``.

        Notes
        -----
        .. versionadded:: 0.8.0

        The Leslie matrix is used to model discrete-time, age-structured
        population growth [1]_ [2]_. In a population with `n` age classes, two sets
        of parameters define a Leslie matrix: the `n` "fecundity coefficients",
        which give the number of offspring per-capita produced by each age
        class, and the `n` - 1 "survival coefficients", which give the
        per-capita survival rate of each age class.

        References
        ----------
        .. [1] P. H. Leslie, On the use of matrices in certain population
               mathematics, Biometrika, Vol. 33, No. 3, 183--212 (Nov. 1945)
        .. [2] P. H. Leslie, Some further notes on the use of matrices in
               population mathematics, Biometrika, Vol. 35, No. 3/4, 213--245
               (Dec. 1948)

        Examples
        --------
        >>> from scipy.linalg import leslie
        >>> leslie([0.1, 2.0, 1.0, 0.1], [0.2, 0.8, 0.7])
        array([[ 0.1,  2. ,  1. ,  0.1],
               [ 0.2,  0. ,  0. ,  0. ],
               [ 0. ,  0.8,  0. ,  0. ],
               [ 0. ,  0. ,  0.7,  0. ]])

    logm(A, disp=True)
        Compute matrix logarithm.

        The matrix logarithm is the inverse of
        expm: expm(logm(`A`)) == `A`

        Parameters
        ----------
        A : (N, N) array_like
            Matrix whose logarithm to evaluate
        disp : bool, optional
            Print warning if error in the result is estimated large
            instead of returning estimated error. (Default: True)

        Returns
        -------
        logm : (N, N) ndarray
            Matrix logarithm of `A`
        errest : float
            (if disp == False)

            1-norm of the estimated error, ||err||_1 / ||A||_1

        References
        ----------
        .. [1] Awad H. Al-Mohy and Nicholas J. Higham (2012)
               "Improved Inverse Scaling and Squaring Algorithms
               for the Matrix Logarithm."
               SIAM Journal on Scientific Computing, 34 (4). C152-C169.
               ISSN 1095-7197

        .. [2] Nicholas J. Higham (2008)
               "Functions of Matrices: Theory and Computation"
               ISBN 978-0-898716-46-7

        .. [3] Nicholas J. Higham and Lijing lin (2011)
               "A Schur-Pade Algorithm for Fractional Powers of a Matrix."
               SIAM Journal on Matrix Analysis and Applications,
               32 (3). pp. 1056-1078. ISSN 0895-4798

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import logm, expm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> b = logm(a)
        >>> b
        array([[-1.02571087,  2.05142174],
               [ 0.68380725,  1.02571087]])
        >>> expm(b)         # Verify expm(logm(a)) returns a
        array([[ 1.,  3.],
               [ 1.,  4.]])

    lstsq(a, b, cond=None, overwrite_a=False, overwrite_b=False, check_finite=True, lapack_driver=None)
        Compute least-squares solution to equation Ax = b.

        Compute a vector x such that the 2-norm ``|b - A x|`` is minimized.

        Parameters
        ----------
        a : (M, N) array_like
            Left-hand side array
        b : (M,) or (M, K) array_like
            Right hand side array
        cond : float, optional
            Cutoff for 'small' singular values; used to determine effective
            rank of a. Singular values smaller than
            ``cond * largest_singular_value`` are considered zero.
        overwrite_a : bool, optional
            Discard data in `a` (may enhance performance). Default is False.
        overwrite_b : bool, optional
            Discard data in `b` (may enhance performance). Default is False.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        lapack_driver : str, optional
            Which LAPACK driver is used to solve the least-squares problem.
            Options are ``'gelsd'``, ``'gelsy'``, ``'gelss'``. Default
            (``'gelsd'``) is a good choice.  However, ``'gelsy'`` can be slightly
            faster on many problems.  ``'gelss'`` was used historically.  It is
            generally slow but uses less memory.

            .. versionadded:: 0.17.0

        Returns
        -------
        x : (N,) or (N, K) ndarray
            Least-squares solution.
        residues : (K,) ndarray or float
            Square of the 2-norm for each column in ``b - a x``, if ``M > N`` and
            ``rank(A) == n`` (returns a scalar if ``b`` is 1-D). Otherwise a
            (0,)-shaped array is returned.
        rank : int
            Effective rank of `a`.
        s : (min(M, N),) ndarray or None
            Singular values of `a`. The condition number of ``a`` is
            ``s[0] / s[-1]``.

        Raises
        ------
        LinAlgError
            If computation does not converge.

        ValueError
            When parameters are not compatible.

        See Also
        --------
        scipy.optimize.nnls : linear least squares with non-negativity constraint

        Notes
        -----
        When ``'gelsy'`` is used as a driver, `residues` is set to a (0,)-shaped
        array and `s` is always ``None``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import lstsq
        >>> import matplotlib.pyplot as plt

        Suppose we have the following data:

        >>> x = np.array([1, 2.5, 3.5, 4, 5, 7, 8.5])
        >>> y = np.array([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6])

        We want to fit a quadratic polynomial of the form ``y = a + b*x**2``
        to this data.  We first form the "design matrix" M, with a constant
        column of 1s and a column containing ``x**2``:

        >>> M = x[:, np.newaxis]**[0, 2]
        >>> M
        array([[  1.  ,   1.  ],
               [  1.  ,   6.25],
               [  1.  ,  12.25],
               [  1.  ,  16.  ],
               [  1.  ,  25.  ],
               [  1.  ,  49.  ],
               [  1.  ,  72.25]])

        We want to find the least-squares solution to ``M.dot(p) = y``,
        where ``p`` is a vector with length 2 that holds the parameters
        ``a`` and ``b``.

        >>> p, res, rnk, s = lstsq(M, y)
        >>> p
        array([ 0.20925829,  0.12013861])

        Plot the data and the fitted curve.

        >>> plt.plot(x, y, 'o', label='data')
        >>> xx = np.linspace(0, 9, 101)
        >>> yy = p[0] + p[1]*xx**2
        >>> plt.plot(xx, yy, label='least squares fit, $y = a + bx^2$')
        >>> plt.xlabel('x')
        >>> plt.ylabel('y')
        >>> plt.legend(framealpha=1, shadow=True)
        >>> plt.grid(alpha=0.25)
        >>> plt.show()

    lu(a, permute_l=False, overwrite_a=False, check_finite=True, p_indices=False)
        Compute LU decomposition of a matrix with partial pivoting.

        The decomposition satisfies::

            A = P @ L @ U

        where ``P`` is a permutation matrix, ``L`` lower triangular with unit
        diagonal elements, and ``U`` upper triangular. If `permute_l` is set to
        ``True`` then ``L`` is returned already permuted and hence satisfying
        ``A = L @ U``.

        Parameters
        ----------
        a : (M, N) array_like
            Array to decompose
        permute_l : bool, optional
            Perform the multiplication P*L (Default: do not permute)
        overwrite_a : bool, optional
            Whether to overwrite data in a (may improve performance)
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        p_indices : bool, optional
            If ``True`` the permutation information is returned as row indices.
            The default is ``False`` for backwards-compatibility reasons.

        Returns
        -------
        **(If `permute_l` is ``False``)**

        p : (..., M, M) ndarray
            Permutation arrays or vectors depending on `p_indices`
        l : (..., M, K) ndarray
            Lower triangular or trapezoidal array with unit diagonal.
            ``K = min(M, N)``
        u : (..., K, N) ndarray
            Upper triangular or trapezoidal array

        **(If `permute_l` is ``True``)**

        pl : (..., M, K) ndarray
            Permuted L matrix.
            ``K = min(M, N)``
        u : (..., K, N) ndarray
            Upper triangular or trapezoidal array

        Notes
        -----
        Permutation matrices are costly since they are nothing but row reorder of
        ``L`` and hence indices are strongly recommended to be used instead if the
        permutation is required. The relation in the 2D case then becomes simply
        ``A = L[P, :] @ U``. In higher dimensions, it is better to use `permute_l`
        to avoid complicated indexing tricks.

        In 2D case, if one has the indices however, for some reason, the
        permutation matrix is still needed then it can be constructed by
        ``np.eye(M)[P, :]``.

        Examples
        --------

        >>> import numpy as np
        >>> from scipy.linalg import lu
        >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
        >>> p, l, u = lu(A)
        >>> np.allclose(A, p @ l @ u)
        True
        >>> p  # Permutation matrix
        array([[0., 1., 0., 0.],  # Row index 1
               [0., 0., 0., 1.],  # Row index 3
               [1., 0., 0., 0.],  # Row index 0
               [0., 0., 1., 0.]]) # Row index 2
        >>> p, _, _ = lu(A, p_indices=True)
        >>> p
        array([1, 3, 0, 2])  # as given by row indices above
        >>> np.allclose(A, l[p, :] @ u)
        True

        We can also use nd-arrays, for example, a demonstration with 4D array:

        >>> rng = np.random.default_rng()
        >>> A = rng.uniform(low=-4, high=4, size=[3, 2, 4, 8])
        >>> p, l, u = lu(A)
        >>> p.shape, l.shape, u.shape
        ((3, 2, 4, 4), (3, 2, 4, 4), (3, 2, 4, 8))
        >>> np.allclose(A, p @ l @ u)
        True
        >>> PL, U = lu(A, permute_l=True)
        >>> np.allclose(A, PL @ U)
        True

    lu_factor(a, overwrite_a=False, check_finite=True)
        Compute pivoted LU decomposition of a matrix.

        The decomposition is::

            A = P L U

        where P is a permutation matrix, L lower triangular with unit
        diagonal elements, and U upper triangular.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to decompose
        overwrite_a : bool, optional
            Whether to overwrite data in A (may increase performance)
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        lu : (M, N) ndarray
            Matrix containing U in its upper triangle, and L in its lower triangle.
            The unit diagonal elements of L are not stored.
        piv : (K,) ndarray
            Pivot indices representing the permutation matrix P:
            row i of matrix was interchanged with row piv[i].
            Of shape ``(K,)``, with ``K = min(M, N)``.

        See Also
        --------
        lu : gives lu factorization in more user-friendly format
        lu_solve : solve an equation system using the LU factorization of a matrix

        Notes
        -----
        This is a wrapper to the ``*GETRF`` routines from LAPACK. Unlike
        :func:`lu`, it outputs the L and U factors into a single array
        and returns pivot indices instead of a permutation matrix.

        While the underlying ``*GETRF`` routines return 1-based pivot indices, the
        ``piv`` array returned by ``lu_factor`` contains 0-based indices.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import lu_factor
        >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
        >>> lu, piv = lu_factor(A)
        >>> piv
        array([2, 2, 3, 3], dtype=int32)

        Convert LAPACK's ``piv`` array to NumPy index and test the permutation

        >>> def pivot_to_permutation(piv):
        ...     perm = np.arange(len(piv))
        ...     for i in range(len(piv)):
        ...         perm[i], perm[piv[i]] = perm[piv[i]], perm[i]
        ...     return perm
        ...
        >>> p_inv = pivot_to_permutation(piv)
        >>> p_inv
        array([2, 0, 3, 1])
        >>> L, U = np.tril(lu, k=-1) + np.eye(4), np.triu(lu)
        >>> np.allclose(A[p_inv] - L @ U, np.zeros((4, 4)))
        True

        The P matrix in P L U is defined by the inverse permutation and
        can be recovered using argsort:

        >>> p = np.argsort(p_inv)
        >>> p
        array([1, 3, 0, 2])
        >>> np.allclose(A - L[p] @ U, np.zeros((4, 4)))
        True

        or alternatively:

        >>> P = np.eye(4)[p]
        >>> np.allclose(A - P @ L @ U, np.zeros((4, 4)))
        True

    lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True)
        Solve an equation system, a x = b, given the LU factorization of a

        Parameters
        ----------
        (lu, piv)
            Factorization of the coefficient matrix a, as given by lu_factor.
            In particular piv are 0-indexed pivot indices.
        b : array
            Right-hand side
        trans : {0, 1, 2}, optional
            Type of system to solve:

            =====  =========
            trans  system
            =====  =========
            0      a x   = b
            1      a^T x = b
            2      a^H x = b
            =====  =========
        overwrite_b : bool, optional
            Whether to overwrite data in b (may increase performance)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : array
            Solution to the system

        See Also
        --------
        lu_factor : LU factorize a matrix

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import lu_factor, lu_solve
        >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
        >>> b = np.array([1, 1, 1, 1])
        >>> lu, piv = lu_factor(A)
        >>> x = lu_solve((lu, piv), b)
        >>> np.allclose(A @ x - b, np.zeros((4,)))
        True

    matmul_toeplitz(c_or_cr, x, check_finite=False, workers=None)
        Efficient Toeplitz Matrix-Matrix Multiplication using FFT

        This function returns the matrix multiplication between a Toeplitz
        matrix and a dense matrix.

        The Toeplitz matrix has constant diagonals, with c as its first column
        and r as its first row. If r is not given, ``r == conjugate(c)`` is
        assumed.

        Parameters
        ----------
        c_or_cr : array_like or tuple of (array_like, array_like)
            The vector ``c``, or a tuple of arrays (``c``, ``r``). Whatever the
            actual shape of ``c``, it will be converted to a 1-D array. If not
            supplied, ``r = conjugate(c)`` is assumed; in this case, if c[0] is
            real, the Toeplitz matrix is Hermitian. r[0] is ignored; the first row
            of the Toeplitz matrix is ``[c[0], r[1:]]``. Whatever the actual shape
            of ``r``, it will be converted to a 1-D array.
        x : (M,) or (M, K) array_like
            Matrix with which to multiply.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (result entirely NaNs) if the inputs do contain infinities or NaNs.
        workers : int, optional
            To pass to scipy.fft.fft and ifft. Maximum number of workers to use
            for parallel computation. If negative, the value wraps around from
            ``os.cpu_count()``. See scipy.fft.fft for more details.

        Returns
        -------
        T @ x : (M,) or (M, K) ndarray
            The result of the matrix multiplication ``T @ x``. Shape of return
            matches shape of `x`.

        See Also
        --------
        toeplitz : Toeplitz matrix
        solve_toeplitz : Solve a Toeplitz system using Levinson Recursion

        Notes
        -----
        The Toeplitz matrix is embedded in a circulant matrix and the FFT is used
        to efficiently calculate the matrix-matrix product.

        Because the computation is based on the FFT, integer inputs will
        result in floating point outputs.  This is unlike NumPy's `matmul`,
        which preserves the data type of the input.

        This is partly based on the implementation that can be found in [1]_,
        licensed under the MIT license. More information about the method can be
        found in reference [2]_. References [3]_ and [4]_ have more reference
        implementations in Python.

        .. versionadded:: 1.6.0

        References
        ----------
        .. [1] Jacob R Gardner, Geoff Pleiss, David Bindel, Kilian
           Q Weinberger, Andrew Gordon Wilson, "GPyTorch: Blackbox Matrix-Matrix
           Gaussian Process Inference with GPU Acceleration" with contributions
           from Max Balandat and Ruihan Wu. Available online:
           https://github.com/cornellius-gp/gpytorch

        .. [2] J. Demmel, P. Koev, and X. Li, "A Brief Survey of Direct Linear
           Solvers". In Z. Bai, J. Demmel, J. Dongarra, A. Ruhe, and H. van der
           Vorst, editors. Templates for the Solution of Algebraic Eigenvalue
           Problems: A Practical Guide. SIAM, Philadelphia, 2000. Available at:
           http://www.netlib.org/utk/people/JackDongarra/etemplates/node384.html

        .. [3] R. Scheibler, E. Bezzam, I. Dokmanic, Pyroomacoustics: A Python
           package for audio room simulations and array processing algorithms,
           Proc. IEEE ICASSP, Calgary, CA, 2018.
           https://github.com/LCAV/pyroomacoustics/blob/pypi-release/
           pyroomacoustics/adaptive/util.py

        .. [4] Marano S, Edwards B, Ferrari G and Fah D (2017), "Fitting
           Earthquake Spectra: Colored Noise and Incomplete Data", Bulletin of
           the Seismological Society of America., January, 2017. Vol. 107(1),
           pp. 276-291.

        Examples
        --------
        Multiply the Toeplitz matrix T with matrix x::

                [ 1 -1 -2 -3]       [1 10]
            T = [ 3  1 -1 -2]   x = [2 11]
                [ 6  3  1 -1]       [2 11]
                [10  6  3  1]       [5 19]

        To specify the Toeplitz matrix, only the first column and the first
        row are needed.

        >>> import numpy as np
        >>> c = np.array([1, 3, 6, 10])    # First column of T
        >>> r = np.array([1, -1, -2, -3])  # First row of T
        >>> x = np.array([[1, 10], [2, 11], [2, 11], [5, 19]])

        >>> from scipy.linalg import toeplitz, matmul_toeplitz
        >>> matmul_toeplitz((c, r), x)
        array([[-20., -80.],
               [ -7.,  -8.],
               [  9.,  85.],
               [ 33., 218.]])

        Check the result by creating the full Toeplitz matrix and
        multiplying it by ``x``.

        >>> toeplitz(c, r) @ x
        array([[-20, -80],
               [ -7,  -8],
               [  9,  85],
               [ 33, 218]])

        The full matrix is never formed explicitly, so this routine
        is suitable for very large Toeplitz matrices.

        >>> n = 1000000
        >>> matmul_toeplitz([1] + [0]*(n-1), np.ones(n))
        array([1., 1., 1., ..., 1., 1., 1.])

    matrix_balance(A, permute=True, scale=True, separate=False, overwrite_a=False)
        Compute a diagonal similarity transformation for row/column balancing.

        The balancing tries to equalize the row and column 1-norms by applying
        a similarity transformation such that the magnitude variation of the
        matrix entries is reflected to the scaling matrices.

        Moreover, if enabled, the matrix is first permuted to isolate the upper
        triangular parts of the matrix and, again if scaling is also enabled,
        only the remaining subblocks are subjected to scaling.

        The balanced matrix satisfies the following equality

        .. math::

                            B = T^{-1} A T

        The scaling coefficients are approximated to the nearest power of 2
        to avoid round-off errors.

        Parameters
        ----------
        A : (n, n) array_like
            Square data matrix for the balancing.
        permute : bool, optional
            The selector to define whether permutation of A is also performed
            prior to scaling.
        scale : bool, optional
            The selector to turn on and off the scaling. If False, the matrix
            will not be scaled.
        separate : bool, optional
            This switches from returning a full matrix of the transformation
            to a tuple of two separate 1-D permutation and scaling arrays.
        overwrite_a : bool, optional
            This is passed to xGEBAL directly. Essentially, overwrites the result
            to the data. It might increase the space efficiency. See LAPACK manual
            for details. This is False by default.

        Returns
        -------
        B : (n, n) ndarray
            Balanced matrix
        T : (n, n) ndarray
            A possibly permuted diagonal matrix whose nonzero entries are
            integer powers of 2 to avoid numerical truncation errors.
        scale, perm : (n,) ndarray
            If ``separate`` keyword is set to True then instead of the array
            ``T`` above, the scaling and the permutation vectors are given
            separately as a tuple without allocating the full array ``T``.

        Notes
        -----
        This algorithm is particularly useful for eigenvalue and matrix
        decompositions and in many cases it is already called by various
        LAPACK routines.

        The algorithm is based on the well-known technique of [1]_ and has
        been modified to account for special cases. See [2]_ for details
        which have been implemented since LAPACK v3.5.0. Before this version
        there are corner cases where balancing can actually worsen the
        conditioning. See [3]_ for such examples.

        The code is a wrapper around LAPACK's xGEBAL routine family for matrix
        balancing.

        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] B.N. Parlett and C. Reinsch, "Balancing a Matrix for
           Calculation of Eigenvalues and Eigenvectors", Numerische Mathematik,
           Vol.13(4), 1969, :doi:`10.1007/BF02165404`
        .. [2] R. James, J. Langou, B.R. Lowery, "On matrix balancing and
           eigenvector computation", 2014, :arxiv:`1401.5766`
        .. [3] D.S. Watkins. A case where balancing is harmful.
           Electron. Trans. Numer. Anal, Vol.23, 2006.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> x = np.array([[1,2,0], [9,1,0.01], [1,2,10*np.pi]])

        >>> y, permscale = linalg.matrix_balance(x)
        >>> np.abs(x).sum(axis=0) / np.abs(x).sum(axis=1)
        array([ 3.66666667,  0.4995005 ,  0.91312162])

        >>> np.abs(y).sum(axis=0) / np.abs(y).sum(axis=1)
        array([ 1.2       ,  1.27041742,  0.92658316])  # may vary

        >>> permscale  # only powers of 2 (0.5 == 2^(-1))
        array([[  0.5,   0. ,  0. ],  # may vary
               [  0. ,   1. ,  0. ],
               [  0. ,   0. ,  1. ]])

    norm(a, ord=None, axis=None, keepdims=False, check_finite=True)
        Matrix or vector norm.

        This function is able to return one of eight different matrix norms,
        or one of an infinite number of vector norms (described below), depending
        on the value of the ``ord`` parameter. For tensors with rank different from
        1 or 2, only `ord=None` is supported.

        Parameters
        ----------
        a : array_like
            Input array. If `axis` is None, `a` must be 1-D or 2-D, unless `ord`
            is None. If both `axis` and `ord` are None, the 2-norm of
            ``a.ravel`` will be returned.
        ord : {int, inf, -inf, 'fro', 'nuc', None}, optional
            Order of the norm (see table under ``Notes``). inf means NumPy's
            `inf` object.
        axis : {int, 2-tuple of ints, None}, optional
            If `axis` is an integer, it specifies the axis of `a` along which to
            compute the vector norms. If `axis` is a 2-tuple, it specifies the
            axes that hold 2-D matrices, and the matrix norms of these matrices
            are computed. If `axis` is None then either a vector norm (when `a`
            is 1-D) or a matrix norm (when `a` is 2-D) is returned.
        keepdims : bool, optional
            If this is set to True, the axes which are normed over are left in the
            result as dimensions with size one. With this option the result will
            broadcast correctly against the original `a`.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        n : float or ndarray
            Norm of the matrix or vector(s).

        Notes
        -----
        For values of ``ord <= 0``, the result is, strictly speaking, not a
        mathematical 'norm', but it may still be useful for various numerical
        purposes.

        The following norms can be calculated:

        =====  ============================  ==========================
        ord    norm for matrices             norm for vectors
        =====  ============================  ==========================
        None   Frobenius norm                2-norm
        'fro'  Frobenius norm                --
        'nuc'  nuclear norm                  --
        inf    max(sum(abs(a), axis=1))      max(abs(a))
        -inf   min(sum(abs(a), axis=1))      min(abs(a))
        0      --                            sum(a != 0)
        1      max(sum(abs(a), axis=0))      as below
        -1     min(sum(abs(a), axis=0))      as below
        2      2-norm (largest sing. value)  as below
        -2     smallest singular value       as below
        other  --                            sum(abs(a)**ord)**(1./ord)
        =====  ============================  ==========================

        The Frobenius norm is given by [1]_:

            :math:`||A||_F = [\sum_{i,j} abs(a_{i,j})^2]^{1/2}`

        The nuclear norm is the sum of the singular values.

        Both the Frobenius and nuclear norm orders are only defined for
        matrices.

        References
        ----------
        .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
               Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import norm
        >>> a = np.arange(9) - 4.0
        >>> a
        array([-4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
        >>> b = a.reshape((3, 3))
        >>> b
        array([[-4., -3., -2.],
               [-1.,  0.,  1.],
               [ 2.,  3.,  4.]])

        >>> norm(a)
        7.745966692414834
        >>> norm(b)
        7.745966692414834
        >>> norm(b, 'fro')
        7.745966692414834
        >>> norm(a, np.inf)
        4
        >>> norm(b, np.inf)
        9
        >>> norm(a, -np.inf)
        0
        >>> norm(b, -np.inf)
        2

        >>> norm(a, 1)
        20
        >>> norm(b, 1)
        7
        >>> norm(a, -1)
        -4.6566128774142013e-010
        >>> norm(b, -1)
        6
        >>> norm(a, 2)
        7.745966692414834
        >>> norm(b, 2)
        7.3484692283495345

        >>> norm(a, -2)
        0
        >>> norm(b, -2)
        1.8570331885190563e-016
        >>> norm(a, 3)
        5.8480354764257312
        >>> norm(a, -3)
        0

    null_space(A, rcond=None)
        Construct an orthonormal basis for the null space of A using SVD

        Parameters
        ----------
        A : (M, N) array_like
            Input array
        rcond : float, optional
            Relative condition number. Singular values ``s`` smaller than
            ``rcond * max(s)`` are considered zero.
            Default: floating point eps * max(M,N).

        Returns
        -------
        Z : (N, K) ndarray
            Orthonormal basis for the null space of A.
            K = dimension of effective null space, as determined by rcond

        See Also
        --------
        svd : Singular value decomposition of a matrix
        orth : Matrix range

        Examples
        --------
        1-D null space:

        >>> import numpy as np
        >>> from scipy.linalg import null_space
        >>> A = np.array([[1, 1], [1, 1]])
        >>> ns = null_space(A)
        >>> ns * np.copysign(1, ns[0,0])  # Remove the sign ambiguity of the vector
        array([[ 0.70710678],
               [-0.70710678]])

        2-D null space:

        >>> from numpy.random import default_rng
        >>> rng = default_rng()
        >>> B = rng.random((3, 5))
        >>> Z = null_space(B)
        >>> Z.shape
        (5, 2)
        >>> np.allclose(B.dot(Z), 0)
        True

        The basis vectors are orthonormal (up to rounding error):

        >>> Z.T.dot(Z)
        array([[  1.00000000e+00,   6.92087741e-17],
               [  6.92087741e-17,   1.00000000e+00]])

    ordqz(A, B, sort='lhp', output='real', overwrite_a=False, overwrite_b=False, check_finite=True)
        QZ decomposition for a pair of matrices with reordering.

        Parameters
        ----------
        A : (N, N) array_like
            2-D array to decompose
        B : (N, N) array_like
            2-D array to decompose
        sort : {callable, 'lhp', 'rhp', 'iuc', 'ouc'}, optional
            Specifies whether the upper eigenvalues should be sorted. A
            callable may be passed that, given an ordered pair ``(alpha,
            beta)`` representing the eigenvalue ``x = (alpha/beta)``,
            returns a boolean denoting whether the eigenvalue should be
            sorted to the top-left (True). For the real matrix pairs
            ``beta`` is real while ``alpha`` can be complex, and for
            complex matrix pairs both ``alpha`` and ``beta`` can be
            complex. The callable must be able to accept a NumPy
            array. Alternatively, string parameters may be used:

                - 'lhp'   Left-hand plane (x.real < 0.0)
                - 'rhp'   Right-hand plane (x.real > 0.0)
                - 'iuc'   Inside the unit circle (x*x.conjugate() < 1.0)
                - 'ouc'   Outside the unit circle (x*x.conjugate() > 1.0)

            With the predefined sorting functions, an infinite eigenvalue
            (i.e., ``alpha != 0`` and ``beta = 0``) is considered to lie in
            neither the left-hand nor the right-hand plane, but it is
            considered to lie outside the unit circle. For the eigenvalue
            ``(alpha, beta) = (0, 0)``, the predefined sorting functions
            all return `False`.
        output : str {'real','complex'}, optional
            Construct the real or complex QZ decomposition for real matrices.
            Default is 'real'.
        overwrite_a : bool, optional
            If True, the contents of A are overwritten.
        overwrite_b : bool, optional
            If True, the contents of B are overwritten.
        check_finite : bool, optional
            If true checks the elements of `A` and `B` are finite numbers. If
            false does no checking and passes matrix through to
            underlying algorithm.

        Returns
        -------
        AA : (N, N) ndarray
            Generalized Schur form of A.
        BB : (N, N) ndarray
            Generalized Schur form of B.
        alpha : (N,) ndarray
            alpha = alphar + alphai * 1j. See notes.
        beta : (N,) ndarray
            See notes.
        Q : (N, N) ndarray
            The left Schur vectors.
        Z : (N, N) ndarray
            The right Schur vectors.

        See Also
        --------
        qz

        Notes
        -----
        On exit, ``(ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N``, will be the
        generalized eigenvalues.  ``ALPHAR(j) + ALPHAI(j)*i`` and
        ``BETA(j),j=1,...,N`` are the diagonals of the complex Schur form (S,T)
        that would result if the 2-by-2 diagonal blocks of the real generalized
        Schur form of (A,B) were further reduced to triangular form using complex
        unitary transformations. If ALPHAI(j) is zero, then the jth eigenvalue is
        real; if positive, then the ``j``\ th and ``(j+1)``\ st eigenvalues are a
        complex conjugate pair, with ``ALPHAI(j+1)`` negative.

        .. versionadded:: 0.17.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import ordqz
        >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]])
        >>> B = np.array([[0, 6, 0, 0], [5, 0, 2, 1], [5, 2, 6, 6], [4, 7, 7, 7]])
        >>> AA, BB, alpha, beta, Q, Z = ordqz(A, B, sort='lhp')

        Since we have sorted for left half plane eigenvalues, negatives come first

        >>> (alpha/beta).real < 0
        array([ True,  True, False, False], dtype=bool)

    orth(A, rcond=None)
        Construct an orthonormal basis for the range of A using SVD

        Parameters
        ----------
        A : (M, N) array_like
            Input array
        rcond : float, optional
            Relative condition number. Singular values ``s`` smaller than
            ``rcond * max(s)`` are considered zero.
            Default: floating point eps * max(M,N).

        Returns
        -------
        Q : (M, K) ndarray
            Orthonormal basis for the range of A.
            K = effective rank of A, as determined by rcond

        See Also
        --------
        svd : Singular value decomposition of a matrix
        null_space : Matrix null space

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import orth
        >>> A = np.array([[2, 0, 0], [0, 5, 0]])  # rank 2 array
        >>> orth(A)
        array([[0., 1.],
               [1., 0.]])
        >>> orth(A.T)
        array([[0., 1.],
               [1., 0.],
               [0., 0.]])

    orthogonal_procrustes(A, B, check_finite=True)
        Compute the matrix solution of the orthogonal Procrustes problem.

        Given matrices A and B of equal shape, find an orthogonal matrix R
        that most closely maps A to B using the algorithm given in [1]_.

        Parameters
        ----------
        A : (M, N) array_like
            Matrix to be mapped.
        B : (M, N) array_like
            Target matrix.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        R : (N, N) ndarray
            The matrix solution of the orthogonal Procrustes problem.
            Minimizes the Frobenius norm of ``(A @ R) - B``, subject to
            ``R.T @ R = I``.
        scale : float
            Sum of the singular values of ``A.T @ B``.

        Raises
        ------
        ValueError
            If the input array shapes don't match or if check_finite is True and
            the arrays contain Inf or NaN.

        Notes
        -----
        Note that unlike higher level Procrustes analyses of spatial data, this
        function only uses orthogonal transformations like rotations and
        reflections, and it does not use scaling or translation.

        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Peter H. Schonemann, "A generalized solution of the orthogonal
               Procrustes problem", Psychometrica -- Vol. 31, No. 1, March, 1966.
               :doi:`10.1007/BF02289451`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import orthogonal_procrustes
        >>> A = np.array([[ 2,  0,  1], [-2,  0,  0]])

        Flip the order of columns and check for the anti-diagonal mapping

        >>> R, sca = orthogonal_procrustes(A, np.fliplr(A))
        >>> R
        array([[-5.34384992e-17,  0.00000000e+00,  1.00000000e+00],
               [ 0.00000000e+00,  1.00000000e+00,  0.00000000e+00],
               [ 1.00000000e+00,  0.00000000e+00, -7.85941422e-17]])
        >>> sca
        9.0

    pascal(n, kind='symmetric', exact=True)
        Returns the n x n Pascal matrix.

        The Pascal matrix is a matrix containing the binomial coefficients as
        its elements.

        Parameters
        ----------
        n : int
            The size of the matrix to create; that is, the result is an n x n
            matrix.
        kind : str, optional
            Must be one of 'symmetric', 'lower', or 'upper'.
            Default is 'symmetric'.
        exact : bool, optional
            If `exact` is True, the result is either an array of type
            numpy.uint64 (if n < 35) or an object array of Python long integers.
            If `exact` is False, the coefficients in the matrix are computed using
            `scipy.special.comb` with `exact=False`. The result will be a floating
            point array, and the values in the array will not be the exact
            coefficients, but this version is much faster than `exact=True`.

        Returns
        -------
        p : (n, n) ndarray
            The Pascal matrix.

        See Also
        --------
        invpascal

        Notes
        -----
        See https://en.wikipedia.org/wiki/Pascal_matrix for more information
        about Pascal matrices.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> from scipy.linalg import pascal
        >>> pascal(4)
        array([[ 1,  1,  1,  1],
               [ 1,  2,  3,  4],
               [ 1,  3,  6, 10],
               [ 1,  4, 10, 20]], dtype=uint64)
        >>> pascal(4, kind='lower')
        array([[1, 0, 0, 0],
               [1, 1, 0, 0],
               [1, 2, 1, 0],
               [1, 3, 3, 1]], dtype=uint64)
        >>> pascal(50)[-1, -1]
        25477612258980856902730428600
        >>> from scipy.special import comb
        >>> comb(98, 49, exact=True)
        25477612258980856902730428600

    pinv(a, *, atol=None, rtol=None, return_rank=False, check_finite=True)
        Compute the (Moore-Penrose) pseudo-inverse of a matrix.

        Calculate a generalized inverse of a matrix using its
        singular-value decomposition ``U @ S @ V`` in the economy mode and picking
        up only the columns/rows that are associated with significant singular
        values.

        If ``s`` is the maximum singular value of ``a``, then the
        significance cut-off value is determined by ``atol + rtol * s``. Any
        singular value below this value is assumed insignificant.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to be pseudo-inverted.
        atol : float, optional
            Absolute threshold term, default value is 0.

            .. versionadded:: 1.7.0

        rtol : float, optional
            Relative threshold term, default value is ``max(M, N) * eps`` where
            ``eps`` is the machine precision value of the datatype of ``a``.

            .. versionadded:: 1.7.0

        return_rank : bool, optional
            If True, return the effective rank of the matrix.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        B : (N, M) ndarray
            The pseudo-inverse of matrix `a`.
        rank : int
            The effective rank of the matrix. Returned if `return_rank` is True.

        Raises
        ------
        LinAlgError
            If SVD computation does not converge.

        See Also
        --------
        pinvh : Moore-Penrose pseudoinverse of a hermitian matrix.

        Notes
        -----
        If ``A`` is invertible then the Moore-Penrose pseudoinverse is exactly
        the inverse of ``A`` [1]_. If ``A`` is not invertible then the
        Moore-Penrose pseudoinverse computes the ``x`` solution to ``Ax = b`` such
        that ``||Ax - b||`` is minimized [1]_.

        References
        ----------
        .. [1] Penrose, R. (1956). On best approximate solutions of linear matrix
               equations. Mathematical Proceedings of the Cambridge Philosophical
               Society, 52(1), 17-19. doi:10.1017/S0305004100030929

        Examples
        --------

        Given an ``m x n`` matrix ``A`` and an ``n x m`` matrix ``B`` the four
        Moore-Penrose conditions are:

        1. ``ABA = A`` (``B`` is a generalized inverse of ``A``),
        2. ``BAB = B`` (``A`` is a generalized inverse of ``B``),
        3. ``(AB)* = AB`` (``AB`` is hermitian),
        4. ``(BA)* = BA`` (``BA`` is hermitian) [1]_.

        Here, ``A*`` denotes the conjugate transpose. The Moore-Penrose
        pseudoinverse is a unique ``B`` that satisfies all four of these
        conditions and exists for any ``A``. Note that, unlike the standard
        matrix inverse, ``A`` does not have to be a square matrix or have
        linearly independent columns/rows.

        As an example, we can calculate the Moore-Penrose pseudoinverse of a
        random non-square matrix and verify it satisfies the four conditions.

        >>> import numpy as np
        >>> from scipy import linalg
        >>> rng = np.random.default_rng()
        >>> A = rng.standard_normal((9, 6))
        >>> B = linalg.pinv(A)
        >>> np.allclose(A @ B @ A, A)  # Condition 1
        True
        >>> np.allclose(B @ A @ B, B)  # Condition 2
        True
        >>> np.allclose((A @ B).conj().T, A @ B)  # Condition 3
        True
        >>> np.allclose((B @ A).conj().T, B @ A)  # Condition 4
        True

    pinvh(a, atol=None, rtol=None, lower=True, return_rank=False, check_finite=True)
        Compute the (Moore-Penrose) pseudo-inverse of a Hermitian matrix.

        Calculate a generalized inverse of a complex Hermitian/real symmetric
        matrix using its eigenvalue decomposition and including all eigenvalues
        with 'large' absolute value.

        Parameters
        ----------
        a : (N, N) array_like
            Real symmetric or complex hermetian matrix to be pseudo-inverted

        atol : float, optional
            Absolute threshold term, default value is 0.

            .. versionadded:: 1.7.0

        rtol : float, optional
            Relative threshold term, default value is ``N * eps`` where
            ``eps`` is the machine precision value of the datatype of ``a``.

            .. versionadded:: 1.7.0

        lower : bool, optional
            Whether the pertinent array data is taken from the lower or upper
            triangle of `a`. (Default: lower)
        return_rank : bool, optional
            If True, return the effective rank of the matrix.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        B : (N, N) ndarray
            The pseudo-inverse of matrix `a`.
        rank : int
            The effective rank of the matrix.  Returned if `return_rank` is True.

        Raises
        ------
        LinAlgError
            If eigenvalue algorithm does not converge.

        See Also
        --------
        pinv : Moore-Penrose pseudoinverse of a matrix.

        Examples
        --------

        For a more detailed example see `pinv`.

        >>> import numpy as np
        >>> from scipy.linalg import pinvh
        >>> rng = np.random.default_rng()
        >>> a = rng.standard_normal((9, 6))
        >>> a = np.dot(a, a.T)
        >>> B = pinvh(a)
        >>> np.allclose(a, a @ B @ a)
        True
        >>> np.allclose(B, B @ a @ B)
        True

    polar(a, side='right')
        Compute the polar decomposition.

        Returns the factors of the polar decomposition [1]_ `u` and `p` such
        that ``a = up`` (if `side` is "right") or ``a = pu`` (if `side` is
        "left"), where `p` is positive semidefinite. Depending on the shape
        of `a`, either the rows or columns of `u` are orthonormal. When `a`
        is a square array, `u` is a square unitary array. When `a` is not
        square, the "canonical polar decomposition" [2]_ is computed.

        Parameters
        ----------
        a : (m, n) array_like
            The array to be factored.
        side : {'left', 'right'}, optional
            Determines whether a right or left polar decomposition is computed.
            If `side` is "right", then ``a = up``.  If `side` is "left",  then
            ``a = pu``.  The default is "right".

        Returns
        -------
        u : (m, n) ndarray
            If `a` is square, then `u` is unitary. If m > n, then the columns
            of `a` are orthonormal, and if m < n, then the rows of `u` are
            orthonormal.
        p : ndarray
            `p` is Hermitian positive semidefinite. If `a` is nonsingular, `p`
            is positive definite. The shape of `p` is (n, n) or (m, m), depending
            on whether `side` is "right" or "left", respectively.

        References
        ----------
        .. [1] R. A. Horn and C. R. Johnson, "Matrix Analysis", Cambridge
               University Press, 1985.
        .. [2] N. J. Higham, "Functions of Matrices: Theory and Computation",
               SIAM, 2008.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import polar
        >>> a = np.array([[1, -1], [2, 4]])
        >>> u, p = polar(a)
        >>> u
        array([[ 0.85749293, -0.51449576],
               [ 0.51449576,  0.85749293]])
        >>> p
        array([[ 1.88648444,  1.2004901 ],
               [ 1.2004901 ,  3.94446746]])

        A non-square example, with m < n:

        >>> b = np.array([[0.5, 1, 2], [1.5, 3, 4]])
        >>> u, p = polar(b)
        >>> u
        array([[-0.21196618, -0.42393237,  0.88054056],
               [ 0.39378971,  0.78757942,  0.4739708 ]])
        >>> p
        array([[ 0.48470147,  0.96940295,  1.15122648],
               [ 0.96940295,  1.9388059 ,  2.30245295],
               [ 1.15122648,  2.30245295,  3.65696431]])
        >>> u.dot(p)   # Verify the decomposition.
        array([[ 0.5,  1. ,  2. ],
               [ 1.5,  3. ,  4. ]])
        >>> u.dot(u.T)   # The rows of u are orthonormal.
        array([[  1.00000000e+00,  -2.07353665e-17],
               [ -2.07353665e-17,   1.00000000e+00]])

        Another non-square example, with m > n:

        >>> c = b.T
        >>> u, p = polar(c)
        >>> u
        array([[-0.21196618,  0.39378971],
               [-0.42393237,  0.78757942],
               [ 0.88054056,  0.4739708 ]])
        >>> p
        array([[ 1.23116567,  1.93241587],
               [ 1.93241587,  4.84930602]])
        >>> u.dot(p)   # Verify the decomposition.
        array([[ 0.5,  1.5],
               [ 1. ,  3. ],
               [ 2. ,  4. ]])
        >>> u.T.dot(u)  # The columns of u are orthonormal.
        array([[  1.00000000e+00,  -1.26363763e-16],
               [ -1.26363763e-16,   1.00000000e+00]])

    qr(a, overwrite_a=False, lwork=None, mode='full', pivoting=False, check_finite=True)
        Compute QR decomposition of a matrix.

        Calculate the decomposition ``A = Q R`` where Q is unitary/orthogonal
        and R upper triangular.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to be decomposed
        overwrite_a : bool, optional
            Whether data in `a` is overwritten (may improve performance if
            `overwrite_a` is set to True by reusing the existing input data
            structure rather than creating a new one.)
        lwork : int, optional
            Work array size, lwork >= a.shape[1]. If None or -1, an optimal size
            is computed.
        mode : {'full', 'r', 'economic', 'raw'}, optional
            Determines what information is to be returned: either both Q and R
            ('full', default), only R ('r') or both Q and R but computed in
            economy-size ('economic', see Notes). The final option 'raw'
            (added in SciPy 0.11) makes the function return two matrices
            (Q, TAU) in the internal format used by LAPACK.
        pivoting : bool, optional
            Whether or not factorization should include pivoting for rank-revealing
            qr decomposition. If pivoting, compute the decomposition
            ``A[:, P] = Q @ R`` as above, but where P is chosen such that the
            diagonal of R is non-increasing.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        Q : float or complex ndarray
            Of shape (M, M), or (M, K) for ``mode='economic'``. Not returned
            if ``mode='r'``. Replaced by tuple ``(Q, TAU)`` if ``mode='raw'``.
        R : float or complex ndarray
            Of shape (M, N), or (K, N) for ``mode in ['economic', 'raw']``.
            ``K = min(M, N)``.
        P : int ndarray
            Of shape (N,) for ``pivoting=True``. Not returned if
            ``pivoting=False``.

        Raises
        ------
        LinAlgError
            Raised if decomposition fails

        Notes
        -----
        This is an interface to the LAPACK routines dgeqrf, zgeqrf,
        dorgqr, zungqr, dgeqp3, and zgeqp3.

        If ``mode=economic``, the shapes of Q and R are (M, K) and (K, N) instead
        of (M,M) and (M,N), with ``K=min(M,N)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> rng = np.random.default_rng()
        >>> a = rng.standard_normal((9, 6))

        >>> q, r = linalg.qr(a)
        >>> np.allclose(a, np.dot(q, r))
        True
        >>> q.shape, r.shape
        ((9, 9), (9, 6))

        >>> r2 = linalg.qr(a, mode='r')
        >>> np.allclose(r, r2)
        True

        >>> q3, r3 = linalg.qr(a, mode='economic')
        >>> q3.shape, r3.shape
        ((9, 6), (6, 6))

        >>> q4, r4, p4 = linalg.qr(a, pivoting=True)
        >>> d = np.abs(np.diag(r4))
        >>> np.all(d[1:] <= d[:-1])
        True
        >>> np.allclose(a[:, p4], np.dot(q4, r4))
        True
        >>> q4.shape, r4.shape, p4.shape
        ((9, 9), (9, 6), (6,))

        >>> q5, r5, p5 = linalg.qr(a, mode='economic', pivoting=True)
        >>> q5.shape, r5.shape, p5.shape
        ((9, 6), (6, 6), (6,))

    qr_delete(Q, R, k, p=1, which='row', overwrite_qr=False, check_finite=True)
        qr_delete(Q, R, k, int p=1, which=u'row', overwrite_qr=False, check_finite=True)


        QR downdate on row or column deletions



        If ``A = Q R`` is the QR factorization of ``A``, return the QR

        factorization of ``A`` where ``p`` rows or columns have been removed

        starting at row or column ``k``.



        Parameters

        ----------

        Q : (M, M) or (M, N) array_like

            Unitary/orthogonal matrix from QR decomposition.

        R : (M, N) or (N, N) array_like

            Upper triangular matrix from QR decomposition.

        k : int

            Index of the first row or column to delete.

        p : int, optional

            Number of rows or columns to delete, defaults to 1.

        which: {'row', 'col'}, optional

            Determines if rows or columns will be deleted, defaults to 'row'

        overwrite_qr : bool, optional

            If True, consume Q and R, overwriting their contents with their

            downdated versions, and returning appropriately sized views.

            Defaults to False.

        check_finite : bool, optional

            Whether to check that the input matrix contains only finite numbers.

            Disabling may give a performance gain, but may result in problems

            (crashes, non-termination) if the inputs do contain infinities or NaNs.

            Default is True.



        Returns

        -------

        Q1 : ndarray

            Updated unitary/orthogonal factor

        R1 : ndarray

            Updated upper triangular factor



        See Also

        --------

        qr, qr_multiply, qr_insert, qr_update



        Notes

        -----

        This routine does not guarantee that the diagonal entries of ``R1`` are

        positive.



        .. versionadded:: 0.16.0



        References

        ----------

        .. [1] Golub, G. H. & Van Loan, C. F. Matrix Computations, 3rd Ed.

               (Johns Hopkins University Press, 1996).



        .. [2] Daniel, J. W., Gragg, W. B., Kaufman, L. & Stewart, G. W.

               Reorthogonalization and stable algorithms for updating the

               Gram-Schmidt QR factorization. Math. Comput. 30, 772-795 (1976).



        .. [3] Reichel, L. & Gragg, W. B. Algorithm 686: FORTRAN Subroutines for

               Updating the QR Decomposition. ACM Trans. Math. Softw. 16, 369-377

               (1990).



        Examples

        --------

        >>> import numpy as np

        >>> from scipy import linalg

        >>> a = np.array([[  3.,  -2.,  -2.],

        ...               [  6.,  -9.,  -3.],

        ...               [ -3.,  10.,   1.],

        ...               [  6.,  -7.,   4.],

        ...               [  7.,   8.,  -6.]])

        >>> q, r = linalg.qr(a)



        Given this QR decomposition, update q and r when 2 rows are removed.



        >>> q1, r1 = linalg.qr_delete(q, r, 2, 2, 'row', False)

        >>> q1

        array([[ 0.30942637,  0.15347579,  0.93845645],  # may vary (signs)

               [ 0.61885275,  0.71680171, -0.32127338],

               [ 0.72199487, -0.68017681, -0.12681844]])

        >>> r1

        array([[  9.69535971,  -0.4125685 ,  -6.80738023],  # may vary (signs)

               [  0.        , -12.19958144,   1.62370412],

               [  0.        ,   0.        ,  -0.15218213]])



        The update is equivalent, but faster than the following.



        >>> a1 = np.delete(a, slice(2,4), 0)

        >>> a1

        array([[ 3., -2., -2.],

               [ 6., -9., -3.],

               [ 7.,  8., -6.]])

        >>> q_direct, r_direct = linalg.qr(a1)



        Check that we have equivalent results:



        >>> np.dot(q1, r1)

        array([[ 3., -2., -2.],

               [ 6., -9., -3.],

               [ 7.,  8., -6.]])

        >>> np.allclose(np.dot(q1, r1), a1)

        True



        And the updated Q is still unitary:



        >>> np.allclose(np.dot(q1.T, q1), np.eye(3))

        True

    qr_insert(Q, R, u, k, which='row', rcond=None, overwrite_qru=False, check_finite=True)
        qr_insert(Q, R, u, k, which=u'row', rcond=None, overwrite_qru=False, check_finite=True)


        QR update on row or column insertions



        If ``A = Q R`` is the QR factorization of ``A``, return the QR

        factorization of ``A`` where rows or columns have been inserted starting

        at row or column ``k``.



        Parameters

        ----------

        Q : (M, M) array_like

            Unitary/orthogonal matrix from the QR decomposition of A.

        R : (M, N) array_like

            Upper triangular matrix from the QR decomposition of A.

        u : (N,), (p, N), (M,), or (M, p) array_like

            Rows or columns to insert

        k : int

            Index before which `u` is to be inserted.

        which: {'row', 'col'}, optional

            Determines if rows or columns will be inserted, defaults to 'row'

        rcond : float

            Lower bound on the reciprocal condition number of ``Q`` augmented with

            ``u/||u||`` Only used when updating economic mode (thin, (M,N) (N,N))

            decompositions.  If None, machine precision is used.  Defaults to

            None.

        overwrite_qru : bool, optional

            If True, consume Q, R, and u, if possible, while performing the update,

            otherwise make copies as necessary. Defaults to False.

        check_finite : bool, optional

            Whether to check that the input matrices contain only finite numbers.

            Disabling may give a performance gain, but may result in problems

            (crashes, non-termination) if the inputs do contain infinities or NaNs.

            Default is True.



        Returns

        -------

        Q1 : ndarray

            Updated unitary/orthogonal factor

        R1 : ndarray

            Updated upper triangular factor



        Raises

        ------

        LinAlgError :

            If updating a (M,N) (N,N) factorization and the reciprocal condition

            number of Q augmented with ``u/||u||`` is smaller than rcond.



        See Also

        --------

        qr, qr_multiply, qr_delete, qr_update



        Notes

        -----

        This routine does not guarantee that the diagonal entries of ``R1`` are

        positive.



        .. versionadded:: 0.16.0



        References

        ----------



        .. [1] Golub, G. H. & Van Loan, C. F. Matrix Computations, 3rd Ed.

               (Johns Hopkins University Press, 1996).



        .. [2] Daniel, J. W., Gragg, W. B., Kaufman, L. & Stewart, G. W.

               Reorthogonalization and stable algorithms for updating the

               Gram-Schmidt QR factorization. Math. Comput. 30, 772-795 (1976).



        .. [3] Reichel, L. & Gragg, W. B. Algorithm 686: FORTRAN Subroutines for

               Updating the QR Decomposition. ACM Trans. Math. Softw. 16, 369-377

               (1990).



        Examples

        --------

        >>> import numpy as np

        >>> from scipy import linalg

        >>> a = np.array([[  3.,  -2.,  -2.],

        ...               [  6.,  -7.,   4.],

        ...               [  7.,   8.,  -6.]])

        >>> q, r = linalg.qr(a)



        Given this QR decomposition, update q and r when 2 rows are inserted.



        >>> u = np.array([[  6.,  -9.,  -3.],

        ...               [ -3.,  10.,   1.]])

        >>> q1, r1 = linalg.qr_insert(q, r, u, 2, 'row')

        >>> q1

        array([[-0.25445668,  0.02246245,  0.18146236, -0.72798806,  0.60979671],  # may vary (signs)

               [-0.50891336,  0.23226178, -0.82836478, -0.02837033, -0.00828114],

               [-0.50891336,  0.35715302,  0.38937158,  0.58110733,  0.35235345],

               [ 0.25445668, -0.52202743, -0.32165498,  0.36263239,  0.65404509],

               [-0.59373225, -0.73856549,  0.16065817, -0.0063658 , -0.27595554]])

        >>> r1

        array([[-11.78982612,   6.44623587,   3.81685018],  # may vary (signs)

               [  0.        , -16.01393278,   3.72202865],

               [  0.        ,   0.        ,  -6.13010256],

               [  0.        ,   0.        ,   0.        ],

               [  0.        ,   0.        ,   0.        ]])



        The update is equivalent, but faster than the following.



        >>> a1 = np.insert(a, 2, u, 0)

        >>> a1

        array([[  3.,  -2.,  -2.],

               [  6.,  -7.,   4.],

               [  6.,  -9.,  -3.],

               [ -3.,  10.,   1.],

               [  7.,   8.,  -6.]])

        >>> q_direct, r_direct = linalg.qr(a1)



        Check that we have equivalent results:



        >>> np.dot(q1, r1)

        array([[  3.,  -2.,  -2.],

               [  6.,  -7.,   4.],

               [  6.,  -9.,  -3.],

               [ -3.,  10.,   1.],

               [  7.,   8.,  -6.]])



        >>> np.allclose(np.dot(q1, r1), a1)

        True



        And the updated Q is still unitary:



        >>> np.allclose(np.dot(q1.T, q1), np.eye(5))

        True

    qr_multiply(a, c, mode='right', pivoting=False, conjugate=False, overwrite_a=False, overwrite_c=False)
        Calculate the QR decomposition and multiply Q with a matrix.

        Calculate the decomposition ``A = Q R`` where Q is unitary/orthogonal
        and R upper triangular. Multiply Q with a vector or a matrix c.

        Parameters
        ----------
        a : (M, N), array_like
            Input array
        c : array_like
            Input array to be multiplied by ``q``.
        mode : {'left', 'right'}, optional
            ``Q @ c`` is returned if mode is 'left', ``c @ Q`` is returned if
            mode is 'right'.
            The shape of c must be appropriate for the matrix multiplications,
            if mode is 'left', ``min(a.shape) == c.shape[0]``,
            if mode is 'right', ``a.shape[0] == c.shape[1]``.
        pivoting : bool, optional
            Whether or not factorization should include pivoting for rank-revealing
            qr decomposition, see the documentation of qr.
        conjugate : bool, optional
            Whether Q should be complex-conjugated. This might be faster
            than explicit conjugation.
        overwrite_a : bool, optional
            Whether data in a is overwritten (may improve performance)
        overwrite_c : bool, optional
            Whether data in c is overwritten (may improve performance).
            If this is used, c must be big enough to keep the result,
            i.e. ``c.shape[0]`` = ``a.shape[0]`` if mode is 'left'.

        Returns
        -------
        CQ : ndarray
            The product of ``Q`` and ``c``.
        R : (K, N), ndarray
            R array of the resulting QR factorization where ``K = min(M, N)``.
        P : (N,) ndarray
            Integer pivot array. Only returned when ``pivoting=True``.

        Raises
        ------
        LinAlgError
            Raised if QR decomposition fails.

        Notes
        -----
        This is an interface to the LAPACK routines ``?GEQRF``, ``?ORMQR``,
        ``?UNMQR``, and ``?GEQP3``.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import qr_multiply, qr
        >>> A = np.array([[1, 3, 3], [2, 3, 2], [2, 3, 3], [1, 3, 2]])
        >>> qc, r1, piv1 = qr_multiply(A, 2*np.eye(4), pivoting=1)
        >>> qc
        array([[-1.,  1., -1.],
               [-1., -1.,  1.],
               [-1., -1., -1.],
               [-1.,  1.,  1.]])
        >>> r1
        array([[-6., -3., -5.            ],
               [ 0., -1., -1.11022302e-16],
               [ 0.,  0., -1.            ]])
        >>> piv1
        array([1, 0, 2], dtype=int32)
        >>> q2, r2, piv2 = qr(A, mode='economic', pivoting=1)
        >>> np.allclose(2*q2 - qc, np.zeros((4, 3)))
        True

    qr_update(Q, R, u, v, overwrite_qruv=False, check_finite=True)
        qr_update(Q, R, u, v, overwrite_qruv=False, check_finite=True)


        Rank-k QR update



        If ``A = Q R`` is the QR factorization of ``A``, return the QR

        factorization of ``A + u v**T`` for real ``A`` or ``A + u v**H``

        for complex ``A``.



        Parameters

        ----------

        Q : (M, M) or (M, N) array_like

            Unitary/orthogonal matrix from the qr decomposition of A.

        R : (M, N) or (N, N) array_like

            Upper triangular matrix from the qr decomposition of A.

        u : (M,) or (M, k) array_like

            Left update vector

        v : (N,) or (N, k) array_like

            Right update vector

        overwrite_qruv : bool, optional

            If True, consume Q, R, u, and v, if possible, while performing the

            update, otherwise make copies as necessary. Defaults to False.

        check_finite : bool, optional

            Whether to check that the input matrix contains only finite numbers.

            Disabling may give a performance gain, but may result in problems

            (crashes, non-termination) if the inputs do contain infinities or NaNs.

            Default is True.



        Returns

        -------

        Q1 : ndarray

            Updated unitary/orthogonal factor

        R1 : ndarray

            Updated upper triangular factor



        See Also

        --------

        qr, qr_multiply, qr_delete, qr_insert



        Notes

        -----

        This routine does not guarantee that the diagonal entries of `R1` are

        real or positive.



        .. versionadded:: 0.16.0



        References

        ----------

        .. [1] Golub, G. H. & Van Loan, C. F. Matrix Computations, 3rd Ed.

               (Johns Hopkins University Press, 1996).



        .. [2] Daniel, J. W., Gragg, W. B., Kaufman, L. & Stewart, G. W.

               Reorthogonalization and stable algorithms for updating the

               Gram-Schmidt QR factorization. Math. Comput. 30, 772-795 (1976).



        .. [3] Reichel, L. & Gragg, W. B. Algorithm 686: FORTRAN Subroutines for

               Updating the QR Decomposition. ACM Trans. Math. Softw. 16, 369-377

               (1990).



        Examples

        --------

        >>> import numpy as np

        >>> from scipy import linalg

        >>> a = np.array([[  3.,  -2.,  -2.],

        ...               [  6.,  -9.,  -3.],

        ...               [ -3.,  10.,   1.],

        ...               [  6.,  -7.,   4.],

        ...               [  7.,   8.,  -6.]])

        >>> q, r = linalg.qr(a)



        Given this q, r decomposition, perform a rank 1 update.



        >>> u = np.array([7., -2., 4., 3., 5.])

        >>> v = np.array([1., 3., -5.])

        >>> q_up, r_up = linalg.qr_update(q, r, u, v, False)

        >>> q_up

        array([[ 0.54073807,  0.18645997,  0.81707661, -0.02136616,  0.06902409],  # may vary (signs)

               [ 0.21629523, -0.63257324,  0.06567893,  0.34125904, -0.65749222],

               [ 0.05407381,  0.64757787, -0.12781284, -0.20031219, -0.72198188],

               [ 0.48666426, -0.30466718, -0.27487277, -0.77079214,  0.0256951 ],

               [ 0.64888568,  0.23001   , -0.4859845 ,  0.49883891,  0.20253783]])

        >>> r_up

        array([[ 18.49324201,  24.11691794, -44.98940746],  # may vary (signs)

               [  0.        ,  31.95894662, -27.40998201],

               [  0.        ,   0.        ,  -9.25451794],

               [  0.        ,   0.        ,   0.        ],

               [  0.        ,   0.        ,   0.        ]])



        The update is equivalent, but faster than the following.



        >>> a_up = a + np.outer(u, v)

        >>> q_direct, r_direct = linalg.qr(a_up)



        Check that we have equivalent results:



        >>> np.allclose(np.dot(q_up, r_up), a_up)

        True



        And the updated Q is still unitary:



        >>> np.allclose(np.dot(q_up.T, q_up), np.eye(5))

        True



        Updating economic (reduced, thin) decompositions is also possible:



        >>> qe, re = linalg.qr(a, mode='economic')

        >>> qe_up, re_up = linalg.qr_update(qe, re, u, v, False)

        >>> qe_up

        array([[ 0.54073807,  0.18645997,  0.81707661],  # may vary (signs)

               [ 0.21629523, -0.63257324,  0.06567893],

               [ 0.05407381,  0.64757787, -0.12781284],

               [ 0.48666426, -0.30466718, -0.27487277],

               [ 0.64888568,  0.23001   , -0.4859845 ]])

        >>> re_up

        array([[ 18.49324201,  24.11691794, -44.98940746],  # may vary (signs)

               [  0.        ,  31.95894662, -27.40998201],

               [  0.        ,   0.        ,  -9.25451794]])

        >>> np.allclose(np.dot(qe_up, re_up), a_up)

        True

        >>> np.allclose(np.dot(qe_up.T, qe_up), np.eye(3))

        True



        Similarly to the above, perform a rank 2 update.



        >>> u2 = np.array([[ 7., -1,],

        ...                [-2.,  4.],

        ...                [ 4.,  2.],

        ...                [ 3., -6.],

        ...                [ 5.,  3.]])

        >>> v2 = np.array([[ 1., 2.],

        ...                [ 3., 4.],

        ...                [-5., 2]])

        >>> q_up2, r_up2 = linalg.qr_update(q, r, u2, v2, False)

        >>> q_up2

        array([[-0.33626508, -0.03477253,  0.61956287, -0.64352987, -0.29618884],  # may vary (signs)

               [-0.50439762,  0.58319694, -0.43010077, -0.33395279,  0.33008064],

               [-0.21016568, -0.63123106,  0.0582249 , -0.13675572,  0.73163206],

               [ 0.12609941,  0.49694436,  0.64590024,  0.31191919,  0.47187344],

               [-0.75659643, -0.11517748,  0.10284903,  0.5986227 , -0.21299983]])

        >>> r_up2

        array([[-23.79075451, -41.1084062 ,  24.71548348],  # may vary (signs)

               [  0.        , -33.83931057,  11.02226551],

               [  0.        ,   0.        ,  48.91476811],

               [  0.        ,   0.        ,   0.        ],

               [  0.        ,   0.        ,   0.        ]])



        This update is also a valid qr decomposition of ``A + U V**T``.



        >>> a_up2 = a + np.dot(u2, v2.T)

        >>> np.allclose(a_up2, np.dot(q_up2, r_up2))

        True

        >>> np.allclose(np.dot(q_up2.T, q_up2), np.eye(5))

        True

    qz(A, B, output='real', lwork=None, sort=None, overwrite_a=False, overwrite_b=False, check_finite=True)
        QZ decomposition for generalized eigenvalues of a pair of matrices.

        The QZ, or generalized Schur, decomposition for a pair of n-by-n
        matrices (A,B) is::

            (A,B) = (Q @ AA @ Z*, Q @ BB @ Z*)

        where AA, BB is in generalized Schur form if BB is upper-triangular
        with non-negative diagonal and AA is upper-triangular, or for real QZ
        decomposition (``output='real'``) block upper triangular with 1x1
        and 2x2 blocks. In this case, the 1x1 blocks correspond to real
        generalized eigenvalues and 2x2 blocks are 'standardized' by making
        the corresponding elements of BB have the form::

            [ a 0 ]
            [ 0 b ]

        and the pair of corresponding 2x2 blocks in AA and BB will have a complex
        conjugate pair of generalized eigenvalues. If (``output='complex'``) or
        A and B are complex matrices, Z' denotes the conjugate-transpose of Z.
        Q and Z are unitary matrices.

        Parameters
        ----------
        A : (N, N) array_like
            2-D array to decompose
        B : (N, N) array_like
            2-D array to decompose
        output : {'real', 'complex'}, optional
            Construct the real or complex QZ decomposition for real matrices.
            Default is 'real'.
        lwork : int, optional
            Work array size. If None or -1, it is automatically computed.
        sort : {None, callable, 'lhp', 'rhp', 'iuc', 'ouc'}, optional
            NOTE: THIS INPUT IS DISABLED FOR NOW. Use ordqz instead.

            Specifies whether the upper eigenvalues should be sorted. A callable
            may be passed that, given a eigenvalue, returns a boolean denoting
            whether the eigenvalue should be sorted to the top-left (True). For
            real matrix pairs, the sort function takes three real arguments
            (alphar, alphai, beta). The eigenvalue
            ``x = (alphar + alphai*1j)/beta``. For complex matrix pairs or
            output='complex', the sort function takes two complex arguments
            (alpha, beta). The eigenvalue ``x = (alpha/beta)``.  Alternatively,
            string parameters may be used:

                - 'lhp'   Left-hand plane (x.real < 0.0)
                - 'rhp'   Right-hand plane (x.real > 0.0)
                - 'iuc'   Inside the unit circle (x*x.conjugate() < 1.0)
                - 'ouc'   Outside the unit circle (x*x.conjugate() > 1.0)

            Defaults to None (no sorting).
        overwrite_a : bool, optional
            Whether to overwrite data in a (may improve performance)
        overwrite_b : bool, optional
            Whether to overwrite data in b (may improve performance)
        check_finite : bool, optional
            If true checks the elements of `A` and `B` are finite numbers. If
            false does no checking and passes matrix through to
            underlying algorithm.

        Returns
        -------
        AA : (N, N) ndarray
            Generalized Schur form of A.
        BB : (N, N) ndarray
            Generalized Schur form of B.
        Q : (N, N) ndarray
            The left Schur vectors.
        Z : (N, N) ndarray
            The right Schur vectors.

        See Also
        --------
        ordqz

        Notes
        -----
        Q is transposed versus the equivalent function in Matlab.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import qz

        >>> A = np.array([[1, 2, -1], [5, 5, 5], [2, 4, -8]])
        >>> B = np.array([[1, 1, -3], [3, 1, -1], [5, 6, -2]])

        Compute the decomposition.  The QZ decomposition is not unique, so
        depending on the underlying library that is used, there may be
        differences in the signs of coefficients in the following output.

        >>> AA, BB, Q, Z = qz(A, B)
        >>> AA
        array([[-1.36949157, -4.05459025,  7.44389431],
               [ 0.        ,  7.65653432,  5.13476017],
               [ 0.        , -0.65978437,  2.4186015 ]])  # may vary
        >>> BB
        array([[ 1.71890633, -1.64723705, -0.72696385],
               [ 0.        ,  8.6965692 , -0.        ],
               [ 0.        ,  0.        ,  2.27446233]])  # may vary
        >>> Q
        array([[-0.37048362,  0.1903278 ,  0.90912992],
               [-0.90073232,  0.16534124, -0.40167593],
               [ 0.22676676,  0.96769706, -0.11017818]])  # may vary
        >>> Z
        array([[-0.67660785,  0.63528924, -0.37230283],
               [ 0.70243299,  0.70853819, -0.06753907],
               [ 0.22088393, -0.30721526, -0.92565062]])  # may vary

        Verify the QZ decomposition.  With real output, we only need the
        transpose of ``Z`` in the following expressions.

        >>> Q @ AA @ Z.T  # Should be A
        array([[ 1.,  2., -1.],
               [ 5.,  5.,  5.],
               [ 2.,  4., -8.]])
        >>> Q @ BB @ Z.T  # Should be B
        array([[ 1.,  1., -3.],
               [ 3.,  1., -1.],
               [ 5.,  6., -2.]])

        Repeat the decomposition, but with ``output='complex'``.

        >>> AA, BB, Q, Z = qz(A, B, output='complex')

        For conciseness in the output, we use ``np.set_printoptions()`` to set
        the output precision of NumPy arrays to 3 and display tiny values as 0.

        >>> np.set_printoptions(precision=3, suppress=True)
        >>> AA
        array([[-1.369+0.j   ,  2.248+4.237j,  4.861-5.022j],
               [ 0.   +0.j   ,  7.037+2.922j,  0.794+4.932j],
               [ 0.   +0.j   ,  0.   +0.j   ,  2.655-1.103j]])  # may vary
        >>> BB
        array([[ 1.719+0.j   , -1.115+1.j   , -0.763-0.646j],
               [ 0.   +0.j   ,  7.24 +0.j   , -3.144+3.322j],
               [ 0.   +0.j   ,  0.   +0.j   ,  2.732+0.j   ]])  # may vary
        >>> Q
        array([[ 0.326+0.175j, -0.273-0.029j, -0.886-0.052j],
               [ 0.794+0.426j, -0.093+0.134j,  0.402-0.02j ],
               [-0.2  -0.107j, -0.816+0.482j,  0.151-0.167j]])  # may vary
        >>> Z
        array([[ 0.596+0.32j , -0.31 +0.414j,  0.393-0.347j],
               [-0.619-0.332j, -0.479+0.314j,  0.154-0.393j],
               [-0.195-0.104j,  0.576+0.27j ,  0.715+0.187j]])  # may vary

        With complex arrays, we must use ``Z.conj().T`` in the following
        expressions to verify the decomposition.

        >>> Q @ AA @ Z.conj().T  # Should be A
        array([[ 1.-0.j,  2.-0.j, -1.-0.j],
               [ 5.+0.j,  5.+0.j,  5.-0.j],
               [ 2.+0.j,  4.+0.j, -8.+0.j]])
        >>> Q @ BB @ Z.conj().T  # Should be B
        array([[ 1.+0.j,  1.+0.j, -3.+0.j],
               [ 3.-0.j,  1.-0.j, -1.+0.j],
               [ 5.+0.j,  6.+0.j, -2.+0.j]])

    rq(a, overwrite_a=False, lwork=None, mode='full', check_finite=True)
        Compute RQ decomposition of a matrix.

        Calculate the decomposition ``A = R Q`` where Q is unitary/orthogonal
        and R upper triangular.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to be decomposed
        overwrite_a : bool, optional
            Whether data in a is overwritten (may improve performance)
        lwork : int, optional
            Work array size, lwork >= a.shape[1]. If None or -1, an optimal size
            is computed.
        mode : {'full', 'r', 'economic'}, optional
            Determines what information is to be returned: either both Q and R
            ('full', default), only R ('r') or both Q and R but computed in
            economy-size ('economic', see Notes).
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        R : float or complex ndarray
            Of shape (M, N) or (M, K) for ``mode='economic'``. ``K = min(M, N)``.
        Q : float or complex ndarray
            Of shape (N, N) or (K, N) for ``mode='economic'``. Not returned
            if ``mode='r'``.

        Raises
        ------
        LinAlgError
            If decomposition fails.

        Notes
        -----
        This is an interface to the LAPACK routines sgerqf, dgerqf, cgerqf, zgerqf,
        sorgrq, dorgrq, cungrq and zungrq.

        If ``mode=economic``, the shapes of Q and R are (K, N) and (M, K) instead
        of (N,N) and (M,N), with ``K=min(M,N)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> rng = np.random.default_rng()
        >>> a = rng.standard_normal((6, 9))
        >>> r, q = linalg.rq(a)
        >>> np.allclose(a, r @ q)
        True
        >>> r.shape, q.shape
        ((6, 9), (9, 9))
        >>> r2 = linalg.rq(a, mode='r')
        >>> np.allclose(r, r2)
        True
        >>> r3, q3 = linalg.rq(a, mode='economic')
        >>> r3.shape, q3.shape
        ((6, 6), (6, 9))

    rsf2csf(T, Z, check_finite=True)
        Convert real Schur form to complex Schur form.

        Convert a quasi-diagonal real-valued Schur form to the upper-triangular
        complex-valued Schur form.

        Parameters
        ----------
        T : (M, M) array_like
            Real Schur form of the original array
        Z : (M, M) array_like
            Schur transformation matrix
        check_finite : bool, optional
            Whether to check that the input arrays contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        T : (M, M) ndarray
            Complex Schur form of the original array
        Z : (M, M) ndarray
            Schur transformation matrix corresponding to the complex form

        See Also
        --------
        schur : Schur decomposition of an array

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import schur, rsf2csf
        >>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
        >>> T, Z = schur(A)
        >>> T
        array([[ 2.65896708,  1.42440458, -1.92933439],
               [ 0.        , -0.32948354, -0.49063704],
               [ 0.        ,  1.31178921, -0.32948354]])
        >>> Z
        array([[0.72711591, -0.60156188, 0.33079564],
               [0.52839428, 0.79801892, 0.28976765],
               [0.43829436, 0.03590414, -0.89811411]])
        >>> T2 , Z2 = rsf2csf(T, Z)
        >>> T2
        array([[2.65896708+0.j, -1.64592781+0.743164187j, -1.21516887+1.00660462j],
               [0.+0.j , -0.32948354+8.02254558e-01j, -0.82115218-2.77555756e-17j],
               [0.+0.j , 0.+0.j, -0.32948354-0.802254558j]])
        >>> Z2
        array([[0.72711591+0.j,  0.28220393-0.31385693j,  0.51319638-0.17258824j],
               [0.52839428+0.j,  0.24720268+0.41635578j, -0.68079517-0.15118243j],
               [0.43829436+0.j, -0.76618703+0.01873251j, -0.03063006+0.46857912j]])

    schur(a, output='real', lwork=None, overwrite_a=False, sort=None, check_finite=True)
        Compute Schur decomposition of a matrix.

        The Schur decomposition is::

            A = Z T Z^H

        where Z is unitary and T is either upper-triangular, or for real
        Schur decomposition (output='real'), quasi-upper triangular. In
        the quasi-triangular form, 2x2 blocks describing complex-valued
        eigenvalue pairs may extrude from the diagonal.

        Parameters
        ----------
        a : (M, M) array_like
            Matrix to decompose
        output : {'real', 'complex'}, optional
            Construct the real or complex Schur decomposition (for real matrices).
        lwork : int, optional
            Work array size. If None or -1, it is automatically computed.
        overwrite_a : bool, optional
            Whether to overwrite data in a (may improve performance).
        sort : {None, callable, 'lhp', 'rhp', 'iuc', 'ouc'}, optional
            Specifies whether the upper eigenvalues should be sorted. A callable
            may be passed that, given a eigenvalue, returns a boolean denoting
            whether the eigenvalue should be sorted to the top-left (True).
            Alternatively, string parameters may be used::

                'lhp'   Left-hand plane (x.real < 0.0)
                'rhp'   Right-hand plane (x.real > 0.0)
                'iuc'   Inside the unit circle (x*x.conjugate() <= 1.0)
                'ouc'   Outside the unit circle (x*x.conjugate() > 1.0)

            Defaults to None (no sorting).
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        T : (M, M) ndarray
            Schur form of A. It is real-valued for the real Schur decomposition.
        Z : (M, M) ndarray
            An unitary Schur transformation matrix for A.
            It is real-valued for the real Schur decomposition.
        sdim : int
            If and only if sorting was requested, a third return value will
            contain the number of eigenvalues satisfying the sort condition.

        Raises
        ------
        LinAlgError
            Error raised under three conditions:

            1. The algorithm failed due to a failure of the QR algorithm to
               compute all eigenvalues.
            2. If eigenvalue sorting was requested, the eigenvalues could not be
               reordered due to a failure to separate eigenvalues, usually because
               of poor conditioning.
            3. If eigenvalue sorting was requested, roundoff errors caused the
               leading eigenvalues to no longer satisfy the sorting condition.

        See Also
        --------
        rsf2csf : Convert real Schur form to complex Schur form

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import schur, eigvals
        >>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]])
        >>> T, Z = schur(A)
        >>> T
        array([[ 2.65896708,  1.42440458, -1.92933439],
               [ 0.        , -0.32948354, -0.49063704],
               [ 0.        ,  1.31178921, -0.32948354]])
        >>> Z
        array([[0.72711591, -0.60156188, 0.33079564],
               [0.52839428, 0.79801892, 0.28976765],
               [0.43829436, 0.03590414, -0.89811411]])

        >>> T2, Z2 = schur(A, output='complex')
        >>> T2
        array([[ 2.65896708, -1.22839825+1.32378589j,  0.42590089+1.51937378j], # may vary
               [ 0.        , -0.32948354+0.80225456j, -0.59877807+0.56192146j],
               [ 0.        ,  0.                    , -0.32948354-0.80225456j]])
        >>> eigvals(T2)
        array([2.65896708, -0.32948354+0.80225456j, -0.32948354-0.80225456j])

        An arbitrary custom eig-sorting condition, having positive imaginary part,
        which is satisfied by only one eigenvalue

        >>> T3, Z3, sdim = schur(A, output='complex', sort=lambda x: x.imag > 0)
        >>> sdim
        1

    signm(A, disp=True)
        Matrix sign function.

        Extension of the scalar sign(x) to matrices.

        Parameters
        ----------
        A : (N, N) array_like
            Matrix at which to evaluate the sign function
        disp : bool, optional
            Print warning if error in the result is estimated large
            instead of returning estimated error. (Default: True)

        Returns
        -------
        signm : (N, N) ndarray
            Value of the sign function at `A`
        errest : float
            (if disp == False)

            1-norm of the estimated error, ||err||_1 / ||A||_1

        Examples
        --------
        >>> from scipy.linalg import signm, eigvals
        >>> a = [[1,2,3], [1,2,1], [1,1,1]]
        >>> eigvals(a)
        array([ 4.12488542+0.j, -0.76155718+0.j,  0.63667176+0.j])
        >>> eigvals(signm(a))
        array([-1.+0.j,  1.+0.j,  1.+0.j])

    sinhm(A)
        Compute the hyperbolic matrix sine.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array.

        Returns
        -------
        sinhm : (N, N) ndarray
            Hyperbolic matrix sine of `A`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import tanhm, sinhm, coshm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> s = sinhm(a)
        >>> s
        array([[ 10.57300653,  39.28826594],
               [ 13.09608865,  49.86127247]])

        Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

        >>> t = tanhm(a)
        >>> c = coshm(a)
        >>> t - s.dot(np.linalg.inv(c))
        array([[  2.72004641e-15,   4.55191440e-15],
               [  0.00000000e+00,  -5.55111512e-16]])

    sinm(A)
        Compute the matrix sine.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array.

        Returns
        -------
        sinm : (N, N) ndarray
            Matrix sine of `A`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import expm, sinm, cosm

        Euler's identity (exp(i*theta) = cos(theta) + i*sin(theta))
        applied to a matrix:

        >>> a = np.array([[1.0, 2.0], [-1.0, 3.0]])
        >>> expm(1j*a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])
        >>> cosm(a) + 1j*sinm(a)
        array([[ 0.42645930+1.89217551j, -2.13721484-0.97811252j],
               [ 1.06860742+0.48905626j, -1.71075555+0.91406299j]])

    solve(a, b, lower=False, overwrite_a=False, overwrite_b=False, check_finite=True, assume_a='gen', transposed=False)
        Solves the linear equation set ``a @ x == b`` for the unknown ``x``
        for square `a` matrix.

        If the data matrix is known to be a particular type then supplying the
        corresponding string to ``assume_a`` key chooses the dedicated solver.
        The available options are

        ===================  ========
         generic matrix       'gen'
         symmetric            'sym'
         hermitian            'her'
         positive definite    'pos'
        ===================  ========

        If omitted, ``'gen'`` is the default structure.

        The datatype of the arrays define which solver is called regardless
        of the values. In other words, even when the complex array entries have
        precisely zero imaginary parts, the complex solver will be called based
        on the data type of the array.

        Parameters
        ----------
        a : (N, N) array_like
            Square input data
        b : (N, NRHS) array_like
            Input data for the right hand side.
        lower : bool, default: False
            Ignored if ``assume_a == 'gen'`` (the default). If True, the
            calculation uses only the data in the lower triangle of `a`;
            entries above the diagonal are ignored. If False (default), the
            calculation uses only the data in the upper triangle of `a`; entries
            below the diagonal are ignored.
        overwrite_a : bool, default: False
            Allow overwriting data in `a` (may enhance performance).
        overwrite_b : bool, default: False
            Allow overwriting data in `b` (may enhance performance).
        check_finite : bool, default: True
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        assume_a : str, {'gen', 'sym', 'her', 'pos'}
            Valid entries are explained above.
        transposed : bool, default: False
            If True, solve ``a.T @ x == b``. Raises `NotImplementedError`
            for complex `a`.

        Returns
        -------
        x : (N, NRHS) ndarray
            The solution array.

        Raises
        ------
        ValueError
            If size mismatches detected or input a is not square.
        LinAlgError
            If the matrix is singular.
        LinAlgWarning
            If an ill-conditioned input a is detected.
        NotImplementedError
            If transposed is True and input a is a complex matrix.

        Notes
        -----
        If the input b matrix is a 1-D array with N elements, when supplied
        together with an NxN input a, it is assumed as a valid column vector
        despite the apparent size mismatch. This is compatible with the
        numpy.dot() behavior and the returned result is still 1-D array.

        The generic, symmetric, Hermitian and positive definite solutions are
        obtained via calling ?GESV, ?SYSV, ?HESV, and ?POSV routines of
        LAPACK respectively.

        Examples
        --------
        Given `a` and `b`, solve for `x`:

        >>> import numpy as np
        >>> a = np.array([[3, 2, 0], [1, -1, 0], [0, 5, 1]])
        >>> b = np.array([2, 4, -1])
        >>> from scipy import linalg
        >>> x = linalg.solve(a, b)
        >>> x
        array([ 2., -2.,  9.])
        >>> np.dot(a, x) == b
        array([ True,  True,  True], dtype=bool)

    solve_banded(l_and_u, ab, b, overwrite_ab=False, overwrite_b=False, check_finite=True)
        Solve the equation a x = b for x, assuming a is banded matrix.

        The matrix a is stored in `ab` using the matrix diagonal ordered form::

            ab[u + i - j, j] == a[i,j]

        Example of `ab` (shape of a is (6,6), `u` =1, `l` =2)::

            *    a01  a12  a23  a34  a45
            a00  a11  a22  a33  a44  a55
            a10  a21  a32  a43  a54   *
            a20  a31  a42  a53   *    *

        Parameters
        ----------
        (l, u) : (integer, integer)
            Number of non-zero lower and upper diagonals
        ab : (`l` + `u` + 1, M) array_like
            Banded matrix
        b : (M,) or (M, K) array_like
            Right-hand side
        overwrite_ab : bool, optional
            Discard data in `ab` (may enhance performance)
        overwrite_b : bool, optional
            Discard data in `b` (may enhance performance)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : (M,) or (M, K) ndarray
            The solution to the system a x = b. Returned shape depends on the
            shape of `b`.

        Examples
        --------
        Solve the banded system a x = b, where::

                [5  2 -1  0  0]       [0]
                [1  4  2 -1  0]       [1]
            a = [0  1  3  2 -1]   b = [2]
                [0  0  1  2  2]       [2]
                [0  0  0  1  1]       [3]

        There is one nonzero diagonal below the main diagonal (l = 1), and
        two above (u = 2). The diagonal banded form of the matrix is::

                 [*  * -1 -1 -1]
            ab = [*  2  2  2  2]
                 [5  4  3  2  1]
                 [1  1  1  1  *]

        >>> import numpy as np
        >>> from scipy.linalg import solve_banded
        >>> ab = np.array([[0,  0, -1, -1, -1],
        ...                [0,  2,  2,  2,  2],
        ...                [5,  4,  3,  2,  1],
        ...                [1,  1,  1,  1,  0]])
        >>> b = np.array([0, 1, 2, 2, 3])
        >>> x = solve_banded((1, 2), ab, b)
        >>> x
        array([-2.37288136,  3.93220339, -4.        ,  4.3559322 , -1.3559322 ])

    solve_circulant(c, b, singular='raise', tol=None, caxis=-1, baxis=0, outaxis=0)
        Solve C x = b for x, where C is a circulant matrix.

        `C` is the circulant matrix associated with the vector `c`.

        The system is solved by doing division in Fourier space. The
        calculation is::

            x = ifft(fft(b) / fft(c))

        where `fft` and `ifft` are the fast Fourier transform and its inverse,
        respectively. For a large vector `c`, this is *much* faster than
        solving the system with the full circulant matrix.

        Parameters
        ----------
        c : array_like
            The coefficients of the circulant matrix.
        b : array_like
            Right-hand side matrix in ``a x = b``.
        singular : str, optional
            This argument controls how a near singular circulant matrix is
            handled.  If `singular` is "raise" and the circulant matrix is
            near singular, a `LinAlgError` is raised. If `singular` is
            "lstsq", the least squares solution is returned. Default is "raise".
        tol : float, optional
            If any eigenvalue of the circulant matrix has an absolute value
            that is less than or equal to `tol`, the matrix is considered to be
            near singular. If not given, `tol` is set to::

                tol = abs_eigs.max() * abs_eigs.size * np.finfo(np.float64).eps

            where `abs_eigs` is the array of absolute values of the eigenvalues
            of the circulant matrix.
        caxis : int
            When `c` has dimension greater than 1, it is viewed as a collection
            of circulant vectors. In this case, `caxis` is the axis of `c` that
            holds the vectors of circulant coefficients.
        baxis : int
            When `b` has dimension greater than 1, it is viewed as a collection
            of vectors. In this case, `baxis` is the axis of `b` that holds the
            right-hand side vectors.
        outaxis : int
            When `c` or `b` are multidimensional, the value returned by
            `solve_circulant` is multidimensional. In this case, `outaxis` is
            the axis of the result that holds the solution vectors.

        Returns
        -------
        x : ndarray
            Solution to the system ``C x = b``.

        Raises
        ------
        LinAlgError
            If the circulant matrix associated with `c` is near singular.

        See Also
        --------
        circulant : circulant matrix

        Notes
        -----
        For a 1-D vector `c` with length `m`, and an array `b`
        with shape ``(m, ...)``,

            solve_circulant(c, b)

        returns the same result as

            solve(circulant(c), b)

        where `solve` and `circulant` are from `scipy.linalg`.

        .. versionadded:: 0.16.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import solve_circulant, solve, circulant, lstsq

        >>> c = np.array([2, 2, 4])
        >>> b = np.array([1, 2, 3])
        >>> solve_circulant(c, b)
        array([ 0.75, -0.25,  0.25])

        Compare that result to solving the system with `scipy.linalg.solve`:

        >>> solve(circulant(c), b)
        array([ 0.75, -0.25,  0.25])

        A singular example:

        >>> c = np.array([1, 1, 0, 0])
        >>> b = np.array([1, 2, 3, 4])

        Calling ``solve_circulant(c, b)`` will raise a `LinAlgError`.  For the
        least square solution, use the option ``singular='lstsq'``:

        >>> solve_circulant(c, b, singular='lstsq')
        array([ 0.25,  1.25,  2.25,  1.25])

        Compare to `scipy.linalg.lstsq`:

        >>> x, resid, rnk, s = lstsq(circulant(c), b)
        >>> x
        array([ 0.25,  1.25,  2.25,  1.25])

        A broadcasting example:

        Suppose we have the vectors of two circulant matrices stored in an array
        with shape (2, 5), and three `b` vectors stored in an array with shape
        (3, 5).  For example,

        >>> c = np.array([[1.5, 2, 3, 0, 0], [1, 1, 4, 3, 2]])
        >>> b = np.arange(15).reshape(-1, 5)

        We want to solve all combinations of circulant matrices and `b` vectors,
        with the result stored in an array with shape (2, 3, 5). When we
        disregard the axes of `c` and `b` that hold the vectors of coefficients,
        the shapes of the collections are (2,) and (3,), respectively, which are
        not compatible for broadcasting. To have a broadcast result with shape
        (2, 3), we add a trivial dimension to `c`: ``c[:, np.newaxis, :]`` has
        shape (2, 1, 5). The last dimension holds the coefficients of the
        circulant matrices, so when we call `solve_circulant`, we can use the
        default ``caxis=-1``. The coefficients of the `b` vectors are in the last
        dimension of the array `b`, so we use ``baxis=-1``. If we use the
        default `outaxis`, the result will have shape (5, 2, 3), so we'll use
        ``outaxis=-1`` to put the solution vectors in the last dimension.

        >>> x = solve_circulant(c[:, np.newaxis, :], b, baxis=-1, outaxis=-1)
        >>> x.shape
        (2, 3, 5)
        >>> np.set_printoptions(precision=3)  # For compact output of numbers.
        >>> x
        array([[[-0.118,  0.22 ,  1.277, -0.142,  0.302],
                [ 0.651,  0.989,  2.046,  0.627,  1.072],
                [ 1.42 ,  1.758,  2.816,  1.396,  1.841]],
               [[ 0.401,  0.304,  0.694, -0.867,  0.377],
                [ 0.856,  0.758,  1.149, -0.412,  0.831],
                [ 1.31 ,  1.213,  1.603,  0.042,  1.286]]])

        Check by solving one pair of `c` and `b` vectors (cf. ``x[1, 1, :]``):

        >>> solve_circulant(c[1], b[1, :])
        array([ 0.856,  0.758,  1.149, -0.412,  0.831])

    solve_continuous_are(a, b, q, r, e=None, s=None, balanced=True)
        Solves the continuous-time algebraic Riccati equation (CARE).

        The CARE is defined as

        .. math::

              X A + A^H X - X B R^{-1} B^H X + Q = 0

        The limitations for a solution to exist are :

            * All eigenvalues of :math:`A` on the right half plane, should be
              controllable.

            * The associated hamiltonian pencil (See Notes), should have
              eigenvalues sufficiently away from the imaginary axis.

        Moreover, if ``e`` or ``s`` is not precisely ``None``, then the
        generalized version of CARE

        .. math::

              E^HXA + A^HXE - (E^HXB + S) R^{-1} (B^HXE + S^H) + Q = 0

        is solved. When omitted, ``e`` is assumed to be the identity and ``s``
        is assumed to be the zero matrix with sizes compatible with ``a`` and
        ``b``, respectively.

        Parameters
        ----------
        a : (M, M) array_like
            Square matrix
        b : (M, N) array_like
            Input
        q : (M, M) array_like
            Input
        r : (N, N) array_like
            Nonsingular square matrix
        e : (M, M) array_like, optional
            Nonsingular square matrix
        s : (M, N) array_like, optional
            Input
        balanced : bool, optional
            The boolean that indicates whether a balancing step is performed
            on the data. The default is set to True.

        Returns
        -------
        x : (M, M) ndarray
            Solution to the continuous-time algebraic Riccati equation.

        Raises
        ------
        LinAlgError
            For cases where the stable subspace of the pencil could not be
            isolated. See Notes section and the references for details.

        See Also
        --------
        solve_discrete_are : Solves the discrete-time algebraic Riccati equation

        Notes
        -----
        The equation is solved by forming the extended hamiltonian matrix pencil,
        as described in [1]_, :math:`H - \lambda J` given by the block matrices ::

            [ A    0    B ]             [ E   0    0 ]
            [-Q  -A^H  -S ] - \lambda * [ 0  E^H   0 ]
            [ S^H B^H   R ]             [ 0   0    0 ]

        and using a QZ decomposition method.

        In this algorithm, the fail conditions are linked to the symmetry
        of the product :math:`U_2 U_1^{-1}` and condition number of
        :math:`U_1`. Here, :math:`U` is the 2m-by-m matrix that holds the
        eigenvectors spanning the stable subspace with 2-m rows and partitioned
        into two m-row matrices. See [1]_ and [2]_ for more details.

        In order to improve the QZ decomposition accuracy, the pencil goes
        through a balancing step where the sum of absolute values of
        :math:`H` and :math:`J` entries (after removing the diagonal entries of
        the sum) is balanced following the recipe given in [3]_.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1]  P. van Dooren , "A Generalized Eigenvalue Approach For Solving
           Riccati Equations.", SIAM Journal on Scientific and Statistical
           Computing, Vol.2(2), :doi:`10.1137/0902010`

        .. [2] A.J. Laub, "A Schur Method for Solving Algebraic Riccati
           Equations.", Massachusetts Institute of Technology. Laboratory for
           Information and Decision Systems. LIDS-R ; 859. Available online :
           http://hdl.handle.net/1721.1/1301

        .. [3] P. Benner, "Symplectic Balancing of Hamiltonian Matrices", 2001,
           SIAM J. Sci. Comput., 2001, Vol.22(5), :doi:`10.1137/S1064827500367993`

        Examples
        --------
        Given `a`, `b`, `q`, and `r` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[4, 3], [-4.5, -3.5]])
        >>> b = np.array([[1], [-1]])
        >>> q = np.array([[9, 6], [6, 4.]])
        >>> r = 1
        >>> x = linalg.solve_continuous_are(a, b, q, r)
        >>> x
        array([[ 21.72792206,  14.48528137],
               [ 14.48528137,   9.65685425]])
        >>> np.allclose(a.T.dot(x) + x.dot(a)-x.dot(b).dot(b.T).dot(x), -q)
        True

    solve_continuous_lyapunov(a, q)
        Solves the continuous Lyapunov equation :math:`AX + XA^H = Q`.

        Uses the Bartels-Stewart algorithm to find :math:`X`.

        Parameters
        ----------
        a : array_like
            A square matrix

        q : array_like
            Right-hand side square matrix

        Returns
        -------
        x : ndarray
            Solution to the continuous Lyapunov equation

        See Also
        --------
        solve_discrete_lyapunov : computes the solution to the discrete-time
            Lyapunov equation
        solve_sylvester : computes the solution to the Sylvester equation

        Notes
        -----
        The continuous Lyapunov equation is a special form of the Sylvester
        equation, hence this solver relies on LAPACK routine ?TRSYL.

        .. versionadded:: 0.11.0

        Examples
        --------
        Given `a` and `q` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[-3, -2, 0], [-1, -1, 0], [0, -5, -1]])
        >>> b = np.array([2, 4, -1])
        >>> q = np.eye(3)
        >>> x = linalg.solve_continuous_lyapunov(a, q)
        >>> x
        array([[ -0.75  ,   0.875 ,  -3.75  ],
               [  0.875 ,  -1.375 ,   5.3125],
               [ -3.75  ,   5.3125, -27.0625]])
        >>> np.allclose(a.dot(x) + x.dot(a.T), q)
        True

    solve_discrete_are(a, b, q, r, e=None, s=None, balanced=True)
        Solves the discrete-time algebraic Riccati equation (DARE).

        The DARE is defined as

        .. math::

              A^HXA - X - (A^HXB) (R + B^HXB)^{-1} (B^HXA) + Q = 0

        The limitations for a solution to exist are :

            * All eigenvalues of :math:`A` outside the unit disc, should be
              controllable.

            * The associated symplectic pencil (See Notes), should have
              eigenvalues sufficiently away from the unit circle.

        Moreover, if ``e`` and ``s`` are not both precisely ``None``, then the
        generalized version of DARE

        .. math::

              A^HXA - E^HXE - (A^HXB+S) (R+B^HXB)^{-1} (B^HXA+S^H) + Q = 0

        is solved. When omitted, ``e`` is assumed to be the identity and ``s``
        is assumed to be the zero matrix.

        Parameters
        ----------
        a : (M, M) array_like
            Square matrix
        b : (M, N) array_like
            Input
        q : (M, M) array_like
            Input
        r : (N, N) array_like
            Square matrix
        e : (M, M) array_like, optional
            Nonsingular square matrix
        s : (M, N) array_like, optional
            Input
        balanced : bool
            The boolean that indicates whether a balancing step is performed
            on the data. The default is set to True.

        Returns
        -------
        x : (M, M) ndarray
            Solution to the discrete algebraic Riccati equation.

        Raises
        ------
        LinAlgError
            For cases where the stable subspace of the pencil could not be
            isolated. See Notes section and the references for details.

        See Also
        --------
        solve_continuous_are : Solves the continuous algebraic Riccati equation

        Notes
        -----
        The equation is solved by forming the extended symplectic matrix pencil,
        as described in [1]_, :math:`H - \lambda J` given by the block matrices ::

               [  A   0   B ]             [ E   0   B ]
               [ -Q  E^H -S ] - \lambda * [ 0  A^H  0 ]
               [ S^H  0   R ]             [ 0 -B^H  0 ]

        and using a QZ decomposition method.

        In this algorithm, the fail conditions are linked to the symmetry
        of the product :math:`U_2 U_1^{-1}` and condition number of
        :math:`U_1`. Here, :math:`U` is the 2m-by-m matrix that holds the
        eigenvectors spanning the stable subspace with 2-m rows and partitioned
        into two m-row matrices. See [1]_ and [2]_ for more details.

        In order to improve the QZ decomposition accuracy, the pencil goes
        through a balancing step where the sum of absolute values of
        :math:`H` and :math:`J` rows/cols (after removing the diagonal entries)
        is balanced following the recipe given in [3]_. If the data has small
        numerical noise, balancing may amplify their effects and some clean up
        is required.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1]  P. van Dooren , "A Generalized Eigenvalue Approach For Solving
           Riccati Equations.", SIAM Journal on Scientific and Statistical
           Computing, Vol.2(2), :doi:`10.1137/0902010`

        .. [2] A.J. Laub, "A Schur Method for Solving Algebraic Riccati
           Equations.", Massachusetts Institute of Technology. Laboratory for
           Information and Decision Systems. LIDS-R ; 859. Available online :
           http://hdl.handle.net/1721.1/1301

        .. [3] P. Benner, "Symplectic Balancing of Hamiltonian Matrices", 2001,
           SIAM J. Sci. Comput., 2001, Vol.22(5), :doi:`10.1137/S1064827500367993`

        Examples
        --------
        Given `a`, `b`, `q`, and `r` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg as la
        >>> a = np.array([[0, 1], [0, -1]])
        >>> b = np.array([[1, 0], [2, 1]])
        >>> q = np.array([[-4, -4], [-4, 7]])
        >>> r = np.array([[9, 3], [3, 1]])
        >>> x = la.solve_discrete_are(a, b, q, r)
        >>> x
        array([[-4., -4.],
               [-4.,  7.]])
        >>> R = la.solve(r + b.T.dot(x).dot(b), b.T.dot(x).dot(a))
        >>> np.allclose(a.T.dot(x).dot(a) - x - a.T.dot(x).dot(b).dot(R), -q)
        True

    solve_discrete_lyapunov(a, q, method=None)
        Solves the discrete Lyapunov equation :math:`AXA^H - X + Q = 0`.

        Parameters
        ----------
        a, q : (M, M) array_like
            Square matrices corresponding to A and Q in the equation
            above respectively. Must have the same shape.

        method : {'direct', 'bilinear'}, optional
            Type of solver.

            If not given, chosen to be ``direct`` if ``M`` is less than 10 and
            ``bilinear`` otherwise.

        Returns
        -------
        x : ndarray
            Solution to the discrete Lyapunov equation

        See Also
        --------
        solve_continuous_lyapunov : computes the solution to the continuous-time
            Lyapunov equation

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter. The default method is *direct* if ``M`` is less than 10
        and ``bilinear`` otherwise.

        Method *direct* uses a direct analytical solution to the discrete Lyapunov
        equation. The algorithm is given in, for example, [1]_. However, it requires
        the linear solution of a system with dimension :math:`M^2` so that
        performance degrades rapidly for even moderately sized matrices.

        Method *bilinear* uses a bilinear transformation to convert the discrete
        Lyapunov equation to a continuous Lyapunov equation :math:`(BX+XB'=-C)`
        where :math:`B=(A-I)(A+I)^{-1}` and
        :math:`C=2(A' + I)^{-1} Q (A + I)^{-1}`. The continuous equation can be
        efficiently solved since it is a special case of a Sylvester equation.
        The transformation algorithm is from Popov (1964) as described in [2]_.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1] "Lyapunov equation", Wikipedia,
           https://en.wikipedia.org/wiki/Lyapunov_equation#Discrete_time
        .. [2] Gajic, Z., and M.T.J. Qureshi. 2008.
           Lyapunov Matrix Equation in System Stability and Control.
           Dover Books on Engineering Series. Dover Publications.

        Examples
        --------
        Given `a` and `q` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[0.2, 0.5],[0.7, -0.9]])
        >>> q = np.eye(2)
        >>> x = linalg.solve_discrete_lyapunov(a, q)
        >>> x
        array([[ 0.70872893,  1.43518822],
               [ 1.43518822, -2.4266315 ]])
        >>> np.allclose(a.dot(x).dot(a.T)-x, -q)
        True

    solve_lyapunov = solve_continuous_lyapunov(a, q)
        Solves the continuous Lyapunov equation :math:`AX + XA^H = Q`.

        Uses the Bartels-Stewart algorithm to find :math:`X`.

        Parameters
        ----------
        a : array_like
            A square matrix

        q : array_like
            Right-hand side square matrix

        Returns
        -------
        x : ndarray
            Solution to the continuous Lyapunov equation

        See Also
        --------
        solve_discrete_lyapunov : computes the solution to the discrete-time
            Lyapunov equation
        solve_sylvester : computes the solution to the Sylvester equation

        Notes
        -----
        The continuous Lyapunov equation is a special form of the Sylvester
        equation, hence this solver relies on LAPACK routine ?TRSYL.

        .. versionadded:: 0.11.0

        Examples
        --------
        Given `a` and `q` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[-3, -2, 0], [-1, -1, 0], [0, -5, -1]])
        >>> b = np.array([2, 4, -1])
        >>> q = np.eye(3)
        >>> x = linalg.solve_continuous_lyapunov(a, q)
        >>> x
        array([[ -0.75  ,   0.875 ,  -3.75  ],
               [  0.875 ,  -1.375 ,   5.3125],
               [ -3.75  ,   5.3125, -27.0625]])
        >>> np.allclose(a.dot(x) + x.dot(a.T), q)
        True

    solve_sylvester(a, b, q)
        Computes a solution (X) to the Sylvester equation :math:`AX + XB = Q`.

        Parameters
        ----------
        a : (M, M) array_like
            Leading matrix of the Sylvester equation
        b : (N, N) array_like
            Trailing matrix of the Sylvester equation
        q : (M, N) array_like
            Right-hand side

        Returns
        -------
        x : (M, N) ndarray
            The solution to the Sylvester equation.

        Raises
        ------
        LinAlgError
            If solution was not found

        Notes
        -----
        Computes a solution to the Sylvester matrix equation via the Bartels-
        Stewart algorithm. The A and B matrices first undergo Schur
        decompositions. The resulting matrices are used to construct an
        alternative Sylvester equation (``RY + YS^T = F``) where the R and S
        matrices are in quasi-triangular form (or, when R, S or F are complex,
        triangular form). The simplified equation is then solved using
        ``*TRSYL`` from LAPACK directly.

        .. versionadded:: 0.11.0

        Examples
        --------
        Given `a`, `b`, and `q` solve for `x`:

        >>> import numpy as np
        >>> from scipy import linalg
        >>> a = np.array([[-3, -2, 0], [-1, -1, 3], [3, -5, -1]])
        >>> b = np.array([[1]])
        >>> q = np.array([[1],[2],[3]])
        >>> x = linalg.solve_sylvester(a, b, q)
        >>> x
        array([[ 0.0625],
               [-0.5625],
               [ 0.6875]])
        >>> np.allclose(a.dot(x) + x.dot(b), q)
        True

    solve_toeplitz(c_or_cr, b, check_finite=True)
        Solve a Toeplitz system using Levinson Recursion

        The Toeplitz matrix has constant diagonals, with c as its first column
        and r as its first row. If r is not given, ``r == conjugate(c)`` is
        assumed.

        Parameters
        ----------
        c_or_cr : array_like or tuple of (array_like, array_like)
            The vector ``c``, or a tuple of arrays (``c``, ``r``). Whatever the
            actual shape of ``c``, it will be converted to a 1-D array. If not
            supplied, ``r = conjugate(c)`` is assumed; in this case, if c[0] is
            real, the Toeplitz matrix is Hermitian. r[0] is ignored; the first row
            of the Toeplitz matrix is ``[c[0], r[1:]]``. Whatever the actual shape
            of ``r``, it will be converted to a 1-D array.
        b : (M,) or (M, K) array_like
            Right-hand side in ``T x = b``.
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (result entirely NaNs) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : (M,) or (M, K) ndarray
            The solution to the system ``T x = b``. Shape of return matches shape
            of `b`.

        See Also
        --------
        toeplitz : Toeplitz matrix

        Notes
        -----
        The solution is computed using Levinson-Durbin recursion, which is faster
        than generic least-squares methods, but can be less numerically stable.

        Examples
        --------
        Solve the Toeplitz system T x = b, where::

                [ 1 -1 -2 -3]       [1]
            T = [ 3  1 -1 -2]   b = [2]
                [ 6  3  1 -1]       [2]
                [10  6  3  1]       [5]

        To specify the Toeplitz matrix, only the first column and the first
        row are needed.

        >>> import numpy as np
        >>> c = np.array([1, 3, 6, 10])    # First column of T
        >>> r = np.array([1, -1, -2, -3])  # First row of T
        >>> b = np.array([1, 2, 2, 5])

        >>> from scipy.linalg import solve_toeplitz, toeplitz
        >>> x = solve_toeplitz((c, r), b)
        >>> x
        array([ 1.66666667, -1.        , -2.66666667,  2.33333333])

        Check the result by creating the full Toeplitz matrix and
        multiplying it by `x`.  We should get `b`.

        >>> T = toeplitz(c, r)
        >>> T.dot(x)
        array([ 1.,  2.,  2.,  5.])

    solve_triangular(a, b, trans=0, lower=False, unit_diagonal=False, overwrite_b=False, check_finite=True)
        Solve the equation `a x = b` for `x`, assuming a is a triangular matrix.

        Parameters
        ----------
        a : (M, M) array_like
            A triangular matrix
        b : (M,) or (M, N) array_like
            Right-hand side matrix in `a x = b`
        lower : bool, optional
            Use only data contained in the lower triangle of `a`.
            Default is to use upper triangle.
        trans : {0, 1, 2, 'N', 'T', 'C'}, optional
            Type of system to solve:

            ========  =========
            trans     system
            ========  =========
            0 or 'N'  a x  = b
            1 or 'T'  a^T x = b
            2 or 'C'  a^H x = b
            ========  =========
        unit_diagonal : bool, optional
            If True, diagonal elements of `a` are assumed to be 1 and
            will not be referenced.
        overwrite_b : bool, optional
            Allow overwriting data in `b` (may enhance performance)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : (M,) or (M, N) ndarray
            Solution to the system `a x = b`.  Shape of return matches `b`.

        Raises
        ------
        LinAlgError
            If `a` is singular

        Notes
        -----
        .. versionadded:: 0.9.0

        Examples
        --------
        Solve the lower triangular system a x = b, where::

                 [3  0  0  0]       [4]
            a =  [2  1  0  0]   b = [2]
                 [1  0  1  0]       [4]
                 [1  1  1  1]       [2]

        >>> import numpy as np
        >>> from scipy.linalg import solve_triangular
        >>> a = np.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]])
        >>> b = np.array([4, 2, 4, 2])
        >>> x = solve_triangular(a, b, lower=True)
        >>> x
        array([ 1.33333333, -0.66666667,  2.66666667, -1.33333333])
        >>> a.dot(x)  # Check the result
        array([ 4.,  2.,  4.,  2.])

    solveh_banded(ab, b, overwrite_ab=False, overwrite_b=False, lower=False, check_finite=True)
        Solve equation a x = b. a is Hermitian positive-definite banded matrix.

        Uses Thomas' Algorithm, which is more efficient than standard LU
        factorization, but should only be used for Hermitian positive-definite
        matrices.

        The matrix ``a`` is stored in `ab` either in lower diagonal or upper
        diagonal ordered form:

            ab[u + i - j, j] == a[i,j]        (if upper form; i <= j)
            ab[    i - j, j] == a[i,j]        (if lower form; i >= j)

        Example of `ab` (shape of ``a`` is (6, 6), number of upper diagonals,
        ``u`` =2)::

            upper form:
            *   *   a02 a13 a24 a35
            *   a01 a12 a23 a34 a45
            a00 a11 a22 a33 a44 a55

            lower form:
            a00 a11 a22 a33 a44 a55
            a10 a21 a32 a43 a54 *
            a20 a31 a42 a53 *   *

        Cells marked with * are not used.

        Parameters
        ----------
        ab : (``u`` + 1, M) array_like
            Banded matrix
        b : (M,) or (M, K) array_like
            Right-hand side
        overwrite_ab : bool, optional
            Discard data in `ab` (may enhance performance)
        overwrite_b : bool, optional
            Discard data in `b` (may enhance performance)
        lower : bool, optional
            Is the matrix in the lower form. (Default is upper form)
        check_finite : bool, optional
            Whether to check that the input matrices contain only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        x : (M,) or (M, K) ndarray
            The solution to the system ``a x = b``. Shape of return matches shape
            of `b`.

        Notes
        -----
        In the case of a non-positive definite matrix ``a``, the solver
        `solve_banded` may be used.

        Examples
        --------
        Solve the banded system ``A x = b``, where::

                [ 4  2 -1  0  0  0]       [1]
                [ 2  5  2 -1  0  0]       [2]
            A = [-1  2  6  2 -1  0]   b = [2]
                [ 0 -1  2  7  2 -1]       [3]
                [ 0  0 -1  2  8  2]       [3]
                [ 0  0  0 -1  2  9]       [3]

        >>> import numpy as np
        >>> from scipy.linalg import solveh_banded

        ``ab`` contains the main diagonal and the nonzero diagonals below the
        main diagonal. That is, we use the lower form:

        >>> ab = np.array([[ 4,  5,  6,  7, 8, 9],
        ...                [ 2,  2,  2,  2, 2, 0],
        ...                [-1, -1, -1, -1, 0, 0]])
        >>> b = np.array([1, 2, 2, 3, 3, 3])
        >>> x = solveh_banded(ab, b, lower=True)
        >>> x
        array([ 0.03431373,  0.45938375,  0.05602241,  0.47759104,  0.17577031,
                0.34733894])


        Solve the Hermitian banded system ``H x = b``, where::

                [ 8   2-1j   0     0  ]        [ 1  ]
            H = [2+1j  5     1j    0  ]    b = [1+1j]
                [ 0   -1j    9   -2-1j]        [1-2j]
                [ 0    0   -2+1j   6  ]        [ 0  ]

        In this example, we put the upper diagonals in the array ``hb``:

        >>> hb = np.array([[0, 2-1j, 1j, -2-1j],
        ...                [8,  5,    9,   6  ]])
        >>> b = np.array([1, 1+1j, 1-2j, 0])
        >>> x = solveh_banded(hb, b)
        >>> x
        array([ 0.07318536-0.02939412j,  0.11877624+0.17696461j,
                0.10077984-0.23035393j, -0.00479904-0.09358128j])

    sqrtm(A, disp=True, blocksize=64)
        Matrix square root.

        Parameters
        ----------
        A : (N, N) array_like
            Matrix whose square root to evaluate
        disp : bool, optional
            Print warning if error in the result is estimated large
            instead of returning estimated error. (Default: True)
        blocksize : integer, optional
            If the blocksize is not degenerate with respect to the
            size of the input array, then use a blocked algorithm. (Default: 64)

        Returns
        -------
        sqrtm : (N, N) ndarray
            Value of the sqrt function at `A`. The dtype is float or complex.
            The precision (data size) is determined based on the precision of
            input `A`. When the dtype is float, the precision is the same as `A`.
            When the dtype is complex, the precision is double that of `A`. The
            precision might be clipped by each dtype precision range.

        errest : float
            (if disp == False)

            Frobenius norm of the estimated error, ||err||_F / ||A||_F

        References
        ----------
        .. [1] Edvin Deadman, Nicholas J. Higham, Rui Ralha (2013)
               "Blocked Schur Algorithms for Computing the Matrix Square Root,
               Lecture Notes in Computer Science, 7782. pp. 171-182.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import sqrtm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> r = sqrtm(a)
        >>> r
        array([[ 0.75592895,  1.13389342],
               [ 0.37796447,  1.88982237]])
        >>> r.dot(r)
        array([[ 1.,  3.],
               [ 1.,  4.]])

    subspace_angles(A, B)
        Compute the subspace angles between two matrices.

        Parameters
        ----------
        A : (M, N) array_like
            The first input array.
        B : (M, K) array_like
            The second input array.

        Returns
        -------
        angles : ndarray, shape (min(N, K),)
            The subspace angles between the column spaces of `A` and `B` in
            descending order.

        See Also
        --------
        orth
        svd

        Notes
        -----
        This computes the subspace angles according to the formula
        provided in [1]_. For equivalence with MATLAB and Octave behavior,
        use ``angles[0]``.

        .. versionadded:: 1.0

        References
        ----------
        .. [1] Knyazev A, Argentati M (2002) Principal Angles between Subspaces
               in an A-Based Scalar Product: Algorithms and Perturbation
               Estimates. SIAM J. Sci. Comput. 23:2008-2040.

        Examples
        --------
        An Hadamard matrix, which has orthogonal columns, so we expect that
        the suspace angle to be :math:`\frac{\pi}{2}`:

        >>> import numpy as np
        >>> from scipy.linalg import hadamard, subspace_angles
        >>> rng = np.random.default_rng()
        >>> H = hadamard(4)
        >>> print(H)
        [[ 1  1  1  1]
         [ 1 -1  1 -1]
         [ 1  1 -1 -1]
         [ 1 -1 -1  1]]
        >>> np.rad2deg(subspace_angles(H[:, :2], H[:, 2:]))
        array([ 90.,  90.])

        And the subspace angle of a matrix to itself should be zero:

        >>> subspace_angles(H[:, :2], H[:, :2]) <= 2 * np.finfo(float).eps
        array([ True,  True], dtype=bool)

        The angles between non-orthogonal subspaces are in between these extremes:

        >>> x = rng.standard_normal((4, 3))
        >>> np.rad2deg(subspace_angles(x[:, :2], x[:, [2]]))
        array([ 55.832])  # random

    svd(a, full_matrices=True, compute_uv=True, overwrite_a=False, check_finite=True, lapack_driver='gesdd')
        Singular Value Decomposition.

        Factorizes the matrix `a` into two unitary matrices ``U`` and ``Vh``, and
        a 1-D array ``s`` of singular values (real, non-negative) such that
        ``a == U @ S @ Vh``, where ``S`` is a suitably shaped matrix of zeros with
        main diagonal ``s``.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to decompose.
        full_matrices : bool, optional
            If True (default), `U` and `Vh` are of shape ``(M, M)``, ``(N, N)``.
            If False, the shapes are ``(M, K)`` and ``(K, N)``, where
            ``K = min(M, N)``.
        compute_uv : bool, optional
            Whether to compute also ``U`` and ``Vh`` in addition to ``s``.
            Default is True.
        overwrite_a : bool, optional
            Whether to overwrite `a`; may improve performance.
            Default is False.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.
        lapack_driver : {'gesdd', 'gesvd'}, optional
            Whether to use the more efficient divide-and-conquer approach
            (``'gesdd'``) or general rectangular approach (``'gesvd'``)
            to compute the SVD. MATLAB and Octave use the ``'gesvd'`` approach.
            Default is ``'gesdd'``.

            .. versionadded:: 0.18

        Returns
        -------
        U : ndarray
            Unitary matrix having left singular vectors as columns.
            Of shape ``(M, M)`` or ``(M, K)``, depending on `full_matrices`.
        s : ndarray
            The singular values, sorted in non-increasing order.
            Of shape (K,), with ``K = min(M, N)``.
        Vh : ndarray
            Unitary matrix having right singular vectors as rows.
            Of shape ``(N, N)`` or ``(K, N)`` depending on `full_matrices`.

        For ``compute_uv=False``, only ``s`` is returned.

        Raises
        ------
        LinAlgError
            If SVD computation does not converge.

        See Also
        --------
        svdvals : Compute singular values of a matrix.
        diagsvd : Construct the Sigma matrix, given the vector s.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import linalg
        >>> rng = np.random.default_rng()
        >>> m, n = 9, 6
        >>> a = rng.standard_normal((m, n)) + 1.j*rng.standard_normal((m, n))
        >>> U, s, Vh = linalg.svd(a)
        >>> U.shape,  s.shape, Vh.shape
        ((9, 9), (6,), (6, 6))

        Reconstruct the original matrix from the decomposition:

        >>> sigma = np.zeros((m, n))
        >>> for i in range(min(m, n)):
        ...     sigma[i, i] = s[i]
        >>> a1 = np.dot(U, np.dot(sigma, Vh))
        >>> np.allclose(a, a1)
        True

        Alternatively, use ``full_matrices=False`` (notice that the shape of
        ``U`` is then ``(m, n)`` instead of ``(m, m)``):

        >>> U, s, Vh = linalg.svd(a, full_matrices=False)
        >>> U.shape, s.shape, Vh.shape
        ((9, 6), (6,), (6, 6))
        >>> S = np.diag(s)
        >>> np.allclose(a, np.dot(U, np.dot(S, Vh)))
        True

        >>> s2 = linalg.svd(a, compute_uv=False)
        >>> np.allclose(s, s2)
        True

    svdvals(a, overwrite_a=False, check_finite=True)
        Compute singular values of a matrix.

        Parameters
        ----------
        a : (M, N) array_like
            Matrix to decompose.
        overwrite_a : bool, optional
            Whether to overwrite `a`; may improve performance.
            Default is False.
        check_finite : bool, optional
            Whether to check that the input matrix contains only finite numbers.
            Disabling may give a performance gain, but may result in problems
            (crashes, non-termination) if the inputs do contain infinities or NaNs.

        Returns
        -------
        s : (min(M, N),) ndarray
            The singular values, sorted in decreasing order.

        Raises
        ------
        LinAlgError
            If SVD computation does not converge.

        See Also
        --------
        svd : Compute the full singular value decomposition of a matrix.
        diagsvd : Construct the Sigma matrix, given the vector s.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import svdvals
        >>> m = np.array([[1.0, 0.0],
        ...               [2.0, 3.0],
        ...               [1.0, 1.0],
        ...               [0.0, 2.0],
        ...               [1.0, 0.0]])
        >>> svdvals(m)
        array([ 4.28091555,  1.63516424])

        We can verify the maximum singular value of `m` by computing the maximum
        length of `m.dot(u)` over all the unit vectors `u` in the (x,y) plane.
        We approximate "all" the unit vectors with a large sample. Because
        of linearity, we only need the unit vectors with angles in [0, pi].

        >>> t = np.linspace(0, np.pi, 2000)
        >>> u = np.array([np.cos(t), np.sin(t)])
        >>> np.linalg.norm(m.dot(u), axis=0).max()
        4.2809152422538475

        `p` is a projection matrix with rank 1. With exact arithmetic,
        its singular values would be [1, 0, 0, 0].

        >>> v = np.array([0.1, 0.3, 0.9, 0.3])
        >>> p = np.outer(v, v)
        >>> svdvals(p)
        array([  1.00000000e+00,   2.02021698e-17,   1.56692500e-17,
                 8.15115104e-34])

        The singular values of an orthogonal matrix are all 1. Here, we
        create a random orthogonal matrix by using the `rvs()` method of
        `scipy.stats.ortho_group`.

        >>> from scipy.stats import ortho_group
        >>> orth = ortho_group.rvs(4)
        >>> svdvals(orth)
        array([ 1.,  1.,  1.,  1.])

    tanhm(A)
        Compute the hyperbolic matrix tangent.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array

        Returns
        -------
        tanhm : (N, N) ndarray
            Hyperbolic matrix tangent of `A`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import tanhm, sinhm, coshm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> t = tanhm(a)
        >>> t
        array([[ 0.3428582 ,  0.51987926],
               [ 0.17329309,  0.86273746]])

        Verify tanhm(a) = sinhm(a).dot(inv(coshm(a)))

        >>> s = sinhm(a)
        >>> c = coshm(a)
        >>> t - s.dot(np.linalg.inv(c))
        array([[  2.72004641e-15,   4.55191440e-15],
               [  0.00000000e+00,  -5.55111512e-16]])

    tanm(A)
        Compute the matrix tangent.

        This routine uses expm to compute the matrix exponentials.

        Parameters
        ----------
        A : (N, N) array_like
            Input array.

        Returns
        -------
        tanm : (N, N) ndarray
            Matrix tangent of `A`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.linalg import tanm, sinm, cosm
        >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
        >>> t = tanm(a)
        >>> t
        array([[ -2.00876993,  -8.41880636],
               [ -2.80626879, -10.42757629]])

        Verify tanm(a) = sinm(a).dot(inv(cosm(a)))

        >>> s = sinm(a)
        >>> c = cosm(a)
        >>> s.dot(np.linalg.inv(c))
        array([[ -2.00876993,  -8.41880636],
               [ -2.80626879, -10.42757629]])

    toeplitz(c, r=None)
        Construct a Toeplitz matrix.

        The Toeplitz matrix has constant diagonals, with c as its first column
        and r as its first row. If r is not given, ``r == conjugate(c)`` is
        assumed.

        Parameters
        ----------
        c : array_like
            First column of the matrix.  Whatever the actual shape of `c`, it
            will be converted to a 1-D array.
        r : array_like, optional
            First row of the matrix. If None, ``r = conjugate(c)`` is assumed;
            in this case, if c[0] is real, the result is a Hermitian matrix.
            r[0] is ignored; the first row of the returned matrix is
            ``[c[0], r[1:]]``.  Whatever the actual shape of `r`, it will be
            converted to a 1-D array.

        Returns
        -------
        A : (len(c), len(r)) ndarray
            The Toeplitz matrix. Dtype is the same as ``(c[0] + r[0]).dtype``.

        See Also
        --------
        circulant : circulant matrix
        hankel : Hankel matrix
        solve_toeplitz : Solve a Toeplitz system.

        Notes
        -----
        The behavior when `c` or `r` is a scalar, or when `c` is complex and
        `r` is None, was changed in version 0.8.0. The behavior in previous
        versions was undocumented and is no longer supported.

        Examples
        --------
        >>> from scipy.linalg import toeplitz
        >>> toeplitz([1,2,3], [1,4,5,6])
        array([[1, 4, 5, 6],
               [2, 1, 4, 5],
               [3, 2, 1, 4]])
        >>> toeplitz([1.0, 2+3j, 4-1j])
        array([[ 1.+0.j,  2.-3.j,  4.+1.j],
               [ 2.+3.j,  1.+0.j,  2.-3.j],
               [ 4.-1.j,  2.+3.j,  1.+0.j]])

DATA
    __all__ = ['LinAlgError', 'LinAlgWarning', 'bandwidth', 'basic', 'blas...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\linalg\__init__.py

scipy.misc
Python Library Documentation: package scipy.misc in scipy

NAME
    scipy.misc

DESCRIPTION
    ==========================================
    Miscellaneous routines (:mod:`scipy.misc`)
    ==========================================

    .. currentmodule:: scipy.misc

    .. deprecated:: 1.10.0

       This module is deprecated and will be completely
       removed in SciPy v2.0.0.

    Various utilities that don't have another home.

    .. autosummary::
       :toctree: generated/

       ascent - Get example image for processing
       central_diff_weights - Weights for an n-point central mth derivative
       derivative - Find the nth derivative of a function at a point
       face - Get example image for processing
       electrocardiogram - Load an example of a 1-D signal

PACKAGE CONTENTS
    _common
    common
    doccer
    tests (package)

FUNCTIONS
    ascent()
        Get an 8-bit grayscale bit-depth, 512 x 512 derived image for easy use in demos

        The image is derived from accent-to-the-top.jpg at
        http://www.public-domain-image.com/people-public-domain-images-pictures/

        .. deprecated:: 1.10.0
            `ascent` has been deprecated from `scipy.misc.ascent`
            in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
            Dataset methods have moved into the `scipy.datasets` module.
            Use `scipy.datasets.ascent` instead.

        Parameters
        ----------
        None

        Returns
        -------
        ascent : ndarray
           convenient image to use for testing and demonstration

        Examples
        --------
        >>> import scipy.misc
        >>> ascent = scipy.misc.ascent()
        >>> ascent.shape
        (512, 512)
        >>> ascent.max()
        255

        >>> import matplotlib.pyplot as plt
        >>> plt.gray()
        >>> plt.imshow(ascent)
        >>> plt.show()

    central_diff_weights(Np, ndiv=1)
        Return weights for an Np-point central derivative.

        Assumes equally-spaced function points.

        If weights are in the vector w, then
        derivative is w[0] * f(x-ho*dx) + ... + w[-1] * f(x+h0*dx)

        .. deprecated:: 1.10.0
            `central_diff_weights` has been deprecated from
            `scipy.misc.central_diff_weights` in SciPy 1.10.0 and
            it will be completely removed in SciPy 1.12.0.
            You may consider using
            findiff: https://github.com/maroba/findiff or
            numdifftools: https://github.com/pbrod/numdifftools

        Parameters
        ----------
        Np : int
            Number of points for the central derivative.
        ndiv : int, optional
            Number of divisions. Default is 1.

        Returns
        -------
        w : ndarray
            Weights for an Np-point central derivative. Its size is `Np`.

        Notes
        -----
        Can be inaccurate for a large number of points.

        Examples
        --------
        We can calculate a derivative value of a function.

        >>> from scipy.misc import central_diff_weights
        >>> def f(x):
        ...     return 2 * x**2 + 3
        >>> x = 3.0 # derivative point
        >>> h = 0.1 # differential step
        >>> Np = 3 # point number for central derivative
        >>> weights = central_diff_weights(Np) # weights for first derivative
        >>> vals = [f(x + (i - Np/2) * h) for i in range(Np)]
        >>> sum(w * v for (w, v) in zip(weights, vals))/h
        11.79999999999998

        This value is close to the analytical solution:
        f'(x) = 4x, so f'(3) = 12

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Finite_difference

    derivative(func, x0, dx=1.0, n=1, args=(), order=3)
        Find the nth derivative of a function at a point.

        Given a function, use a central difference formula with spacing `dx` to
        compute the nth derivative at `x0`.

        .. deprecated:: 1.10.0
            `derivative` has been deprecated from `scipy.misc.derivative`
            in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
            You may consider using
            findiff: https://github.com/maroba/findiff or
            numdifftools: https://github.com/pbrod/numdifftools

        Parameters
        ----------
        func : function
            Input function.
        x0 : float
            The point at which the nth derivative is found.
        dx : float, optional
            Spacing.
        n : int, optional
            Order of the derivative. Default is 1.
        args : tuple, optional
            Arguments
        order : int, optional
            Number of points to use, must be odd.

        Notes
        -----
        Decreasing the step size too small can result in round-off error.

        Examples
        --------
        >>> from scipy.misc import derivative
        >>> def f(x):
        ...     return x**3 + x**2
        >>> derivative(f, 1.0, dx=1e-6)
        4.9999999999217337

    electrocardiogram()
        Load an electrocardiogram as an example for a 1-D signal.

        The returned signal is a 5 minute long electrocardiogram (ECG), a medical
        recording of the heart's electrical activity, sampled at 360 Hz.

        .. deprecated:: 1.10.0
            `electrocardiogram` has been deprecated from
            `scipy.misc.electrocardiogram` in SciPy 1.10.0 and it will be
            completely removed in SciPy 1.12.0.
            Dataset methods have moved into the `scipy.datasets` module.
            Use `scipy.datasets.electrocardiogram` instead.

        Returns
        -------
        ecg : ndarray
            The electrocardiogram in millivolt (mV) sampled at 360 Hz.

        Notes
        -----
        The provided signal is an excerpt (19:35 to 24:35) from the `record 208`_
        (lead MLII) provided by the MIT-BIH Arrhythmia Database [1]_ on
        PhysioNet [2]_. The excerpt includes noise induced artifacts, typical
        heartbeats as well as pathological changes.

        .. _record 208: https://physionet.org/physiobank/database/html/mitdbdir/records.htm#208

        .. versionadded:: 1.1.0

        References
        ----------
        .. [1] Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database.
               IEEE Eng in Med and Biol 20(3):45-50 (May-June 2001).
               (PMID: 11446209); :doi:`10.13026/C2F305`
        .. [2] Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh,
               Mark RG, Mietus JE, Moody GB, Peng C-K, Stanley HE. PhysioBank,
               PhysioToolkit, and PhysioNet: Components of a New Research Resource
               for Complex Physiologic Signals. Circulation 101(23):e215-e220;
               :doi:`10.1161/01.CIR.101.23.e215`

        Examples
        --------
        >>> from scipy.misc import electrocardiogram
        >>> ecg = electrocardiogram()
        >>> ecg
        array([-0.245, -0.215, -0.185, ..., -0.405, -0.395, -0.385])
        >>> ecg.shape, ecg.mean(), ecg.std()
        ((108000,), -0.16510875, 0.5992473991177294)

        As stated the signal features several areas with a different morphology.
        E.g., the first few seconds show the electrical activity of a heart in
        normal sinus rhythm as seen below.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> fs = 360
        >>> time = np.arange(ecg.size) / fs
        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(9, 10.2)
        >>> plt.ylim(-1, 1.5)
        >>> plt.show()

        After second 16, however, the first premature ventricular contractions, also
        called extrasystoles, appear. These have a different morphology compared to
        typical heartbeats. The difference can easily be observed in the following
        plot.

        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(46.5, 50)
        >>> plt.ylim(-2, 1.5)
        >>> plt.show()

        At several points large artifacts disturb the recording, e.g.:

        >>> plt.plot(time, ecg)
        >>> plt.xlabel("time in s")
        >>> plt.ylabel("ECG in mV")
        >>> plt.xlim(207, 215)
        >>> plt.ylim(-2, 3.5)
        >>> plt.show()

        Finally, examining the power spectrum reveals that most of the biosignal is
        made up of lower frequencies. At 60 Hz the noise induced by the mains
        electricity can be clearly observed.

        >>> from scipy.signal import welch
        >>> f, Pxx = welch(ecg, fs=fs, nperseg=2048, scaling="spectrum")
        >>> plt.semilogy(f, Pxx)
        >>> plt.xlabel("Frequency in Hz")
        >>> plt.ylabel("Power spectrum of the ECG in mV**2")
        >>> plt.xlim(f[[0, -1]])
        >>> plt.show()

    face(gray=False)
        Get a 1024 x 768, color image of a raccoon face.

        raccoon-procyon-lotor.jpg at http://www.public-domain-image.com

        .. deprecated:: 1.10.0
            `face` has been deprecated from `scipy.misc.face`
            in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
            Dataset methods have moved into the `scipy.datasets` module.
            Use `scipy.datasets.face` instead.

        Parameters
        ----------
        gray : bool, optional
            If True return 8-bit grey-scale image, otherwise return a color image

        Returns
        -------
        face : ndarray
            image of a raccoon face

        Examples
        --------
        >>> import scipy.misc
        >>> face = scipy.misc.face()
        >>> face.shape
        (768, 1024, 3)
        >>> face.max()
        255
        >>> face.dtype
        dtype('uint8')

        >>> import matplotlib.pyplot as plt
        >>> plt.gray()
        >>> plt.imshow(face)
        >>> plt.show()

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\misc\__init__.py

scipy.ndimage
Python Library Documentation: package scipy.ndimage in scipy

NAME
    scipy.ndimage

DESCRIPTION
    =========================================================
    Multidimensional image processing (:mod:`scipy.ndimage`)
    =========================================================

    .. currentmodule:: scipy.ndimage

    This package contains various functions for multidimensional image
    processing.


    Filters
    =======

    .. autosummary::
       :toctree: generated/

       convolve - Multidimensional convolution
       convolve1d - 1-D convolution along the given axis
       correlate - Multidimensional correlation
       correlate1d - 1-D correlation along the given axis
       gaussian_filter
       gaussian_filter1d
       gaussian_gradient_magnitude
       gaussian_laplace
       generic_filter - Multidimensional filter using a given function
       generic_filter1d - 1-D generic filter along the given axis
       generic_gradient_magnitude
       generic_laplace
       laplace - N-D Laplace filter based on approximate second derivatives
       maximum_filter
       maximum_filter1d
       median_filter - Calculates a multidimensional median filter
       minimum_filter
       minimum_filter1d
       percentile_filter - Calculates a multidimensional percentile filter
       prewitt
       rank_filter - Calculates a multidimensional rank filter
       sobel
       uniform_filter - Multidimensional uniform filter
       uniform_filter1d - 1-D uniform filter along the given axis

    Fourier filters
    ===============

    .. autosummary::
       :toctree: generated/

       fourier_ellipsoid
       fourier_gaussian
       fourier_shift
       fourier_uniform

    Interpolation
    =============

    .. autosummary::
       :toctree: generated/

       affine_transform - Apply an affine transformation
       geometric_transform - Apply an arbitrary geometric transform
       map_coordinates - Map input array to new coordinates by interpolation
       rotate - Rotate an array
       shift - Shift an array
       spline_filter
       spline_filter1d
       zoom - Zoom an array

    Measurements
    ============

    .. autosummary::
       :toctree: generated/

       center_of_mass - The center of mass of the values of an array at labels
       extrema - Min's and max's of an array at labels, with their positions
       find_objects - Find objects in a labeled array
       histogram - Histogram of the values of an array, optionally at labels
       label - Label features in an array
       labeled_comprehension
       maximum
       maximum_position
       mean - Mean of the values of an array at labels
       median
       minimum
       minimum_position
       standard_deviation - Standard deviation of an N-D image array
       sum_labels - Sum of the values of the array
       value_indices - Find indices of each distinct value in given array
       variance - Variance of the values of an N-D image array
       watershed_ift

    Morphology
    ==========

    .. autosummary::
       :toctree: generated/

       binary_closing
       binary_dilation
       binary_erosion
       binary_fill_holes
       binary_hit_or_miss
       binary_opening
       binary_propagation
       black_tophat
       distance_transform_bf
       distance_transform_cdt
       distance_transform_edt
       generate_binary_structure
       grey_closing
       grey_dilation
       grey_erosion
       grey_opening
       iterate_structure
       morphological_gradient
       morphological_laplace
       white_tophat

PACKAGE CONTENTS
    _ctest
    _cytest
    _filters
    _fourier
    _interpolation
    _measurements
    _morphology
    _nd_image
    _ni_docstrings
    _ni_label
    _ni_support
    filters
    fourier
    interpolation
    measurements
    morphology
    tests (package)

FUNCTIONS
    affine_transform(input, matrix, offset=0.0, output_shape=None, output=None, order=3, mode='constant', cval=0.0, prefilter=True)
        Apply an affine transformation.

        Given an output image pixel index vector ``o``, the pixel value
        is determined from the input image at position
        ``np.dot(matrix, o) + offset``.

        This does 'pull' (or 'backward') resampling, transforming the output space
        to the input to locate data. Affine transformations are often described in
        the 'push' (or 'forward') direction, transforming input to output. If you
        have a matrix for the 'push' transformation, use its inverse
        (:func:`numpy.linalg.inv`) in this function.

        Parameters
        ----------
        input : array_like
            The input array.
        matrix : ndarray
            The inverse coordinate transformation matrix, mapping output
            coordinates to input coordinates. If ``ndim`` is the number of
            dimensions of ``input``, the given matrix must have one of the
            following shapes:

                - ``(ndim, ndim)``: the linear transformation matrix for each
                  output coordinate.
                - ``(ndim,)``: assume that the 2-D transformation matrix is
                  diagonal, with the diagonal specified by the given value. A more
                  efficient algorithm is then used that exploits the separability
                  of the problem.
                - ``(ndim + 1, ndim + 1)``: assume that the transformation is
                  specified using homogeneous coordinates [1]_. In this case, any
                  value passed to ``offset`` is ignored.
                - ``(ndim, ndim + 1)``: as above, but the bottom row of a
                  homogeneous transformation matrix is always ``[0, 0, ..., 1]``,
                  and may be omitted.

        offset : float or sequence, optional
            The offset into the array where the transform is applied. If a float,
            `offset` is the same for each axis. If a sequence, `offset` should
            contain one value for each axis.
        output_shape : tuple of ints, optional
            Shape tuple.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.

        Returns
        -------
        affine_transform : ndarray
            The transformed input.

        Notes
        -----
        The given matrix and offset are used to find for each point in the
        output the corresponding coordinates in the input by an affine
        transformation. The value of the input at those coordinates is
        determined by spline interpolation of the requested order. Points
        outside the boundaries of the input are filled according to the given
        mode.

        .. versionchanged:: 0.18.0
            Previously, the exact interpretation of the affine transformation
            depended on whether the matrix was supplied as a 1-D or a
            2-D array. If a 1-D array was supplied
            to the matrix parameter, the output pixel value at index ``o``
            was determined from the input image at position
            ``matrix * (o + offset)``.

        For complex-valued `input`, this function transforms the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Homogeneous_coordinates

    binary_closing(input, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False)
        Multidimensional binary closing with the given structuring element.

        The *closing* of an input image by a structuring element is the
        *erosion* of the *dilation* of the image by the structuring element.

        Parameters
        ----------
        input : array_like
            Binary array_like to be closed. Non-zero (True) elements form
            the subset to be closed.
        structure : array_like, optional
            Structuring element used for the closing. Non-zero elements are
            considered True. If no structuring element is provided an element
            is generated with a square connectivity equal to one (i.e., only
            nearest neighbors are connected to the center, diagonally-connected
            elements are not considered neighbors).
        iterations : int, optional
            The dilation step of the closing, then the erosion step are each
            repeated `iterations` times (one, by default). If iterations is
            less than 1, each operations is repeated until the result does
            not change anymore. Only an integer of iterations is accepted.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        origin : int or tuple of ints, optional
            Placement of the filter, by default 0.
        mask : array_like, optional
            If a mask is given, only those elements with a True value at
            the corresponding mask element are modified at each iteration.

            .. versionadded:: 1.1.0
        border_value : int (cast to 0 or 1), optional
            Value at the border in the output array.

            .. versionadded:: 1.1.0
        brute_force : boolean, optional
            Memory condition: if False, only the pixels whose value was changed in
            the last iteration are tracked as candidates to be updated in the
            current iteration; if true al pixels are considered as candidates for
            update, regardless of what happened in the previous iteration.
            False by default.

            .. versionadded:: 1.1.0

        Returns
        -------
        binary_closing : ndarray of bools
            Closing of the input by the structuring element.

        See Also
        --------
        grey_closing, binary_opening, binary_dilation, binary_erosion,
        generate_binary_structure

        Notes
        -----
        *Closing* [1]_ is a mathematical morphology operation [2]_ that
        consists in the succession of a dilation and an erosion of the
        input with the same structuring element. Closing therefore fills
        holes smaller than the structuring element.

        Together with *opening* (`binary_opening`), closing can be used for
        noise removal.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Closing_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((5,5), dtype=int)
        >>> a[1:-1, 1:-1] = 1; a[2,2] = 0
        >>> a
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 0, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])
        >>> # Closing removes small holes
        >>> ndimage.binary_closing(a).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])
        >>> # Closing is the erosion of the dilation of the input
        >>> ndimage.binary_dilation(a).astype(int)
        array([[0, 1, 1, 1, 0],
               [1, 1, 1, 1, 1],
               [1, 1, 1, 1, 1],
               [1, 1, 1, 1, 1],
               [0, 1, 1, 1, 0]])
        >>> ndimage.binary_erosion(ndimage.binary_dilation(a)).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])


        >>> a = np.zeros((7,7), dtype=int)
        >>> a[1:6, 2:5] = 1; a[1:3,3] = 0
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 0, 1, 0, 0],
               [0, 0, 1, 0, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> # In addition to removing holes, closing can also
        >>> # coarsen boundaries with fine hollows.
        >>> ndimage.binary_closing(a).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 0, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.binary_closing(a, structure=np.ones((2,2))).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])

    binary_dilation(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False)
        Multidimensional binary dilation with the given structuring element.

        Parameters
        ----------
        input : array_like
            Binary array_like to be dilated. Non-zero (True) elements form
            the subset to be dilated.
        structure : array_like, optional
            Structuring element used for the dilation. Non-zero elements are
            considered True. If no structuring element is provided an element
            is generated with a square connectivity equal to one.
        iterations : int, optional
            The dilation is repeated `iterations` times (one, by default).
            If iterations is less than 1, the dilation is repeated until the
            result does not change anymore. Only an integer of iterations is
            accepted.
        mask : array_like, optional
            If a mask is given, only those elements with a True value at
            the corresponding mask element are modified at each iteration.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        border_value : int (cast to 0 or 1), optional
            Value at the border in the output array.
        origin : int or tuple of ints, optional
            Placement of the filter, by default 0.
        brute_force : boolean, optional
            Memory condition: if False, only the pixels whose value was changed in
            the last iteration are tracked as candidates to be updated (dilated)
            in the current iteration; if True all pixels are considered as
            candidates for dilation, regardless of what happened in the previous
            iteration. False by default.

        Returns
        -------
        binary_dilation : ndarray of bools
            Dilation of the input by the structuring element.

        See Also
        --------
        grey_dilation, binary_erosion, binary_closing, binary_opening,
        generate_binary_structure

        Notes
        -----
        Dilation [1]_ is a mathematical morphology operation [2]_ that uses a
        structuring element for expanding the shapes in an image. The binary
        dilation of an image by a structuring element is the locus of the points
        covered by the structuring element, when its center lies within the
        non-zero points of the image.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Dilation_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((5, 5))
        >>> a[2, 2] = 1
        >>> a
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> ndimage.binary_dilation(a)
        array([[False, False, False, False, False],
               [False, False,  True, False, False],
               [False,  True,  True,  True, False],
               [False, False,  True, False, False],
               [False, False, False, False, False]], dtype=bool)
        >>> ndimage.binary_dilation(a).astype(a.dtype)
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> # 3x3 structuring element with connectivity 1, used by default
        >>> struct1 = ndimage.generate_binary_structure(2, 1)
        >>> struct1
        array([[False,  True, False],
               [ True,  True,  True],
               [False,  True, False]], dtype=bool)
        >>> # 3x3 structuring element with connectivity 2
        >>> struct2 = ndimage.generate_binary_structure(2, 2)
        >>> struct2
        array([[ True,  True,  True],
               [ True,  True,  True],
               [ True,  True,  True]], dtype=bool)
        >>> ndimage.binary_dilation(a, structure=struct1).astype(a.dtype)
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> ndimage.binary_dilation(a, structure=struct2).astype(a.dtype)
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> ndimage.binary_dilation(a, structure=struct1,\
        ... iterations=2).astype(a.dtype)
        array([[ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 1.,  1.,  1.,  1.,  1.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  1.,  0.,  0.]])

    binary_erosion(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False)
        Multidimensional binary erosion with a given structuring element.

        Binary erosion is a mathematical morphology operation used for image
        processing.

        Parameters
        ----------
        input : array_like
            Binary image to be eroded. Non-zero (True) elements form
            the subset to be eroded.
        structure : array_like, optional
            Structuring element used for the erosion. Non-zero elements are
            considered True. If no structuring element is provided, an element
            is generated with a square connectivity equal to one.
        iterations : int, optional
            The erosion is repeated `iterations` times (one, by default).
            If iterations is less than 1, the erosion is repeated until the
            result does not change anymore.
        mask : array_like, optional
            If a mask is given, only those elements with a True value at
            the corresponding mask element are modified at each iteration.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        border_value : int (cast to 0 or 1), optional
            Value at the border in the output array.
        origin : int or tuple of ints, optional
            Placement of the filter, by default 0.
        brute_force : boolean, optional
            Memory condition: if False, only the pixels whose value was changed in
            the last iteration are tracked as candidates to be updated (eroded) in
            the current iteration; if True all pixels are considered as candidates
            for erosion, regardless of what happened in the previous iteration.
            False by default.

        Returns
        -------
        binary_erosion : ndarray of bools
            Erosion of the input by the structuring element.

        See Also
        --------
        grey_erosion, binary_dilation, binary_closing, binary_opening,
        generate_binary_structure

        Notes
        -----
        Erosion [1]_ is a mathematical morphology operation [2]_ that uses a
        structuring element for shrinking the shapes in an image. The binary
        erosion of an image by a structuring element is the locus of the points
        where a superimposition of the structuring element centered on the point
        is entirely contained in the set of non-zero elements of the image.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Erosion_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[1:6, 2:5] = 1
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.binary_erosion(a).astype(a.dtype)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> #Erosion removes objects smaller than the structure
        >>> ndimage.binary_erosion(a, structure=np.ones((5,5))).astype(a.dtype)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])

    binary_fill_holes(input, structure=None, output=None, origin=0)
        Fill the holes in binary objects.


        Parameters
        ----------
        input : array_like
            N-D binary array with holes to be filled
        structure : array_like, optional
            Structuring element used in the computation; large-size elements
            make computations faster but may miss holes separated from the
            background by thin regions. The default element (with a square
            connectivity equal to one) yields the intuitive result where all
            holes in the input have been filled.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        origin : int, tuple of ints, optional
            Position of the structuring element.

        Returns
        -------
        out : ndarray
            Transformation of the initial image `input` where holes have been
            filled.

        See Also
        --------
        binary_dilation, binary_propagation, label

        Notes
        -----
        The algorithm used in this function consists in invading the complementary
        of the shapes in `input` from the outer boundary of the image,
        using binary dilations. Holes are not connected to the boundary and are
        therefore not invaded. The result is the complementary subset of the
        invaded region.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Mathematical_morphology


        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((5, 5), dtype=int)
        >>> a[1:4, 1:4] = 1
        >>> a[2,2] = 0
        >>> a
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 0, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])
        >>> ndimage.binary_fill_holes(a).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])
        >>> # Too big structuring element
        >>> ndimage.binary_fill_holes(a, structure=np.ones((5,5))).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 0, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])

    binary_hit_or_miss(input, structure1=None, structure2=None, output=None, origin1=0, origin2=None)
        Multidimensional binary hit-or-miss transform.

        The hit-or-miss transform finds the locations of a given pattern
        inside the input image.

        Parameters
        ----------
        input : array_like (cast to booleans)
            Binary image where a pattern is to be detected.
        structure1 : array_like (cast to booleans), optional
            Part of the structuring element to be fitted to the foreground
            (non-zero elements) of `input`. If no value is provided, a
            structure of square connectivity 1 is chosen.
        structure2 : array_like (cast to booleans), optional
            Second part of the structuring element that has to miss completely
            the foreground. If no value is provided, the complementary of
            `structure1` is taken.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        origin1 : int or tuple of ints, optional
            Placement of the first part of the structuring element `structure1`,
            by default 0 for a centered structure.
        origin2 : int or tuple of ints, optional
            Placement of the second part of the structuring element `structure2`,
            by default 0 for a centered structure. If a value is provided for
            `origin1` and not for `origin2`, then `origin2` is set to `origin1`.

        Returns
        -------
        binary_hit_or_miss : ndarray
            Hit-or-miss transform of `input` with the given structuring
            element (`structure1`, `structure2`).

        See Also
        --------
        binary_erosion

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Hit-or-miss_transform

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[1, 1] = 1; a[2:4, 2:4] = 1; a[4:6, 4:6] = 1
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 0, 0, 0],
               [0, 0, 1, 1, 0, 0, 0],
               [0, 0, 0, 0, 1, 1, 0],
               [0, 0, 0, 0, 1, 1, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> structure1 = np.array([[1, 0, 0], [0, 1, 1], [0, 1, 1]])
        >>> structure1
        array([[1, 0, 0],
               [0, 1, 1],
               [0, 1, 1]])
        >>> # Find the matches of structure1 in the array a
        >>> ndimage.binary_hit_or_miss(a, structure1=structure1).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> # Change the origin of the filter
        >>> # origin1=1 is equivalent to origin1=(1,1) here
        >>> ndimage.binary_hit_or_miss(a, structure1=structure1,\
        ... origin1=1).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 1, 0],
               [0, 0, 0, 0, 0, 0, 0]])

    binary_opening(input, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False)
        Multidimensional binary opening with the given structuring element.

        The *opening* of an input image by a structuring element is the
        *dilation* of the *erosion* of the image by the structuring element.

        Parameters
        ----------
        input : array_like
            Binary array_like to be opened. Non-zero (True) elements form
            the subset to be opened.
        structure : array_like, optional
            Structuring element used for the opening. Non-zero elements are
            considered True. If no structuring element is provided an element
            is generated with a square connectivity equal to one (i.e., only
            nearest neighbors are connected to the center, diagonally-connected
            elements are not considered neighbors).
        iterations : int, optional
            The erosion step of the opening, then the dilation step are each
            repeated `iterations` times (one, by default). If `iterations` is
            less than 1, each operation is repeated until the result does
            not change anymore. Only an integer of iterations is accepted.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        origin : int or tuple of ints, optional
            Placement of the filter, by default 0.
        mask : array_like, optional
            If a mask is given, only those elements with a True value at
            the corresponding mask element are modified at each iteration.

            .. versionadded:: 1.1.0
        border_value : int (cast to 0 or 1), optional
            Value at the border in the output array.

            .. versionadded:: 1.1.0
        brute_force : boolean, optional
            Memory condition: if False, only the pixels whose value was changed in
            the last iteration are tracked as candidates to be updated in the
            current iteration; if true all pixels are considered as candidates for
            update, regardless of what happened in the previous iteration.
            False by default.

            .. versionadded:: 1.1.0

        Returns
        -------
        binary_opening : ndarray of bools
            Opening of the input by the structuring element.

        See Also
        --------
        grey_opening, binary_closing, binary_erosion, binary_dilation,
        generate_binary_structure

        Notes
        -----
        *Opening* [1]_ is a mathematical morphology operation [2]_ that
        consists in the succession of an erosion and a dilation of the
        input with the same structuring element. Opening, therefore, removes
        objects smaller than the structuring element.

        Together with *closing* (`binary_closing`), opening can be used for
        noise removal.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Opening_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((5,5), dtype=int)
        >>> a[1:4, 1:4] = 1; a[4, 4] = 1
        >>> a
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 1]])
        >>> # Opening removes small objects
        >>> ndimage.binary_opening(a, structure=np.ones((3,3))).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0]])
        >>> # Opening can also smooth corners
        >>> ndimage.binary_opening(a).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0]])
        >>> # Opening is the dilation of the erosion of the input
        >>> ndimage.binary_erosion(a).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0]])
        >>> ndimage.binary_dilation(ndimage.binary_erosion(a)).astype(int)
        array([[0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0],
               [0, 1, 1, 1, 0],
               [0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0]])

    binary_propagation(input, structure=None, mask=None, output=None, border_value=0, origin=0)
        Multidimensional binary propagation with the given structuring element.

        Parameters
        ----------
        input : array_like
            Binary image to be propagated inside `mask`.
        structure : array_like, optional
            Structuring element used in the successive dilations. The output
            may depend on the structuring element, especially if `mask` has
            several connex components. If no structuring element is
            provided, an element is generated with a squared connectivity equal
            to one.
        mask : array_like, optional
            Binary mask defining the region into which `input` is allowed to
            propagate.
        output : ndarray, optional
            Array of the same shape as input, into which the output is placed.
            By default, a new array is created.
        border_value : int (cast to 0 or 1), optional
            Value at the border in the output array.
        origin : int or tuple of ints, optional
            Placement of the filter, by default 0.

        Returns
        -------
        binary_propagation : ndarray
            Binary propagation of `input` inside `mask`.

        Notes
        -----
        This function is functionally equivalent to calling binary_dilation
        with the number of iterations less than one: iterative dilation until
        the result does not change anymore.

        The succession of an erosion and propagation inside the original image
        can be used instead of an *opening* for deleting small objects while
        keeping the contours of larger objects untouched.

        References
        ----------
        .. [1] http://cmm.ensmp.fr/~serra/cours/pdf/en/ch6en.pdf, slide 15.
        .. [2] I.T. Young, J.J. Gerbrands, and L.J. van Vliet, "Fundamentals of
            image processing", 1998
            ftp://qiftp.tudelft.nl/DIPimage/docs/FIP2.3.pdf

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> input = np.zeros((8, 8), dtype=int)
        >>> input[2, 2] = 1
        >>> mask = np.zeros((8, 8), dtype=int)
        >>> mask[1:4, 1:4] = mask[4, 4]  = mask[6:8, 6:8] = 1
        >>> input
        array([[0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0]])
        >>> mask
        array([[0, 0, 0, 0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 1, 1],
               [0, 0, 0, 0, 0, 0, 1, 1]])
        >>> ndimage.binary_propagation(input, mask=mask).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.binary_propagation(input, mask=mask,\
        ... structure=np.ones((3,3))).astype(int)
        array([[0, 0, 0, 0, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 1, 1, 1, 0, 0, 0, 0],
               [0, 0, 0, 0, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0]])

        >>> # Comparison between opening and erosion+propagation
        >>> a = np.zeros((6,6), dtype=int)
        >>> a[2:5, 2:5] = 1; a[0, 0] = 1; a[5, 5] = 1
        >>> a
        array([[1, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0, 1]])
        >>> ndimage.binary_opening(a).astype(int)
        array([[0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0, 0]])
        >>> b = ndimage.binary_erosion(a)
        >>> b.astype(int)
        array([[0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0]])
        >>> ndimage.binary_propagation(b, mask=a).astype(int)
        array([[0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 1, 1, 1, 0],
               [0, 0, 0, 0, 0, 0]])

    black_tophat(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional black tophat filter.

        Parameters
        ----------
        input : array_like
            Input.
        size : tuple of ints, optional
            Shape of a flat and full structuring element used for the filter.
            Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the black tophat filter.
        structure : array of ints, optional
            Structuring element used for the filter. `structure` may be a non-flat
            structuring element. The `structure` array applies offsets to the
            pixels in a neighborhood (the offset is additive during dilation and
            subtractive during erosion)
        output : array, optional
            An array used for storing the output of the filter may be provided.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        black_tophat : ndarray
            Result of the filter of `input` with `structure`.

        See Also
        --------
        white_tophat, grey_opening, grey_closing

        Examples
        --------
        Change dark peak to bright peak and subtract background.

        >>> from scipy.ndimage import generate_binary_structure, black_tophat
        >>> import numpy as np
        >>> square = generate_binary_structure(rank=2, connectivity=3)
        >>> dark_on_gray = np.array([[7, 6, 6, 6, 7],
        ...                          [6, 5, 4, 5, 6],
        ...                          [6, 4, 0, 4, 6],
        ...                          [6, 5, 4, 5, 6],
        ...                          [7, 6, 6, 6, 7]])
        >>> black_tophat(input=dark_on_gray, structure=square)
        array([[0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0],
               [0, 1, 5, 1, 0],
               [0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0]])

    center_of_mass(input, labels=None, index=None)
        Calculate the center of mass of the values of an array at labels.

        Parameters
        ----------
        input : ndarray
            Data from which to calculate center-of-mass. The masses can either
            be positive or negative.
        labels : ndarray, optional
            Labels for objects in `input`, as generated by `ndimage.label`.
            Only used with `index`. Dimensions must be the same as `input`.
        index : int or sequence of ints, optional
            Labels for which to calculate centers-of-mass. If not specified,
            the combined center of mass of all labels greater than zero
            will be calculated. Only used with `labels`.

        Returns
        -------
        center_of_mass : tuple, or list of tuples
            Coordinates of centers-of-mass.

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array(([0,0,0,0],
        ...               [0,1,1,0],
        ...               [0,1,1,0],
        ...               [0,1,1,0]))
        >>> from scipy import ndimage
        >>> ndimage.center_of_mass(a)
        (2.0, 1.5)

        Calculation of multiple objects in an image

        >>> b = np.array(([0,1,1,0],
        ...               [0,1,0,0],
        ...               [0,0,0,0],
        ...               [0,0,1,1],
        ...               [0,0,1,1]))
        >>> lbl = ndimage.label(b)[0]
        >>> ndimage.center_of_mass(b, lbl, [1,2])
        [(0.33333333333333331, 1.3333333333333333), (3.5, 2.5)]

        Negative masses are also accepted, which can occur for example when
        bias is removed from measured data due to random noise.

        >>> c = np.array(([-1,0,0,0],
        ...               [0,-1,-1,0],
        ...               [0,1,-1,0],
        ...               [0,1,1,0]))
        >>> ndimage.center_of_mass(c)
        (-4.0, 1.0)

        If there are division by zero issues, the function does not raise an
        error but rather issues a RuntimeWarning before returning inf and/or NaN.

        >>> d = np.array([-1, 1])
        >>> ndimage.center_of_mass(d)
        (inf,)

    convolve(input, weights, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional convolution.

        The array is convolved with the given kernel.

        Parameters
        ----------
        input : array_like
            The input array.
        weights : array_like
            Array of weights, same number of dimensions as input
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0
        origin : int, optional
            Controls the origin of the input signal, which is where the
            filter is centered to produce the first element of the output.
            Positive values shift the filter to the right, and negative values
            shift the filter to the left. Default is 0.

        Returns
        -------
        result : ndarray
            The result of convolution of `input` with `weights`.

        See Also
        --------
        correlate : Correlate an image with a kernel.

        Notes
        -----
        Each value in result is :math:`C_i = \sum_j{I_{i+k-j} W_j}`, where
        W is the `weights` kernel,
        j is the N-D spatial index over :math:`W`,
        I is the `input` and k is the coordinate of the center of
        W, specified by `origin` in the input parameters.

        Examples
        --------
        Perhaps the simplest case to understand is ``mode='constant', cval=0.0``,
        because in this case borders (i.e., where the `weights` kernel, centered
        on any one value, extends beyond an edge of `input`) are treated as zeros.

        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> k = np.array([[1,1,1],[1,1,0],[1,0,0]])
        >>> from scipy import ndimage
        >>> ndimage.convolve(a, k, mode='constant', cval=0.0)
        array([[11, 10,  7,  4],
               [10,  3, 11, 11],
               [15, 12, 14,  7],
               [12,  3,  7,  0]])

        Setting ``cval=1.0`` is equivalent to padding the outer edge of `input`
        with 1.0's (and then extracting only the original region of the result).

        >>> ndimage.convolve(a, k, mode='constant', cval=1.0)
        array([[13, 11,  8,  7],
               [11,  3, 11, 14],
               [16, 12, 14, 10],
               [15,  6, 10,  5]])

        With ``mode='reflect'`` (the default), outer values are reflected at the
        edge of `input` to fill in missing values.

        >>> b = np.array([[2, 0, 0],
        ...               [1, 0, 0],
        ...               [0, 0, 0]])
        >>> k = np.array([[0,1,0], [0,1,0], [0,1,0]])
        >>> ndimage.convolve(b, k, mode='reflect')
        array([[5, 0, 0],
               [3, 0, 0],
               [1, 0, 0]])

        This includes diagonally at the corners.

        >>> k = np.array([[1,0,0],[0,1,0],[0,0,1]])
        >>> ndimage.convolve(b, k)
        array([[4, 2, 0],
               [3, 2, 0],
               [1, 1, 0]])

        With ``mode='nearest'``, the single nearest value in to an edge in
        `input` is repeated as many times as needed to match the overlapping
        `weights`.

        >>> c = np.array([[2, 0, 1],
        ...               [1, 0, 0],
        ...               [0, 0, 0]])
        >>> k = np.array([[0, 1, 0],
        ...               [0, 1, 0],
        ...               [0, 1, 0],
        ...               [0, 1, 0],
        ...               [0, 1, 0]])
        >>> ndimage.convolve(c, k, mode='nearest')
        array([[7, 0, 3],
               [5, 0, 2],
               [3, 0, 1]])

    convolve1d(input, weights, axis=-1, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a 1-D convolution along the given axis.

        The lines of the array along the given axis are convolved with the
        given weights.

        Parameters
        ----------
        input : array_like
            The input array.
        weights : ndarray
            1-D sequence of numbers.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.

        Returns
        -------
        convolve1d : ndarray
            Convolved array with same shape as input

        Examples
        --------
        >>> from scipy.ndimage import convolve1d
        >>> convolve1d([2, 8, 0, 4, 1, 9, 9, 0], weights=[1, 3])
        array([14, 24,  4, 13, 12, 36, 27,  0])

    correlate(input, weights, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional correlation.

        The array is correlated with the given kernel.

        Parameters
        ----------
        input : array_like
            The input array.
        weights : ndarray
            array of weights, same number of dimensions as input
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.

        Returns
        -------
        result : ndarray
            The result of correlation of `input` with `weights`.

        See Also
        --------
        convolve : Convolve an image with a kernel.

        Examples
        --------
        Correlation is the process of moving a filter mask often referred to
        as kernel over the image and computing the sum of products at each location.

        >>> from scipy.ndimage import correlate
        >>> import numpy as np
        >>> input_img = np.arange(25).reshape(5,5)
        >>> print(input_img)
        [[ 0  1  2  3  4]
        [ 5  6  7  8  9]
        [10 11 12 13 14]
        [15 16 17 18 19]
        [20 21 22 23 24]]

        Define a kernel (weights) for correlation. In this example, it is for sum of
        center and up, down, left and right next elements.

        >>> weights = [[0, 1, 0],
        ...            [1, 1, 1],
        ...            [0, 1, 0]]

        We can calculate a correlation result:
        For example, element ``[2,2]`` is ``7 + 11 + 12 + 13 + 17 = 60``.

        >>> correlate(input_img, weights)
        array([[  6,  10,  15,  20,  24],
            [ 26,  30,  35,  40,  44],
            [ 51,  55,  60,  65,  69],
            [ 76,  80,  85,  90,  94],
            [ 96, 100, 105, 110, 114]])

    correlate1d(input, weights, axis=-1, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a 1-D correlation along the given axis.

        The lines of the array along the given axis are correlated with the
        given weights.

        Parameters
        ----------
        input : array_like
            The input array.
        weights : array
            1-D sequence of numbers.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.

        Returns
        -------
        result : ndarray
            Correlation result. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy.ndimage import correlate1d
        >>> correlate1d([2, 8, 0, 4, 1, 9, 9, 0], weights=[1, 3])
        array([ 8, 26,  8, 12,  7, 28, 36,  9])

    distance_transform_bf(input, metric='euclidean', sampling=None, return_distances=True, return_indices=False, distances=None, indices=None)
        Distance transform function by a brute force algorithm.

        This function calculates the distance transform of the `input`, by
        replacing each foreground (non-zero) element, with its
        shortest distance to the background (any zero-valued element).

        In addition to the distance transform, the feature transform can
        be calculated. In this case the index of the closest background
        element to each foreground element is returned in a separate array.

        Parameters
        ----------
        input : array_like
            Input
        metric : {'euclidean', 'taxicab', 'chessboard'}, optional
            'cityblock' and 'manhattan' are also valid, and map to 'taxicab'.
            The default is 'euclidean'.
        sampling : float, or sequence of float, optional
            This parameter is only used when `metric` is 'euclidean'.
            Spacing of elements along each dimension. If a sequence, must be of
            length equal to the input rank; if a single number, this is used for
            all axes. If not specified, a grid spacing of unity is implied.
        return_distances : bool, optional
            Whether to calculate the distance transform.
            Default is True.
        return_indices : bool, optional
            Whether to calculate the feature transform.
            Default is False.
        distances : ndarray, optional
            An output array to store the calculated distance transform, instead of
            returning it.
            `return_distances` must be True.
            It must be the same shape as `input`, and of type float64 if `metric`
            is 'euclidean', uint32 otherwise.
        indices : int32 ndarray, optional
            An output array to store the calculated feature transform, instead of
            returning it.
            `return_indicies` must be True.
            Its shape must be `(input.ndim,) + input.shape`.

        Returns
        -------
        distances : ndarray, optional
            The calculated distance transform. Returned only when
            `return_distances` is True and `distances` is not supplied.
            It will have the same shape as the input array.
        indices : int32 ndarray, optional
            The calculated feature transform. It has an input-shaped array for each
            dimension of the input. See distance_transform_edt documentation for an
            example.
            Returned only when `return_indices` is True and `indices` is not
            supplied.

        See Also
        --------
        distance_transform_cdt : Faster distance transform for taxicab and
                                 chessboard metrics
        distance_transform_edt : Faster distance transform for euclidean metric

        Notes
        -----
        This function employs a slow brute force algorithm. See also the
        function `distance_transform_cdt` for more efficient taxicab [1]_ and
        chessboard algorithms [2]_.

        References
        ----------
        .. [1] Taxicab distance. Wikipedia, 2023.
               https://en.wikipedia.org/wiki/Taxicab_geometry
        .. [2] Chessboard distance. Wikipedia, 2023.
               https://en.wikipedia.org/wiki/Chebyshev_distance

        Examples
        --------
        Import the necessary modules.

        >>> import numpy as np
        >>> from scipy.ndimage import distance_transform_bf
        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.axes_grid1 import ImageGrid

        First, we create a toy binary image.

        >>> def add_circle(center_x, center_y, radius, image, fillvalue=1):
        ...     # fill circular area with 1
        ...     xx, yy = np.mgrid[:image.shape[0], :image.shape[1]]
        ...     circle = (xx - center_x) ** 2 + (yy - center_y) ** 2
        ...     circle_shape = np.sqrt(circle) < radius
        ...     image[circle_shape] = fillvalue
        ...     return image
        >>> image = np.zeros((100, 100), dtype=np.uint8)
        >>> image[35:65, 20:80] = 1
        >>> image = add_circle(28, 65, 10, image)
        >>> image = add_circle(37, 30, 10, image)
        >>> image = add_circle(70, 45, 20, image)
        >>> image = add_circle(45, 80, 10, image)

        Next, we set up the figure.

        >>> fig = plt.figure(figsize=(8, 8))  # set up the figure structure
        >>> grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=(0.4, 0.3),
        ...                  label_mode="1", share_all=True,
        ...                  cbar_location="right", cbar_mode="each",
        ...                  cbar_size="7%", cbar_pad="2%")
        >>> for ax in grid:
        ...     ax.axis('off')  # remove axes from images

        The top left image is the original binary image.

        >>> binary_image = grid[0].imshow(image, cmap='gray')
        >>> cbar_binary_image = grid.cbar_axes[0].colorbar(binary_image)
        >>> cbar_binary_image.set_ticks([0, 1])
        >>> grid[0].set_title("Binary image: foreground in white")

        The distance transform calculates the distance between foreground pixels
        and the image background according to a distance metric. Available metrics
        in `distance_transform_bf` are: ``euclidean`` (default), ``taxicab``
        and ``chessboard``. The top right image contains the distance transform
        based on the ``euclidean`` metric.

        >>> distance_transform_euclidean = distance_transform_bf(image)
        >>> euclidean_transform = grid[1].imshow(distance_transform_euclidean,
        ...                                      cmap='gray')
        >>> cbar_euclidean = grid.cbar_axes[1].colorbar(euclidean_transform)
        >>> colorbar_ticks = [0, 10, 20]
        >>> cbar_euclidean.set_ticks(colorbar_ticks)
        >>> grid[1].set_title("Euclidean distance")

        The lower left image contains the distance transform using the ``taxicab``
        metric.

        >>> distance_transform_taxicab = distance_transform_bf(image,
        ...                                                    metric='taxicab')
        >>> taxicab_transformation = grid[2].imshow(distance_transform_taxicab,
        ...                                         cmap='gray')
        >>> cbar_taxicab = grid.cbar_axes[2].colorbar(taxicab_transformation)
        >>> cbar_taxicab.set_ticks(colorbar_ticks)
        >>> grid[2].set_title("Taxicab distance")

        Finally, the lower right image contains the distance transform using the
        ``chessboard`` metric.

        >>> distance_transform_cb = distance_transform_bf(image,
        ...                                               metric='chessboard')
        >>> chessboard_transformation = grid[3].imshow(distance_transform_cb,
        ...                                            cmap='gray')
        >>> cbar_taxicab = grid.cbar_axes[3].colorbar(chessboard_transformation)
        >>> cbar_taxicab.set_ticks(colorbar_ticks)
        >>> grid[3].set_title("Chessboard distance")
        >>> plt.show()

    distance_transform_cdt(input, metric='chessboard', return_distances=True, return_indices=False, distances=None, indices=None)
        Distance transform for chamfer type of transforms.

        This function calculates the distance transform of the `input`, by
        replacing each foreground (non-zero) element, with its
        shortest distance to the background (any zero-valued element).

        In addition to the distance transform, the feature transform can
        be calculated. In this case the index of the closest background
        element to each foreground element is returned in a separate array.

        Parameters
        ----------
        input : array_like
            Input. Values of 0 are treated as background.
        metric : {'chessboard', 'taxicab'} or array_like, optional
            The `metric` determines the type of chamfering that is done. If the
            `metric` is equal to 'taxicab' a structure is generated using
            `generate_binary_structure` with a squared distance equal to 1. If
            the `metric` is equal to 'chessboard', a `metric` is generated
            using `generate_binary_structure` with a squared distance equal to
            the dimensionality of the array. These choices correspond to the
            common interpretations of the 'taxicab' and the 'chessboard'
            distance metrics in two dimensions.
            A custom metric may be provided, in the form of a matrix where
            each dimension has a length of three.
            'cityblock' and 'manhattan' are also valid, and map to 'taxicab'.
            The default is 'chessboard'.
        return_distances : bool, optional
            Whether to calculate the distance transform.
            Default is True.
        return_indices : bool, optional
            Whether to calculate the feature transform.
            Default is False.
        distances : int32 ndarray, optional
            An output array to store the calculated distance transform, instead of
            returning it.
            `return_distances` must be True.
            It must be the same shape as `input`.
        indices : int32 ndarray, optional
            An output array to store the calculated feature transform, instead of
            returning it.
            `return_indicies` must be True.
            Its shape must be `(input.ndim,) + input.shape`.

        Returns
        -------
        distances : int32 ndarray, optional
            The calculated distance transform. Returned only when
            `return_distances` is True, and `distances` is not supplied.
            It will have the same shape as the input array.
        indices : int32 ndarray, optional
            The calculated feature transform. It has an input-shaped array for each
            dimension of the input. See distance_transform_edt documentation for an
            example.
            Returned only when `return_indices` is True, and `indices` is not
            supplied.

        See Also
        --------
        distance_transform_edt : Fast distance transform for euclidean metric
        distance_transform_bf : Distance transform for different metrics using
                                a slower brute force algorithm

        Examples
        --------
        Import the necessary modules.

        >>> import numpy as np
        >>> from scipy.ndimage import distance_transform_cdt
        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.axes_grid1 import ImageGrid

        First, we create a toy binary image.

        >>> def add_circle(center_x, center_y, radius, image, fillvalue=1):
        ...     # fill circular area with 1
        ...     xx, yy = np.mgrid[:image.shape[0], :image.shape[1]]
        ...     circle = (xx - center_x) ** 2 + (yy - center_y) ** 2
        ...     circle_shape = np.sqrt(circle) < radius
        ...     image[circle_shape] = fillvalue
        ...     return image
        >>> image = np.zeros((100, 100), dtype=np.uint8)
        >>> image[35:65, 20:80] = 1
        >>> image = add_circle(28, 65, 10, image)
        >>> image = add_circle(37, 30, 10, image)
        >>> image = add_circle(70, 45, 20, image)
        >>> image = add_circle(45, 80, 10, image)

        Next, we set up the figure.

        >>> fig = plt.figure(figsize=(5, 15))
        >>> grid = ImageGrid(fig, 111, nrows_ncols=(3, 1), axes_pad=(0.5, 0.3),
        ...                  label_mode="1", share_all=True,
        ...                  cbar_location="right", cbar_mode="each",
        ...                  cbar_size="7%", cbar_pad="2%")
        >>> for ax in grid:
        ...     ax.axis('off')
        >>> top, middle, bottom = grid
        >>> colorbar_ticks = [0, 10, 20]

        The top image contains the original binary image.

        >>> binary_image = top.imshow(image, cmap='gray')
        >>> cbar_binary_image = top.cax.colorbar(binary_image)
        >>> cbar_binary_image.set_ticks([0, 1])
        >>> top.set_title("Binary image: foreground in white")

        The middle image contains the distance transform using the ``taxicab``
        metric.

        >>> distance_taxicab = distance_transform_cdt(image, metric="taxicab")
        >>> taxicab_transform = middle.imshow(distance_taxicab, cmap='gray')
        >>> cbar_taxicab = middle.cax.colorbar(taxicab_transform)
        >>> cbar_taxicab.set_ticks(colorbar_ticks)
        >>> middle.set_title("Taxicab metric")

        The bottom image contains the distance transform using the ``chessboard``
        metric.

        >>> distance_chessboard = distance_transform_cdt(image,
        ...                                              metric="chessboard")
        >>> chessboard_transform = bottom.imshow(distance_chessboard, cmap='gray')
        >>> cbar_chessboard = bottom.cax.colorbar(chessboard_transform)
        >>> cbar_chessboard.set_ticks(colorbar_ticks)
        >>> bottom.set_title("Chessboard metric")
        >>> plt.tight_layout()
        >>> plt.show()

    distance_transform_edt(input, sampling=None, return_distances=True, return_indices=False, distances=None, indices=None)
        Exact Euclidean distance transform.

        This function calculates the distance transform of the `input`, by
        replacing each foreground (non-zero) element, with its
        shortest distance to the background (any zero-valued element).

        In addition to the distance transform, the feature transform can
        be calculated. In this case the index of the closest background
        element to each foreground element is returned in a separate array.

        Parameters
        ----------
        input : array_like
            Input data to transform. Can be any type but will be converted
            into binary: 1 wherever input equates to True, 0 elsewhere.
        sampling : float, or sequence of float, optional
            Spacing of elements along each dimension. If a sequence, must be of
            length equal to the input rank; if a single number, this is used for
            all axes. If not specified, a grid spacing of unity is implied.
        return_distances : bool, optional
            Whether to calculate the distance transform.
            Default is True.
        return_indices : bool, optional
            Whether to calculate the feature transform.
            Default is False.
        distances : float64 ndarray, optional
            An output array to store the calculated distance transform, instead of
            returning it.
            `return_distances` must be True.
            It must be the same shape as `input`.
        indices : int32 ndarray, optional
            An output array to store the calculated feature transform, instead of
            returning it.
            `return_indicies` must be True.
            Its shape must be `(input.ndim,) + input.shape`.

        Returns
        -------
        distances : float64 ndarray, optional
            The calculated distance transform. Returned only when
            `return_distances` is True and `distances` is not supplied.
            It will have the same shape as the input array.
        indices : int32 ndarray, optional
            The calculated feature transform. It has an input-shaped array for each
            dimension of the input. See example below.
            Returned only when `return_indices` is True and `indices` is not
            supplied.

        Notes
        -----
        The Euclidean distance transform gives values of the Euclidean
        distance::

                        n
          y_i = sqrt(sum (x[i]-b[i])**2)
                        i

        where b[i] is the background point (value 0) with the smallest
        Euclidean distance to input points x[i], and n is the
        number of dimensions.

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.array(([0,1,1,1,1],
        ...               [0,0,1,1,1],
        ...               [0,1,1,1,1],
        ...               [0,1,1,1,0],
        ...               [0,1,1,0,0]))
        >>> ndimage.distance_transform_edt(a)
        array([[ 0.    ,  1.    ,  1.4142,  2.2361,  3.    ],
               [ 0.    ,  0.    ,  1.    ,  2.    ,  2.    ],
               [ 0.    ,  1.    ,  1.4142,  1.4142,  1.    ],
               [ 0.    ,  1.    ,  1.4142,  1.    ,  0.    ],
               [ 0.    ,  1.    ,  1.    ,  0.    ,  0.    ]])

        With a sampling of 2 units along x, 1 along y:

        >>> ndimage.distance_transform_edt(a, sampling=[2,1])
        array([[ 0.    ,  1.    ,  2.    ,  2.8284,  3.6056],
               [ 0.    ,  0.    ,  1.    ,  2.    ,  3.    ],
               [ 0.    ,  1.    ,  2.    ,  2.2361,  2.    ],
               [ 0.    ,  1.    ,  2.    ,  1.    ,  0.    ],
               [ 0.    ,  1.    ,  1.    ,  0.    ,  0.    ]])

        Asking for indices as well:

        >>> edt, inds = ndimage.distance_transform_edt(a, return_indices=True)
        >>> inds
        array([[[0, 0, 1, 1, 3],
                [1, 1, 1, 1, 3],
                [2, 2, 1, 3, 3],
                [3, 3, 4, 4, 3],
                [4, 4, 4, 4, 4]],
               [[0, 0, 1, 1, 4],
                [0, 1, 1, 1, 4],
                [0, 0, 1, 4, 4],
                [0, 0, 3, 3, 4],
                [0, 0, 3, 3, 4]]])

        With arrays provided for inplace outputs:

        >>> indices = np.zeros(((np.ndim(a),) + a.shape), dtype=np.int32)
        >>> ndimage.distance_transform_edt(a, return_indices=True, indices=indices)
        array([[ 0.    ,  1.    ,  1.4142,  2.2361,  3.    ],
               [ 0.    ,  0.    ,  1.    ,  2.    ,  2.    ],
               [ 0.    ,  1.    ,  1.4142,  1.4142,  1.    ],
               [ 0.    ,  1.    ,  1.4142,  1.    ,  0.    ],
               [ 0.    ,  1.    ,  1.    ,  0.    ,  0.    ]])
        >>> indices
        array([[[0, 0, 1, 1, 3],
                [1, 1, 1, 1, 3],
                [2, 2, 1, 3, 3],
                [3, 3, 4, 4, 3],
                [4, 4, 4, 4, 4]],
               [[0, 0, 1, 1, 4],
                [0, 1, 1, 1, 4],
                [0, 0, 1, 4, 4],
                [0, 0, 3, 3, 4],
                [0, 0, 3, 3, 4]]])

    extrema(input, labels=None, index=None)
        Calculate the minimums and maximums of the values of an array
        at labels, along with their positions.

        Parameters
        ----------
        input : ndarray
            N-D image data to process.
        labels : ndarray, optional
            Labels of features in input.
            If not None, must be same shape as `input`.
        index : int or sequence of ints, optional
            Labels to include in output.  If None (default), all values where
            non-zero `labels` are used.

        Returns
        -------
        minimums, maximums : int or ndarray
            Values of minimums and maximums in each feature.
        min_positions, max_positions : tuple or list of tuples
            Each tuple gives the N-D coordinates of the corresponding minimum
            or maximum.

        See Also
        --------
        maximum, minimum, maximum_position, minimum_position, center_of_mass

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> from scipy import ndimage
        >>> ndimage.extrema(a)
        (0, 9, (0, 2), (3, 0))

        Features to process can be specified using `labels` and `index`:

        >>> lbl, nlbl = ndimage.label(a)
        >>> ndimage.extrema(a, lbl, index=np.arange(1, nlbl+1))
        (array([1, 4, 3]),
         array([5, 7, 9]),
         [(0, 0), (1, 3), (3, 1)],
         [(1, 0), (2, 3), (3, 0)])

        If no index is given, non-zero `labels` are processed:

        >>> ndimage.extrema(a, lbl)
        (1, 9, (0, 0), (3, 0))

    find_objects(input, max_label=0)
        Find objects in a labeled array.

        Parameters
        ----------
        input : ndarray of ints
            Array containing objects defined by different labels. Labels with
            value 0 are ignored.
        max_label : int, optional
            Maximum label to be searched for in `input`. If max_label is not
            given, the positions of all objects are returned.

        Returns
        -------
        object_slices : list of tuples
            A list of tuples, with each tuple containing N slices (with N the
            dimension of the input array). Slices correspond to the minimal
            parallelepiped that contains the object. If a number is missing,
            None is returned instead of a slice. The label ``l`` corresponds to
            the index ``l-1`` in the returned list.

        See Also
        --------
        label, center_of_mass

        Notes
        -----
        This function is very useful for isolating a volume of interest inside
        a 3-D array, that cannot be "seen through".

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((6,6), dtype=int)
        >>> a[2:4, 2:4] = 1
        >>> a[4, 4] = 1
        >>> a[:2, :3] = 2
        >>> a[0, 5] = 3
        >>> a
        array([[2, 2, 2, 0, 0, 3],
               [2, 2, 2, 0, 0, 0],
               [0, 0, 1, 1, 0, 0],
               [0, 0, 1, 1, 0, 0],
               [0, 0, 0, 0, 1, 0],
               [0, 0, 0, 0, 0, 0]])
        >>> ndimage.find_objects(a)
        [(slice(2, 5, None), slice(2, 5, None)),
         (slice(0, 2, None), slice(0, 3, None)),
         (slice(0, 1, None), slice(5, 6, None))]
        >>> ndimage.find_objects(a, max_label=2)
        [(slice(2, 5, None), slice(2, 5, None)), (slice(0, 2, None), slice(0, 3, None))]
        >>> ndimage.find_objects(a == 1, max_label=2)
        [(slice(2, 5, None), slice(2, 5, None)), None]

        >>> loc = ndimage.find_objects(a)[0]
        >>> a[loc]
        array([[1, 1, 0],
               [1, 1, 0],
               [0, 0, 1]])

    fourier_ellipsoid(input, size, n=-1, axis=-1, output=None)
        Multidimensional ellipsoid Fourier filter.

        The array is multiplied with the fourier transform of an ellipsoid of
        given sizes.

        Parameters
        ----------
        input : array_like
            The input array.
        size : float or sequence
            The size of the box used for filtering.
            If a float, `size` is the same for all axes. If a sequence, `size` has
            to contain one value for each axis.
        n : int, optional
            If `n` is negative (default), then the input is assumed to be the
            result of a complex fft.
            If `n` is larger than or equal to zero, the input is assumed to be the
            result of a real fft, and `n` gives the length of the array before
            transformation along the real transform direction.
        axis : int, optional
            The axis of the real transform.
        output : ndarray, optional
            If given, the result of filtering the input is placed in this array.

        Returns
        -------
        fourier_ellipsoid : ndarray
            The filtered input.

        Notes
        -----
        This function is implemented for arrays of rank 1, 2, or 3.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import numpy.fft
        >>> import matplotlib.pyplot as plt
        >>> fig, (ax1, ax2) = plt.subplots(1, 2)
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ascent = datasets.ascent()
        >>> input_ = numpy.fft.fft2(ascent)
        >>> result = ndimage.fourier_ellipsoid(input_, size=20)
        >>> result = numpy.fft.ifft2(result)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result.real)  # the imaginary part is an artifact
        >>> plt.show()

    fourier_gaussian(input, sigma, n=-1, axis=-1, output=None)
        Multidimensional Gaussian fourier filter.

        The array is multiplied with the fourier transform of a Gaussian
        kernel.

        Parameters
        ----------
        input : array_like
            The input array.
        sigma : float or sequence
            The sigma of the Gaussian kernel. If a float, `sigma` is the same for
            all axes. If a sequence, `sigma` has to contain one value for each
            axis.
        n : int, optional
            If `n` is negative (default), then the input is assumed to be the
            result of a complex fft.
            If `n` is larger than or equal to zero, the input is assumed to be the
            result of a real fft, and `n` gives the length of the array before
            transformation along the real transform direction.
        axis : int, optional
            The axis of the real transform.
        output : ndarray, optional
            If given, the result of filtering the input is placed in this array.

        Returns
        -------
        fourier_gaussian : ndarray
            The filtered input.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import numpy.fft
        >>> import matplotlib.pyplot as plt
        >>> fig, (ax1, ax2) = plt.subplots(1, 2)
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ascent = datasets.ascent()
        >>> input_ = numpy.fft.fft2(ascent)
        >>> result = ndimage.fourier_gaussian(input_, sigma=4)
        >>> result = numpy.fft.ifft2(result)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result.real)  # the imaginary part is an artifact
        >>> plt.show()

    fourier_shift(input, shift, n=-1, axis=-1, output=None)
        Multidimensional Fourier shift filter.

        The array is multiplied with the Fourier transform of a shift operation.

        Parameters
        ----------
        input : array_like
            The input array.
        shift : float or sequence
            The size of the box used for filtering.
            If a float, `shift` is the same for all axes. If a sequence, `shift`
            has to contain one value for each axis.
        n : int, optional
            If `n` is negative (default), then the input is assumed to be the
            result of a complex fft.
            If `n` is larger than or equal to zero, the input is assumed to be the
            result of a real fft, and `n` gives the length of the array before
            transformation along the real transform direction.
        axis : int, optional
            The axis of the real transform.
        output : ndarray, optional
            If given, the result of shifting the input is placed in this array.

        Returns
        -------
        fourier_shift : ndarray
            The shifted input.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> import numpy.fft
        >>> fig, (ax1, ax2) = plt.subplots(1, 2)
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ascent = datasets.ascent()
        >>> input_ = numpy.fft.fft2(ascent)
        >>> result = ndimage.fourier_shift(input_, shift=200)
        >>> result = numpy.fft.ifft2(result)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result.real)  # the imaginary part is an artifact
        >>> plt.show()

    fourier_uniform(input, size, n=-1, axis=-1, output=None)
        Multidimensional uniform fourier filter.

        The array is multiplied with the Fourier transform of a box of given
        size.

        Parameters
        ----------
        input : array_like
            The input array.
        size : float or sequence
            The size of the box used for filtering.
            If a float, `size` is the same for all axes. If a sequence, `size` has
            to contain one value for each axis.
        n : int, optional
            If `n` is negative (default), then the input is assumed to be the
            result of a complex fft.
            If `n` is larger than or equal to zero, the input is assumed to be the
            result of a real fft, and `n` gives the length of the array before
            transformation along the real transform direction.
        axis : int, optional
            The axis of the real transform.
        output : ndarray, optional
            If given, the result of filtering the input is placed in this array.

        Returns
        -------
        fourier_uniform : ndarray
            The filtered input.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import numpy.fft
        >>> import matplotlib.pyplot as plt
        >>> fig, (ax1, ax2) = plt.subplots(1, 2)
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ascent = datasets.ascent()
        >>> input_ = numpy.fft.fft2(ascent)
        >>> result = ndimage.fourier_uniform(input_, size=20)
        >>> result = numpy.fft.ifft2(result)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result.real)  # the imaginary part is an artifact
        >>> plt.show()

    gaussian_filter(input, sigma, order=0, output=None, mode='reflect', cval=0.0, truncate=4.0, *, radius=None, axes=None)
        Multidimensional Gaussian filter.

        Parameters
        ----------
        input : array_like
            The input array.
        sigma : scalar or sequence of scalars
            Standard deviation for Gaussian kernel. The standard
            deviations of the Gaussian filter are given for each axis as a
            sequence, or as a single number, in which case it is equal for
            all axes.
        order : int or sequence of ints, optional
            The order of the filter along each axis is given as a sequence
            of integers, or as a single number. An order of 0 corresponds
            to convolution with a Gaussian kernel. A positive order
            corresponds to convolution with that derivative of a Gaussian.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        truncate : float, optional
            Truncate the filter at this many standard deviations.
            Default is 4.0.
        radius : None or int or sequence of ints, optional
            Radius of the Gaussian kernel. The radius are given for each axis
            as a sequence, or as a single number, in which case it is equal
            for all axes. If specified, the size of the kernel along each axis
            will be ``2*radius + 1``, and `truncate` is ignored.
            Default is None.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes. When `axes` is
            specified, any tuples used for `sigma`, `order`, `mode` and/or `radius`
            must match the length of `axes`. The ith entry in any of these tuples
            corresponds to the ith entry in `axes`.

        Returns
        -------
        gaussian_filter : ndarray
            Returned array of same shape as `input`.

        Notes
        -----
        The multidimensional filter is implemented as a sequence of
        1-D convolution filters. The intermediate arrays are
        stored in the same data type as the output. Therefore, for output
        types with a limited precision, the results may be imprecise
        because intermediate results may be stored with insufficient
        precision.

        The Gaussian kernel will have size ``2*radius + 1`` along each axis. If
        `radius` is None, the default ``radius = round(truncate * sigma)`` will be
        used.

        Examples
        --------
        >>> from scipy.ndimage import gaussian_filter
        >>> import numpy as np
        >>> a = np.arange(50, step=2).reshape((5,5))
        >>> a
        array([[ 0,  2,  4,  6,  8],
               [10, 12, 14, 16, 18],
               [20, 22, 24, 26, 28],
               [30, 32, 34, 36, 38],
               [40, 42, 44, 46, 48]])
        >>> gaussian_filter(a, sigma=1)
        array([[ 4,  6,  8,  9, 11],
               [10, 12, 14, 15, 17],
               [20, 22, 24, 25, 27],
               [29, 31, 33, 34, 36],
               [35, 37, 39, 40, 42]])

        >>> from scipy import datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = gaussian_filter(ascent, sigma=5)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    gaussian_filter1d(input, sigma, axis=-1, order=0, output=None, mode='reflect', cval=0.0, truncate=4.0, *, radius=None)
        1-D Gaussian filter.

        Parameters
        ----------
        input : array_like
            The input array.
        sigma : scalar
            standard deviation for Gaussian kernel
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        order : int, optional
            An order of 0 corresponds to convolution with a Gaussian
            kernel. A positive order corresponds to convolution with
            that derivative of a Gaussian.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        truncate : float, optional
            Truncate the filter at this many standard deviations.
            Default is 4.0.
        radius : None or int, optional
            Radius of the Gaussian kernel. If specified, the size of
            the kernel will be ``2*radius + 1``, and `truncate` is ignored.
            Default is None.

        Returns
        -------
        gaussian_filter1d : ndarray

        Notes
        -----
        The Gaussian kernel will have size ``2*radius + 1`` along each axis. If
        `radius` is None, a default ``radius = round(truncate * sigma)`` will be
        used.

        Examples
        --------
        >>> from scipy.ndimage import gaussian_filter1d
        >>> import numpy as np
        >>> gaussian_filter1d([1.0, 2.0, 3.0, 4.0, 5.0], 1)
        array([ 1.42704095,  2.06782203,  3.        ,  3.93217797,  4.57295905])
        >>> gaussian_filter1d([1.0, 2.0, 3.0, 4.0, 5.0], 4)
        array([ 2.91948343,  2.95023502,  3.        ,  3.04976498,  3.08051657])
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> x = rng.standard_normal(101).cumsum()
        >>> y3 = gaussian_filter1d(x, 3)
        >>> y6 = gaussian_filter1d(x, 6)
        >>> plt.plot(x, 'k', label='original data')
        >>> plt.plot(y3, '--', label='filtered, sigma=3')
        >>> plt.plot(y6, ':', label='filtered, sigma=6')
        >>> plt.legend()
        >>> plt.grid()
        >>> plt.show()

    gaussian_gradient_magnitude(input, sigma, output=None, mode='reflect', cval=0.0, **kwargs)
        Multidimensional gradient magnitude using Gaussian derivatives.

        Parameters
        ----------
        input : array_like
            The input array.
        sigma : scalar or sequence of scalars
            The standard deviations of the Gaussian filter are given for
            each axis as a sequence, or as a single number, in which case
            it is equal for all axes.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        Extra keyword arguments will be passed to gaussian_filter().

        Returns
        -------
        gaussian_gradient_magnitude : ndarray
            Filtered array. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.gaussian_gradient_magnitude(ascent, sigma=5)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    gaussian_laplace(input, sigma, output=None, mode='reflect', cval=0.0, **kwargs)
        Multidimensional Laplace filter using Gaussian second derivatives.

        Parameters
        ----------
        input : array_like
            The input array.
        sigma : scalar or sequence of scalars
            The standard deviations of the Gaussian filter are given for
            each axis as a sequence, or as a single number, in which case
            it is equal for all axes.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        Extra keyword arguments will be passed to gaussian_filter().

        Returns
        -------
        gaussian_laplace : ndarray
            Filtered array. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> ascent = datasets.ascent()

        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side

        >>> result = ndimage.gaussian_laplace(ascent, sigma=1)
        >>> ax1.imshow(result)

        >>> result = ndimage.gaussian_laplace(ascent, sigma=3)
        >>> ax2.imshow(result)
        >>> plt.show()

    generate_binary_structure(rank, connectivity)
        Generate a binary structure for binary morphological operations.

        Parameters
        ----------
        rank : int
             Number of dimensions of the array to which the structuring element
             will be applied, as returned by `np.ndim`.
        connectivity : int
             `connectivity` determines which elements of the output array belong
             to the structure, i.e., are considered as neighbors of the central
             element. Elements up to a squared distance of `connectivity` from
             the center are considered neighbors. `connectivity` may range from 1
             (no diagonal elements are neighbors) to `rank` (all elements are
             neighbors).

        Returns
        -------
        output : ndarray of bools
             Structuring element which may be used for binary morphological
             operations, with `rank` dimensions and all dimensions equal to 3.

        See Also
        --------
        iterate_structure, binary_dilation, binary_erosion

        Notes
        -----
        `generate_binary_structure` can only create structuring elements with
        dimensions equal to 3, i.e., minimal dimensions. For larger structuring
        elements, that are useful e.g., for eroding large objects, one may either
        use `iterate_structure`, or create directly custom arrays with
        numpy functions such as `numpy.ones`.

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> struct = ndimage.generate_binary_structure(2, 1)
        >>> struct
        array([[False,  True, False],
               [ True,  True,  True],
               [False,  True, False]], dtype=bool)
        >>> a = np.zeros((5,5))
        >>> a[2, 2] = 1
        >>> a
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> b = ndimage.binary_dilation(a, structure=struct).astype(a.dtype)
        >>> b
        array([[ 0.,  0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  0.,  0.,  0.,  0.]])
        >>> ndimage.binary_dilation(b, structure=struct).astype(a.dtype)
        array([[ 0.,  0.,  1.,  0.,  0.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 1.,  1.,  1.,  1.,  1.],
               [ 0.,  1.,  1.,  1.,  0.],
               [ 0.,  0.,  1.,  0.,  0.]])
        >>> struct = ndimage.generate_binary_structure(2, 2)
        >>> struct
        array([[ True,  True,  True],
               [ True,  True,  True],
               [ True,  True,  True]], dtype=bool)
        >>> struct = ndimage.generate_binary_structure(3, 1)
        >>> struct # no diagonal elements
        array([[[False, False, False],
                [False,  True, False],
                [False, False, False]],
               [[False,  True, False],
                [ True,  True,  True],
                [False,  True, False]],
               [[False, False, False],
                [False,  True, False],
                [False, False, False]]], dtype=bool)

    generic_filter(input, function, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, extra_arguments=(), extra_keywords=None)
        Calculate a multidimensional filter using the given function.

        At each element the provided function is called. The input values
        within the filter footprint at that element are passed to the function
        as a 1-D array of double values.

        Parameters
        ----------
        input : array_like
            The input array.
        function : {callable, scipy.LowLevelCallable}
            Function to apply at each element.
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        extra_arguments : sequence, optional
            Sequence of extra positional arguments to pass to passed function.
        extra_keywords : dict, optional
            dict of extra keyword arguments to pass to passed function.

        Returns
        -------
        generic_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        This function also accepts low-level callback functions with one of
        the following signatures and wrapped in `scipy.LowLevelCallable`:

        .. code:: c

           int callback(double *buffer, npy_intp filter_size,
                        double *return_value, void *user_data)
           int callback(double *buffer, intptr_t filter_size,
                        double *return_value, void *user_data)

        The calling function iterates over the elements of the input and
        output arrays, calling the callback function at each element. The
        elements within the footprint of the filter at the current element are
        passed through the ``buffer`` parameter, and the number of elements
        within the footprint through ``filter_size``. The calculated value is
        returned in ``return_value``. ``user_data`` is the data pointer provided
        to `scipy.LowLevelCallable` as-is.

        The callback function must return an integer error status that is zero
        if something went wrong and one otherwise. If an error occurs, you should
        normally set the python error status with an informative message
        before returning, otherwise a default error message is set by the
        calling function.

        In addition, some other low-level function pointer specifications
        are accepted, but these are for backward compatibility only and should
        not be used in new code.

        Examples
        --------
        Import the necessary modules and load the example image used for
        filtering.

        >>> import numpy as np
        >>> from scipy import datasets
        >>> from scipy.ndimage import zoom, generic_filter
        >>> import matplotlib.pyplot as plt
        >>> ascent = zoom(datasets.ascent(), 0.5)

        Compute a maximum filter with kernel size 5 by passing a simple NumPy
        aggregation function as argument to `function`.

        >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])

        While a maximmum filter could also directly be obtained using
        `maximum_filter`, `generic_filter` allows generic Python function or
        `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
        range between maximum and minimum value as an example for a kernel size
        of 5.

        >>> def custom_filter(image):
        ...     return np.amax(image) - np.amin(image)
        >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])

        Plot the original and filtered images.

        >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
        >>> plt.gray()  # show the filtered result in grayscale
        >>> top, middle, bottom = axes
        >>> for ax in axes:
        ...     ax.set_axis_off()  # remove coordinate system
        >>> top.imshow(ascent)
        >>> top.set_title("Original image")
        >>> middle.imshow(maximum_filter_result)
        >>> middle.set_title("Maximum filter, Kernel: 5x5")
        >>> bottom.imshow(custom_filter_result)
        >>> bottom.set_title("Custom filter, Kernel: 5x5")
        >>> fig.tight_layout()

    generic_filter1d(input, function, filter_size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0, extra_arguments=(), extra_keywords=None)
        Calculate a 1-D filter along the given axis.

        `generic_filter1d` iterates over the lines of the array, calling the
        given function at each line. The arguments of the line are the
        input line, and the output line. The input and output lines are 1-D
        double arrays. The input line is extended appropriately according
        to the filter size and origin. The output line must be modified
        in-place with the result.

        Parameters
        ----------
        input : array_like
            The input array.
        function : {callable, scipy.LowLevelCallable}
            Function to apply along given axis.
        filter_size : scalar
            Length of the filter.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.
        extra_arguments : sequence, optional
            Sequence of extra positional arguments to pass to passed function.
        extra_keywords : dict, optional
            dict of extra keyword arguments to pass to passed function.

        Returns
        -------
        generic_filter1d : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        This function also accepts low-level callback functions with one of
        the following signatures and wrapped in `scipy.LowLevelCallable`:

        .. code:: c

           int function(double *input_line, npy_intp input_length,
                        double *output_line, npy_intp output_length,
                        void *user_data)
           int function(double *input_line, intptr_t input_length,
                        double *output_line, intptr_t output_length,
                        void *user_data)

        The calling function iterates over the lines of the input and output
        arrays, calling the callback function at each line. The current line
        is extended according to the border conditions set by the calling
        function, and the result is copied into the array that is passed
        through ``input_line``. The length of the input line (after extension)
        is passed through ``input_length``. The callback function should apply
        the filter and store the result in the array passed through
        ``output_line``. The length of the output line is passed through
        ``output_length``. ``user_data`` is the data pointer provided
        to `scipy.LowLevelCallable` as-is.

        The callback function must return an integer error status that is zero
        if something went wrong and one otherwise. If an error occurs, you should
        normally set the python error status with an informative message
        before returning, otherwise a default error message is set by the
        calling function.

        In addition, some other low-level function pointer specifications
        are accepted, but these are for backward compatibility only and should
        not be used in new code.

    generic_gradient_magnitude(input, derivative, output=None, mode='reflect', cval=0.0, extra_arguments=(), extra_keywords=None)
        Gradient magnitude using a provided gradient function.

        Parameters
        ----------
        input : array_like
            The input array.
        derivative : callable
            Callable with the following signature::

                derivative(input, axis, output, mode, cval,
                           *extra_arguments, **extra_keywords)

            See `extra_arguments`, `extra_keywords` below.
            `derivative` can assume that `input` and `output` are ndarrays.
            Note that the output from `derivative` is modified inplace;
            be careful to copy important inputs before returning them.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        extra_keywords : dict, optional
            dict of extra keyword arguments to pass to passed function.
        extra_arguments : sequence, optional
            Sequence of extra positional arguments to pass to passed function.

        Returns
        -------
        generic_gradient_matnitude : ndarray
            Filtered array. Has the same shape as `input`.

    generic_laplace(input, derivative2, output=None, mode='reflect', cval=0.0, extra_arguments=(), extra_keywords=None)
        N-D Laplace filter using a provided second derivative function.

        Parameters
        ----------
        input : array_like
            The input array.
        derivative2 : callable
            Callable with the following signature::

                derivative2(input, axis, output, mode, cval,
                            *extra_arguments, **extra_keywords)

            See `extra_arguments`, `extra_keywords` below.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        extra_keywords : dict, optional
            dict of extra keyword arguments to pass to passed function.
        extra_arguments : sequence, optional
            Sequence of extra positional arguments to pass to passed function.

        Returns
        -------
        generic_laplace : ndarray
            Filtered array. Has the same shape as `input`.

    geometric_transform(input, mapping, output_shape=None, output=None, order=3, mode='constant', cval=0.0, prefilter=True, extra_arguments=(), extra_keywords={})
        Apply an arbitrary geometric transform.

        The given mapping function is used to find, for each point in the
        output, the corresponding coordinates in the input. The value of the
        input at those coordinates is determined by spline interpolation of
        the requested order.

        Parameters
        ----------
        input : array_like
            The input array.
        mapping : {callable, scipy.LowLevelCallable}
            A callable object that accepts a tuple of length equal to the output
            array rank, and returns the corresponding input coordinates as a tuple
            of length equal to the input array rank.
        output_shape : tuple of ints, optional
            Shape tuple.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.
        extra_arguments : tuple, optional
            Extra arguments passed to `mapping`.
        extra_keywords : dict, optional
            Extra keywords passed to `mapping`.

        Returns
        -------
        output : ndarray
            The filtered input.

        See Also
        --------
        map_coordinates, affine_transform, spline_filter1d


        Notes
        -----
        This function also accepts low-level callback functions with one
        the following signatures and wrapped in `scipy.LowLevelCallable`:

        .. code:: c

           int mapping(npy_intp *output_coordinates, double *input_coordinates,
                       int output_rank, int input_rank, void *user_data)
           int mapping(intptr_t *output_coordinates, double *input_coordinates,
                       int output_rank, int input_rank, void *user_data)

        The calling function iterates over the elements of the output array,
        calling the callback function at each element. The coordinates of the
        current output element are passed through ``output_coordinates``. The
        callback function must return the coordinates at which the input must
        be interpolated in ``input_coordinates``. The rank of the input and
        output arrays are given by ``input_rank`` and ``output_rank``
        respectively. ``user_data`` is the data pointer provided
        to `scipy.LowLevelCallable` as-is.

        The callback function must return an integer error status that is zero
        if something went wrong and one otherwise. If an error occurs, you should
        normally set the Python error status with an informative message
        before returning, otherwise a default error message is set by the
        calling function.

        In addition, some other low-level function pointer specifications
        are accepted, but these are for backward compatibility only and should
        not be used in new code.

        For complex-valued `input`, this function transforms the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.ndimage import geometric_transform
        >>> a = np.arange(12.).reshape((4, 3))
        >>> def shift_func(output_coords):
        ...     return (output_coords[0] - 0.5, output_coords[1] - 0.5)
        ...
        >>> geometric_transform(a, shift_func)
        array([[ 0.   ,  0.   ,  0.   ],
               [ 0.   ,  1.362,  2.738],
               [ 0.   ,  4.812,  6.187],
               [ 0.   ,  8.263,  9.637]])

        >>> b = [1, 2, 3, 4, 5]
        >>> def shift_func(output_coords):
        ...     return (output_coords[0] - 3,)
        ...
        >>> geometric_transform(b, shift_func, mode='constant')
        array([0, 0, 0, 1, 2])
        >>> geometric_transform(b, shift_func, mode='nearest')
        array([1, 1, 1, 1, 2])
        >>> geometric_transform(b, shift_func, mode='reflect')
        array([3, 2, 1, 1, 2])
        >>> geometric_transform(b, shift_func, mode='wrap')
        array([2, 3, 4, 1, 2])

    grey_closing(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional grayscale closing.

        A grayscale closing consists in the succession of a grayscale dilation,
        and a grayscale erosion.

        Parameters
        ----------
        input : array_like
            Array over which the grayscale closing is to be computed.
        size : tuple of ints
            Shape of a flat and full structuring element used for the grayscale
            closing. Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the grayscale closing.
        structure : array of ints, optional
            Structuring element used for the grayscale closing. `structure`
            may be a non-flat structuring element. The `structure` array applies
            offsets to the pixels in a neighborhood (the offset is additive during
            dilation and subtractive during erosion)
        output : array, optional
            An array used for storing the output of the closing may be provided.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        grey_closing : ndarray
            Result of the grayscale closing of `input` with `structure`.

        See Also
        --------
        binary_closing, grey_dilation, grey_erosion, grey_opening,
        generate_binary_structure

        Notes
        -----
        The action of a grayscale closing with a flat structuring element amounts
        to smoothen deep local minima, whereas binary closing fills small holes.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.arange(36).reshape((6,6))
        >>> a[3,3] = 0
        >>> a
        array([[ 0,  1,  2,  3,  4,  5],
               [ 6,  7,  8,  9, 10, 11],
               [12, 13, 14, 15, 16, 17],
               [18, 19, 20,  0, 22, 23],
               [24, 25, 26, 27, 28, 29],
               [30, 31, 32, 33, 34, 35]])
        >>> ndimage.grey_closing(a, size=(3,3))
        array([[ 7,  7,  8,  9, 10, 11],
               [ 7,  7,  8,  9, 10, 11],
               [13, 13, 14, 15, 16, 17],
               [19, 19, 20, 20, 22, 23],
               [25, 25, 26, 27, 28, 29],
               [31, 31, 32, 33, 34, 35]])
        >>> # Note that the local minimum a[3,3] has disappeared

    grey_dilation(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a greyscale dilation, using either a structuring element,
        or a footprint corresponding to a flat structuring element.

        Grayscale dilation is a mathematical morphology operation. For the
        simple case of a full and flat structuring element, it can be viewed
        as a maximum filter over a sliding window.

        Parameters
        ----------
        input : array_like
            Array over which the grayscale dilation is to be computed.
        size : tuple of ints
            Shape of a flat and full structuring element used for the grayscale
            dilation. Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the grayscale dilation. Non-zero values give the set of
            neighbors of the center over which the maximum is chosen.
        structure : array of ints, optional
            Structuring element used for the grayscale dilation. `structure`
            may be a non-flat structuring element. The `structure` array applies an
            additive offset for each pixel in the neighborhood.
        output : array, optional
            An array used for storing the output of the dilation may be provided.
        mode : {'reflect','constant','nearest','mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        grey_dilation : ndarray
            Grayscale dilation of `input`.

        See Also
        --------
        binary_dilation, grey_erosion, grey_closing, grey_opening
        generate_binary_structure, maximum_filter

        Notes
        -----
        The grayscale dilation of an image input by a structuring element s defined
        over a domain E is given by:

        (input+s)(x) = max {input(y) + s(x-y), for y in E}

        In particular, for structuring elements defined as
        s(y) = 0 for y in E, the grayscale dilation computes the maximum of the
        input image inside a sliding window defined by E.

        Grayscale dilation [1]_ is a *mathematical morphology* operation [2]_.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Dilation_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[2:5, 2:5] = 1
        >>> a[4,4] = 2; a[2,3] = 3
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 3, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 2, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.grey_dilation(a, size=(3,3))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 3, 3, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.grey_dilation(a, footprint=np.ones((3,3)))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 3, 3, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> s = ndimage.generate_binary_structure(2,1)
        >>> s
        array([[False,  True, False],
               [ True,  True,  True],
               [False,  True, False]], dtype=bool)
        >>> ndimage.grey_dilation(a, footprint=s)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 3, 1, 0, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 1, 3, 2, 1, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 0, 1, 1, 2, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.grey_dilation(a, size=(3,3), structure=np.ones((3,3)))
        array([[1, 1, 1, 1, 1, 1, 1],
               [1, 2, 4, 4, 4, 2, 1],
               [1, 2, 4, 4, 4, 2, 1],
               [1, 2, 4, 4, 4, 3, 1],
               [1, 2, 2, 3, 3, 3, 1],
               [1, 2, 2, 3, 3, 3, 1],
               [1, 1, 1, 1, 1, 1, 1]])

    grey_erosion(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a greyscale erosion, using either a structuring element,
        or a footprint corresponding to a flat structuring element.

        Grayscale erosion is a mathematical morphology operation. For the
        simple case of a full and flat structuring element, it can be viewed
        as a minimum filter over a sliding window.

        Parameters
        ----------
        input : array_like
            Array over which the grayscale erosion is to be computed.
        size : tuple of ints
            Shape of a flat and full structuring element used for the grayscale
            erosion. Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the grayscale erosion. Non-zero values give the set of
            neighbors of the center over which the minimum is chosen.
        structure : array of ints, optional
            Structuring element used for the grayscale erosion. `structure`
            may be a non-flat structuring element. The `structure` array applies a
            subtractive offset for each pixel in the neighborhood.
        output : array, optional
            An array used for storing the output of the erosion may be provided.
        mode : {'reflect','constant','nearest','mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        output : ndarray
            Grayscale erosion of `input`.

        See Also
        --------
        binary_erosion, grey_dilation, grey_opening, grey_closing
        generate_binary_structure, minimum_filter

        Notes
        -----
        The grayscale erosion of an image input by a structuring element s defined
        over a domain E is given by:

        (input+s)(x) = min {input(y) - s(x-y), for y in E}

        In particular, for structuring elements defined as
        s(y) = 0 for y in E, the grayscale erosion computes the minimum of the
        input image inside a sliding window defined by E.

        Grayscale erosion [1]_ is a *mathematical morphology* operation [2]_.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Erosion_%28morphology%29
        .. [2] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[1:6, 1:6] = 3
        >>> a[4,4] = 2; a[2,3] = 1
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 3, 3, 3, 3, 3, 0],
               [0, 3, 3, 1, 3, 3, 0],
               [0, 3, 3, 3, 3, 3, 0],
               [0, 3, 3, 3, 2, 3, 0],
               [0, 3, 3, 3, 3, 3, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.grey_erosion(a, size=(3,3))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 3, 2, 2, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> footprint = ndimage.generate_binary_structure(2, 1)
        >>> footprint
        array([[False,  True, False],
               [ True,  True,  True],
               [False,  True, False]], dtype=bool)
        >>> # Diagonally-connected elements are not considered neighbors
        >>> ndimage.grey_erosion(a, footprint=footprint)
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 3, 1, 2, 0, 0],
               [0, 0, 3, 2, 2, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])

    grey_opening(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional grayscale opening.

        A grayscale opening consists in the succession of a grayscale erosion,
        and a grayscale dilation.

        Parameters
        ----------
        input : array_like
            Array over which the grayscale opening is to be computed.
        size : tuple of ints
            Shape of a flat and full structuring element used for the grayscale
            opening. Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the grayscale opening.
        structure : array of ints, optional
            Structuring element used for the grayscale opening. `structure`
            may be a non-flat structuring element. The `structure` array applies
            offsets to the pixels in a neighborhood (the offset is additive during
            dilation and subtractive during erosion).
        output : array, optional
            An array used for storing the output of the opening may be provided.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        grey_opening : ndarray
            Result of the grayscale opening of `input` with `structure`.

        See Also
        --------
        binary_opening, grey_dilation, grey_erosion, grey_closing
        generate_binary_structure

        Notes
        -----
        The action of a grayscale opening with a flat structuring element amounts
        to smoothen high local maxima, whereas binary opening erases small objects.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.arange(36).reshape((6,6))
        >>> a[3, 3] = 50
        >>> a
        array([[ 0,  1,  2,  3,  4,  5],
               [ 6,  7,  8,  9, 10, 11],
               [12, 13, 14, 15, 16, 17],
               [18, 19, 20, 50, 22, 23],
               [24, 25, 26, 27, 28, 29],
               [30, 31, 32, 33, 34, 35]])
        >>> ndimage.grey_opening(a, size=(3,3))
        array([[ 0,  1,  2,  3,  4,  4],
               [ 6,  7,  8,  9, 10, 10],
               [12, 13, 14, 15, 16, 16],
               [18, 19, 20, 22, 22, 22],
               [24, 25, 26, 27, 28, 28],
               [24, 25, 26, 27, 28, 28]])
        >>> # Note that the local maximum a[3,3] has disappeared

    histogram(input, min, max, bins, labels=None, index=None)
        Calculate the histogram of the values of an array, optionally at labels.

        Histogram calculates the frequency of values in an array within bins
        determined by `min`, `max`, and `bins`. The `labels` and `index`
        keywords can limit the scope of the histogram to specified sub-regions
        within the array.

        Parameters
        ----------
        input : array_like
            Data for which to calculate histogram.
        min, max : int
            Minimum and maximum values of range of histogram bins.
        bins : int
            Number of bins.
        labels : array_like, optional
            Labels for objects in `input`.
            If not None, must be same shape as `input`.
        index : int or sequence of ints, optional
            Label or labels for which to calculate histogram. If None, all values
            where label is greater than zero are used

        Returns
        -------
        hist : ndarray
            Histogram counts.

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[ 0.    ,  0.2146,  0.5962,  0.    ],
        ...               [ 0.    ,  0.7778,  0.    ,  0.    ],
        ...               [ 0.    ,  0.    ,  0.    ,  0.    ],
        ...               [ 0.    ,  0.    ,  0.7181,  0.2787],
        ...               [ 0.    ,  0.    ,  0.6573,  0.3094]])
        >>> from scipy import ndimage
        >>> ndimage.histogram(a, 0, 1, 10)
        array([13,  0,  2,  1,  0,  1,  1,  2,  0,  0])

        With labels and no indices, non-zero elements are counted:

        >>> lbl, nlbl = ndimage.label(a)
        >>> ndimage.histogram(a, 0, 1, 10, lbl)
        array([0, 0, 2, 1, 0, 1, 1, 2, 0, 0])

        Indices can be used to count only certain objects:

        >>> ndimage.histogram(a, 0, 1, 10, lbl, 2)
        array([0, 0, 1, 1, 0, 0, 1, 1, 0, 0])

    iterate_structure(structure, iterations, origin=None)
        Iterate a structure by dilating it with itself.

        Parameters
        ----------
        structure : array_like
           Structuring element (an array of bools, for example), to be dilated with
           itself.
        iterations : int
           number of dilations performed on the structure with itself
        origin : optional
            If origin is None, only the iterated structure is returned. If
            not, a tuple of the iterated structure and the modified origin is
            returned.

        Returns
        -------
        iterate_structure : ndarray of bools
            A new structuring element obtained by dilating `structure`
            (`iterations` - 1) times with itself.

        See Also
        --------
        generate_binary_structure

        Examples
        --------
        >>> from scipy import ndimage
        >>> struct = ndimage.generate_binary_structure(2, 1)
        >>> struct.astype(int)
        array([[0, 1, 0],
               [1, 1, 1],
               [0, 1, 0]])
        >>> ndimage.iterate_structure(struct, 2).astype(int)
        array([[0, 0, 1, 0, 0],
               [0, 1, 1, 1, 0],
               [1, 1, 1, 1, 1],
               [0, 1, 1, 1, 0],
               [0, 0, 1, 0, 0]])
        >>> ndimage.iterate_structure(struct, 3).astype(int)
        array([[0, 0, 0, 1, 0, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [1, 1, 1, 1, 1, 1, 1],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 0, 1, 0, 0, 0]])

    label(input, structure=None, output=None)
        Label features in an array.

        Parameters
        ----------
        input : array_like
            An array-like object to be labeled. Any non-zero values in `input` are
            counted as features and zero values are considered the background.
        structure : array_like, optional
            A structuring element that defines feature connections.
            `structure` must be centrosymmetric
            (see Notes).
            If no structuring element is provided,
            one is automatically generated with a squared connectivity equal to
            one.  That is, for a 2-D `input` array, the default structuring element
            is::

                [[0,1,0],
                 [1,1,1],
                 [0,1,0]]

        output : (None, data-type, array_like), optional
            If `output` is a data type, it specifies the type of the resulting
            labeled feature array.
            If `output` is an array-like object, then `output` will be updated
            with the labeled features from this function.  This function can
            operate in-place, by passing output=input.
            Note that the output must be able to store the largest label, or this
            function will raise an Exception.

        Returns
        -------
        label : ndarray or int
            An integer ndarray where each unique feature in `input` has a unique
            label in the returned array.
        num_features : int
            How many objects were found.

            If `output` is None, this function returns a tuple of
            (`labeled_array`, `num_features`).

            If `output` is a ndarray, then it will be updated with values in
            `labeled_array` and only `num_features` will be returned by this
            function.

        See Also
        --------
        find_objects : generate a list of slices for the labeled features (or
                       objects); useful for finding features' position or
                       dimensions

        Notes
        -----
        A centrosymmetric matrix is a matrix that is symmetric about the center.
        See [1]_ for more information.

        The `structure` matrix must be centrosymmetric to ensure
        two-way connections.
        For instance, if the `structure` matrix is not centrosymmetric
        and is defined as::

            [[0,1,0],
             [1,1,0],
             [0,0,0]]

        and the `input` is::

            [[1,2],
             [0,3]]

        then the structure matrix would indicate the
        entry 2 in the input is connected to 1,
        but 1 is not connected to 2.

        References
        ----------
        .. [1] James R. Weaver, "Centrosymmetric (cross-symmetric)
           matrices, their basic properties, eigenvalues, and
           eigenvectors." The American Mathematical Monthly 92.10
           (1985): 711-717.

        Examples
        --------
        Create an image with some features, then label it using the default
        (cross-shaped) structuring element:

        >>> from scipy.ndimage import label, generate_binary_structure
        >>> import numpy as np
        >>> a = np.array([[0,0,1,1,0,0],
        ...               [0,0,0,1,0,0],
        ...               [1,1,0,0,1,0],
        ...               [0,0,0,1,0,0]])
        >>> labeled_array, num_features = label(a)

        Each of the 4 features are labeled with a different integer:

        >>> num_features
        4
        >>> labeled_array
        array([[0, 0, 1, 1, 0, 0],
               [0, 0, 0, 1, 0, 0],
               [2, 2, 0, 0, 3, 0],
               [0, 0, 0, 4, 0, 0]])

        Generate a structuring element that will consider features connected even
        if they touch diagonally:

        >>> s = generate_binary_structure(2,2)

        or,

        >>> s = [[1,1,1],
        ...      [1,1,1],
        ...      [1,1,1]]

        Label the image using the new structuring element:

        >>> labeled_array, num_features = label(a, structure=s)

        Show the 2 labeled features (note that features 1, 3, and 4 from above are
        now considered a single feature):

        >>> num_features
        2
        >>> labeled_array
        array([[0, 0, 1, 1, 0, 0],
               [0, 0, 0, 1, 0, 0],
               [2, 2, 0, 0, 1, 0],
               [0, 0, 0, 1, 0, 0]])

    labeled_comprehension(input, labels, index, func, out_dtype, default, pass_positions=False)
        Roughly equivalent to [func(input[labels == i]) for i in index].

        Sequentially applies an arbitrary function (that works on array_like input)
        to subsets of an N-D image array specified by `labels` and `index`.
        The option exists to provide the function with positional parameters as the
        second argument.

        Parameters
        ----------
        input : array_like
            Data from which to select `labels` to process.
        labels : array_like or None
            Labels to objects in `input`.
            If not None, array must be same shape as `input`.
            If None, `func` is applied to raveled `input`.
        index : int, sequence of ints or None
            Subset of `labels` to which to apply `func`.
            If a scalar, a single value is returned.
            If None, `func` is applied to all non-zero values of `labels`.
        func : callable
            Python function to apply to `labels` from `input`.
        out_dtype : dtype
            Dtype to use for `result`.
        default : int, float or None
            Default return value when a element of `index` does not exist
            in `labels`.
        pass_positions : bool, optional
            If True, pass linear indices to `func` as a second argument.
            Default is False.

        Returns
        -------
        result : ndarray
            Result of applying `func` to each of `labels` to `input` in `index`.

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> from scipy import ndimage
        >>> lbl, nlbl = ndimage.label(a)
        >>> lbls = np.arange(1, nlbl+1)
        >>> ndimage.labeled_comprehension(a, lbl, lbls, np.mean, float, 0)
        array([ 2.75,  5.5 ,  6.  ])

        Falling back to `default`:

        >>> lbls = np.arange(1, nlbl+2)
        >>> ndimage.labeled_comprehension(a, lbl, lbls, np.mean, float, -1)
        array([ 2.75,  5.5 ,  6.  , -1.  ])

        Passing positions:

        >>> def fn(val, pos):
        ...     print("fn says: %s : %s" % (val, pos))
        ...     return (val.sum()) if (pos.sum() % 2 == 0) else (-val.sum())
        ...
        >>> ndimage.labeled_comprehension(a, lbl, lbls, fn, float, 0, True)
        fn says: [1 2 5 3] : [0 1 4 5]
        fn says: [4 7] : [ 7 11]
        fn says: [9 3] : [12 13]
        array([ 11.,  11., -12.,   0.])

    laplace(input, output=None, mode='reflect', cval=0.0)
        N-D Laplace filter based on approximate second derivatives.

        Parameters
        ----------
        input : array_like
            The input array.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.

        Returns
        -------
        laplace : ndarray
            Filtered array. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.laplace(ascent)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    map_coordinates(input, coordinates, output=None, order=3, mode='constant', cval=0.0, prefilter=True)
        Map the input array to new coordinates by interpolation.

        The array of coordinates is used to find, for each point in the output,
        the corresponding coordinates in the input. The value of the input at
        those coordinates is determined by spline interpolation of the
        requested order.

        The shape of the output is derived from that of the coordinate
        array by dropping the first axis. The values of the array along
        the first axis are the coordinates in the input array at which the
        output value is found.

        Parameters
        ----------
        input : array_like
            The input array.
        coordinates : array_like
            The coordinates at which `input` is evaluated.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.

        Returns
        -------
        map_coordinates : ndarray
            The result of transforming the input. The shape of the output is
            derived from that of `coordinates` by dropping the first axis.

        See Also
        --------
        spline_filter, geometric_transform, scipy.interpolate

        Notes
        -----
        For complex-valued `input`, this function maps the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.arange(12.).reshape((4, 3))
        >>> a
        array([[  0.,   1.,   2.],
               [  3.,   4.,   5.],
               [  6.,   7.,   8.],
               [  9.,  10.,  11.]])
        >>> ndimage.map_coordinates(a, [[0.5, 2], [0.5, 1]], order=1)
        array([ 2.,  7.])

        Above, the interpolated value of a[0.5, 0.5] gives output[0], while
        a[2, 1] is output[1].

        >>> inds = np.array([[0.5, 2], [0.5, 4]])
        >>> ndimage.map_coordinates(a, inds, order=1, cval=-33.3)
        array([  2. , -33.3])
        >>> ndimage.map_coordinates(a, inds, order=1, mode='nearest')
        array([ 2.,  8.])
        >>> ndimage.map_coordinates(a, inds, order=1, cval=0, output=bool)
        array([ True, False], dtype=bool)

    maximum(input, labels=None, index=None)
        Calculate the maximum of the values of an array over labeled regions.

        Parameters
        ----------
        input : array_like
            Array_like of values. For each region specified by `labels`, the
            maximal values of `input` over the region is computed.
        labels : array_like, optional
            An array of integers marking different regions over which the
            maximum value of `input` is to be computed. `labels` must have the
            same shape as `input`. If `labels` is not specified, the maximum
            over the whole array is returned.
        index : array_like, optional
            A list of region labels that are taken into account for computing the
            maxima. If index is None, the maximum over all elements where `labels`
            is non-zero is returned.

        Returns
        -------
        output : float or list of floats
            List of maxima of `input` over the regions determined by `labels` and
            whose index is in `index`. If `index` or `labels` are not specified, a
            float is returned: the maximal value of `input` if `labels` is None,
            and the maximal value of elements where `labels` is greater than zero
            if `index` is None.

        See Also
        --------
        label, minimum, median, maximum_position, extrema, sum, mean, variance,
        standard_deviation

        Notes
        -----
        The function returns a Python list and not a NumPy array, use
        `np.array` to convert the list to an array.

        Examples
        --------
        >>> import numpy as np
        >>> a = np.arange(16).reshape((4,4))
        >>> a
        array([[ 0,  1,  2,  3],
               [ 4,  5,  6,  7],
               [ 8,  9, 10, 11],
               [12, 13, 14, 15]])
        >>> labels = np.zeros_like(a)
        >>> labels[:2,:2] = 1
        >>> labels[2:, 1:3] = 2
        >>> labels
        array([[1, 1, 0, 0],
               [1, 1, 0, 0],
               [0, 2, 2, 0],
               [0, 2, 2, 0]])
        >>> from scipy import ndimage
        >>> ndimage.maximum(a)
        15.0
        >>> ndimage.maximum(a, labels=labels, index=[1,2])
        [5.0, 14.0]
        >>> ndimage.maximum(a, labels=labels)
        14.0

        >>> b = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> labels, labels_nb = ndimage.label(b)
        >>> labels
        array([[1, 1, 0, 0],
               [1, 1, 0, 2],
               [0, 0, 0, 2],
               [3, 3, 0, 0]])
        >>> ndimage.maximum(b, labels=labels, index=np.arange(1, labels_nb + 1))
        [5.0, 7.0, 9.0]

    maximum_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Calculate a multidimensional maximum filter.

        Parameters
        ----------
        input : array_like
            The input array.
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes. When `axes` is
            specified, any tuples used for `size`, `origin`, and/or `mode`
            must match the length of `axes`. The ith entry in any of these tuples
            corresponds to the ith entry in `axes`.

        Returns
        -------
        maximum_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        A sequence of modes (one per axis) is only supported when the footprint is
        separable. Otherwise, a single mode string must be provided.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.maximum_filter(ascent, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    maximum_filter1d(input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a 1-D maximum filter along the given axis.

        The lines of the array along the given axis are filtered with a
        maximum filter of given size.

        Parameters
        ----------
        input : array_like
            The input array.
        size : int
            Length along which to calculate the 1-D maximum.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.

        Returns
        -------
        maximum1d : ndarray, None
            Maximum-filtered array with same shape as input.
            None if `output` is not None

        Notes
        -----
        This function implements the MAXLIST algorithm [1]_, as described by
        Richard Harter [2]_, and has a guaranteed O(n) performance, `n` being
        the `input` length, regardless of filter size.

        References
        ----------
        .. [1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2777
        .. [2] http://www.richardhartersworld.com/cri/2001/slidingmin.html

        Examples
        --------
        >>> from scipy.ndimage import maximum_filter1d
        >>> maximum_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
        array([8, 8, 8, 4, 9, 9, 9, 9])

    maximum_position(input, labels=None, index=None)
        Find the positions of the maximums of the values of an array at labels.

        For each region specified by `labels`, the position of the maximum
        value of `input` within the region is returned.

        Parameters
        ----------
        input : array_like
            Array_like of values.
        labels : array_like, optional
            An array of integers marking different regions over which the
            position of the maximum value of `input` is to be computed.
            `labels` must have the same shape as `input`. If `labels` is not
            specified, the location of the first maximum over the whole
            array is returned.

            The `labels` argument only works when `index` is specified.
        index : array_like, optional
            A list of region labels that are taken into account for finding the
            location of the maxima. If `index` is None, the first maximum
            over all elements where `labels` is non-zero is returned.

            The `index` argument only works when `labels` is specified.

        Returns
        -------
        output : list of tuples of ints
            List of tuples of ints that specify the location of maxima of
            `input` over the regions determined by `labels` and whose index
            is in `index`.

            If `index` or `labels` are not specified, a tuple of ints is
            returned specifying the location of the ``first`` maximal value
            of `input`.

        See Also
        --------
        label, minimum, median, maximum_position, extrema, sum, mean, variance,
        standard_deviation

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> ndimage.maximum_position(a)
        (3, 0)

        Features to process can be specified using `labels` and `index`:

        >>> lbl = np.array([[0, 1, 2, 3],
        ...                 [0, 1, 2, 3],
        ...                 [0, 1, 2, 3],
        ...                 [0, 1, 2, 3]])
        >>> ndimage.maximum_position(a, lbl, 1)
        (1, 1)

        If no index is given, non-zero `labels` are processed:

        >>> ndimage.maximum_position(a, lbl)
        (2, 3)

        If there are no maxima, the position of the first element is returned:

        >>> ndimage.maximum_position(a, lbl, 2)
        (0, 2)

    mean(input, labels=None, index=None)
        Calculate the mean of the values of an array at labels.

        Parameters
        ----------
        input : array_like
            Array on which to compute the mean of elements over distinct
            regions.
        labels : array_like, optional
            Array of labels of same shape, or broadcastable to the same shape as
            `input`. All elements sharing the same label form one region over
            which the mean of the elements is computed.
        index : int or sequence of ints, optional
            Labels of the objects over which the mean is to be computed.
            Default is None, in which case the mean for all values where label is
            greater than 0 is calculated.

        Returns
        -------
        out : list
            Sequence of same length as `index`, with the mean of the different
            regions labeled by the labels in `index`.

        See Also
        --------
        variance, standard_deviation, minimum, maximum, sum, label

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.arange(25).reshape((5,5))
        >>> labels = np.zeros_like(a)
        >>> labels[3:5,3:5] = 1
        >>> index = np.unique(labels)
        >>> labels
        array([[0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0],
               [0, 0, 0, 1, 1],
               [0, 0, 0, 1, 1]])
        >>> index
        array([0, 1])
        >>> ndimage.mean(a, labels=labels, index=index)
        [10.285714285714286, 21.0]

    median(input, labels=None, index=None)
        Calculate the median of the values of an array over labeled regions.

        Parameters
        ----------
        input : array_like
            Array_like of values. For each region specified by `labels`, the
            median value of `input` over the region is computed.
        labels : array_like, optional
            An array_like of integers marking different regions over which the
            median value of `input` is to be computed. `labels` must have the
            same shape as `input`. If `labels` is not specified, the median
            over the whole array is returned.
        index : array_like, optional
            A list of region labels that are taken into account for computing the
            medians. If index is None, the median over all elements where `labels`
            is non-zero is returned.

        Returns
        -------
        median : float or list of floats
            List of medians of `input` over the regions determined by `labels` and
            whose index is in `index`. If `index` or `labels` are not specified, a
            float is returned: the median value of `input` if `labels` is None,
            and the median value of elements where `labels` is greater than zero
            if `index` is None.

        See Also
        --------
        label, minimum, maximum, extrema, sum, mean, variance, standard_deviation

        Notes
        -----
        The function returns a Python list and not a NumPy array, use
        `np.array` to convert the list to an array.

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 1],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> labels, labels_nb = ndimage.label(a)
        >>> labels
        array([[1, 1, 0, 2],
               [1, 1, 0, 2],
               [0, 0, 0, 2],
               [3, 3, 0, 0]])
        >>> ndimage.median(a, labels=labels, index=np.arange(1, labels_nb + 1))
        [2.5, 4.0, 6.0]
        >>> ndimage.median(a)
        1.0
        >>> ndimage.median(a, labels=labels)
        3.0

    median_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Calculate a multidimensional median filter.

        Parameters
        ----------
        input : array_like
            The input array.
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes.

        Returns
        -------
        median_filter : ndarray
            Filtered array. Has the same shape as `input`.

        See Also
        --------
        scipy.signal.medfilt2d

        Notes
        -----
        For 2-dimensional images with ``uint8``, ``float32`` or ``float64`` dtypes
        the specialised function `scipy.signal.medfilt2d` may be faster. It is
        however limited to constant mode with ``cval=0``.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.median_filter(ascent, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    minimum(input, labels=None, index=None)
        Calculate the minimum of the values of an array over labeled regions.

        Parameters
        ----------
        input : array_like
            Array_like of values. For each region specified by `labels`, the
            minimal values of `input` over the region is computed.
        labels : array_like, optional
            An array_like of integers marking different regions over which the
            minimum value of `input` is to be computed. `labels` must have the
            same shape as `input`. If `labels` is not specified, the minimum
            over the whole array is returned.
        index : array_like, optional
            A list of region labels that are taken into account for computing the
            minima. If index is None, the minimum over all elements where `labels`
            is non-zero is returned.

        Returns
        -------
        minimum : float or list of floats
            List of minima of `input` over the regions determined by `labels` and
            whose index is in `index`. If `index` or `labels` are not specified, a
            float is returned: the minimal value of `input` if `labels` is None,
            and the minimal value of elements where `labels` is greater than zero
            if `index` is None.

        See Also
        --------
        label, maximum, median, minimum_position, extrema, sum, mean, variance,
        standard_deviation

        Notes
        -----
        The function returns a Python list and not a NumPy array, use
        `np.array` to convert the list to an array.

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> labels, labels_nb = ndimage.label(a)
        >>> labels
        array([[1, 1, 0, 0],
               [1, 1, 0, 2],
               [0, 0, 0, 2],
               [3, 3, 0, 0]])
        >>> ndimage.minimum(a, labels=labels, index=np.arange(1, labels_nb + 1))
        [1.0, 4.0, 3.0]
        >>> ndimage.minimum(a)
        0.0
        >>> ndimage.minimum(a, labels=labels)
        1.0

    minimum_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Calculate a multidimensional minimum filter.

        Parameters
        ----------
        input : array_like
            The input array.
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes. When `axes` is
            specified, any tuples used for `size`, `origin`, and/or `mode`
            must match the length of `axes`. The ith entry in any of these tuples
            corresponds to the ith entry in `axes`.

        Returns
        -------
        minimum_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        A sequence of modes (one per axis) is only supported when the footprint is
        separable. Otherwise, a single mode string must be provided.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.minimum_filter(ascent, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    minimum_filter1d(input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a 1-D minimum filter along the given axis.

        The lines of the array along the given axis are filtered with a
        minimum filter of given size.

        Parameters
        ----------
        input : array_like
            The input array.
        size : int
            length along which to calculate 1D minimum
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.

        Returns
        -------
        result : ndarray.
            Filtered image. Has the same shape as `input`.

        Notes
        -----
        This function implements the MINLIST algorithm [1]_, as described by
        Richard Harter [2]_, and has a guaranteed O(n) performance, `n` being
        the `input` length, regardless of filter size.

        References
        ----------
        .. [1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2777
        .. [2] http://www.richardhartersworld.com/cri/2001/slidingmin.html


        Examples
        --------
        >>> from scipy.ndimage import minimum_filter1d
        >>> minimum_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
        array([2, 0, 0, 0, 1, 1, 0, 0])

    minimum_position(input, labels=None, index=None)
        Find the positions of the minimums of the values of an array at labels.

        Parameters
        ----------
        input : array_like
            Array_like of values.
        labels : array_like, optional
            An array of integers marking different regions over which the
            position of the minimum value of `input` is to be computed.
            `labels` must have the same shape as `input`. If `labels` is not
            specified, the location of the first minimum over the whole
            array is returned.

            The `labels` argument only works when `index` is specified.
        index : array_like, optional
            A list of region labels that are taken into account for finding the
            location of the minima. If `index` is None, the ``first`` minimum
            over all elements where `labels` is non-zero is returned.

            The `index` argument only works when `labels` is specified.

        Returns
        -------
        output : list of tuples of ints
            Tuple of ints or list of tuples of ints that specify the location
            of minima of `input` over the regions determined by `labels` and
            whose index is in `index`.

            If `index` or `labels` are not specified, a tuple of ints is
            returned specifying the location of the first minimal value of `input`.

        See Also
        --------
        label, minimum, median, maximum_position, extrema, sum, mean, variance,
        standard_deviation

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[10, 20, 30],
        ...               [40, 80, 100],
        ...               [1, 100, 200]])
        >>> b = np.array([[1, 2, 0, 1],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])

        >>> from scipy import ndimage

        >>> ndimage.minimum_position(a)
        (2, 0)
        >>> ndimage.minimum_position(b)
        (0, 2)

        Features to process can be specified using `labels` and `index`:

        >>> label, pos = ndimage.label(a)
        >>> ndimage.minimum_position(a, label, index=np.arange(1, pos+1))
        [(2, 0)]

        >>> label, pos = ndimage.label(b)
        >>> ndimage.minimum_position(b, label, index=np.arange(1, pos+1))
        [(0, 0), (0, 3), (3, 1)]

    morphological_gradient(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional morphological gradient.

        The morphological gradient is calculated as the difference between a
        dilation and an erosion of the input with a given structuring element.

        Parameters
        ----------
        input : array_like
            Array over which to compute the morphlogical gradient.
        size : tuple of ints
            Shape of a flat and full structuring element used for the mathematical
            morphology operations. Optional if `footprint` or `structure` is
            provided. A larger `size` yields a more blurred gradient.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the morphology operations. Larger footprints
            give a more blurred morphological gradient.
        structure : array of ints, optional
            Structuring element used for the morphology operations. `structure` may
            be a non-flat structuring element. The `structure` array applies
            offsets to the pixels in a neighborhood (the offset is additive during
            dilation and subtractive during erosion)
        output : array, optional
            An array used for storing the output of the morphological gradient
            may be provided.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default 0

        Returns
        -------
        morphological_gradient : ndarray
            Morphological gradient of `input`.

        See Also
        --------
        grey_dilation, grey_erosion, gaussian_gradient_magnitude

        Notes
        -----
        For a flat structuring element, the morphological gradient
        computed at a given point corresponds to the maximal difference
        between elements of the input among the elements covered by the
        structuring element centered on the point.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Mathematical_morphology

        Examples
        --------
        >>> from scipy import ndimage
        >>> import numpy as np
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[2:5, 2:5] = 1
        >>> ndimage.morphological_gradient(a, size=(3,3))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 0, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> # The morphological gradient is computed as the difference
        >>> # between a dilation and an erosion
        >>> ndimage.grey_dilation(a, size=(3,3)) -\
        ...  ndimage.grey_erosion(a, size=(3,3))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 0, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 1, 1, 1, 1, 1, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> a = np.zeros((7,7), dtype=int)
        >>> a[2:5, 2:5] = 1
        >>> a[4,4] = 2; a[2,3] = 3
        >>> a
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 3, 1, 0, 0],
               [0, 0, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 2, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]])
        >>> ndimage.morphological_gradient(a, size=(3,3))
        array([[0, 0, 0, 0, 0, 0, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 3, 3, 1, 0],
               [0, 1, 3, 2, 3, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 1, 1, 2, 2, 2, 0],
               [0, 0, 0, 0, 0, 0, 0]])

    morphological_laplace(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional morphological laplace.

        Parameters
        ----------
        input : array_like
            Input.
        size : tuple of ints
            Shape of a flat and full structuring element used for the mathematical
            morphology operations. Optional if `footprint` or `structure` is
            provided.
        footprint : array of ints, optional
            Positions of non-infinite elements of a flat structuring element
            used for the morphology operations.
        structure : array of ints, optional
            Structuring element used for the morphology operations. `structure` may
            be a non-flat structuring element. The `structure` array applies
            offsets to the pixels in a neighborhood (the offset is additive during
            dilation and subtractive during erosion)
        output : ndarray, optional
            An output array can optionally be provided.
        mode : {'reflect','constant','nearest','mirror', 'wrap'}, optional
            The mode parameter determines how the array borders are handled.
            For 'constant' mode, values beyond borders are set to be `cval`.
            Default is 'reflect'.
        cval : scalar, optional
            Value to fill past edges of input if mode is 'constant'.
            Default is 0.0
        origin : origin, optional
            The origin parameter controls the placement of the filter.

        Returns
        -------
        morphological_laplace : ndarray
            Output

    percentile_filter(input, percentile, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Calculate a multidimensional percentile filter.

        Parameters
        ----------
        input : array_like
            The input array.
        percentile : scalar
            The percentile parameter may be less than zero, i.e.,
            percentile = -20 equals percentile = 80
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes.

        Returns
        -------
        percentile_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.percentile_filter(ascent, percentile=20, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    prewitt(input, axis=-1, output=None, mode='reflect', cval=0.0)
        Calculate a Prewitt filter.

        Parameters
        ----------
        input : array_like
            The input array.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.

        Returns
        -------
        prewitt : ndarray
            Filtered array. Has the same shape as `input`.

        See Also
        --------
        sobel: Sobel filter

        Notes
        -----
        This function computes the one-dimensional Prewitt filter.
        Horizontal edges are emphasised with the horizontal transform (axis=0),
        vertical edges with the vertical transform (axis=1), and so on for higher
        dimensions. These can be combined to give the magnitude.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np
        >>> ascent = datasets.ascent()
        >>> prewitt_h = ndimage.prewitt(ascent, axis=0)
        >>> prewitt_v = ndimage.prewitt(ascent, axis=1)
        >>> magnitude = np.sqrt(prewitt_h ** 2 + prewitt_v ** 2)
        >>> magnitude *= 255 / np.max(magnitude) # Normalization
        >>> fig, axes = plt.subplots(2, 2, figsize = (8, 8))
        >>> plt.gray()
        >>> axes[0, 0].imshow(ascent)
        >>> axes[0, 1].imshow(prewitt_h)
        >>> axes[1, 0].imshow(prewitt_v)
        >>> axes[1, 1].imshow(magnitude)
        >>> titles = ["original", "horizontal", "vertical", "magnitude"]
        >>> for i, ax in enumerate(axes.ravel()):
        ...     ax.set_title(titles[i])
        ...     ax.axis("off")
        >>> plt.show()

    rank_filter(input, rank, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Calculate a multidimensional rank filter.

        Parameters
        ----------
        input : array_like
            The input array.
        rank : int
            The rank parameter may be less than zero, i.e., rank = -1
            indicates the largest element.
        size : scalar or tuple, optional
            See footprint, below. Ignored if footprint is given.
        footprint : array, optional
            Either `size` or `footprint` must be defined. `size` gives
            the shape that is taken from the input array, at every element
            position, to define the input to the filter function.
            `footprint` is a boolean array that specifies (implicitly) a
            shape, but also which of the elements within this shape will get
            passed to the filter function. Thus ``size=(n,m)`` is equivalent
            to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
            of dimensions of the input array, so that, if the input array is
            shape (10,10,10), and `size` is 2, then the actual size used is
            (2,2,2). When `footprint` is given, `size` is ignored.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes.

        Returns
        -------
        rank_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.rank_filter(ascent, rank=42, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    rotate(input, angle, axes=(1, 0), reshape=True, output=None, order=3, mode='constant', cval=0.0, prefilter=True)
        Rotate an array.

        The array is rotated in the plane defined by the two axes given by the
        `axes` parameter using spline interpolation of the requested order.

        Parameters
        ----------
        input : array_like
            The input array.
        angle : float
            The rotation angle in degrees.
        axes : tuple of 2 ints, optional
            The two axes that define the plane of rotation. Default is the first
            two axes.
        reshape : bool, optional
            If `reshape` is true, the output shape is adapted so that the input
            array is contained completely in the output. Default is True.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.

        Returns
        -------
        rotate : ndarray
            The rotated input.

        Notes
        -----
        For complex-valued `input`, this function rotates the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure(figsize=(10, 3))
        >>> ax1, ax2, ax3 = fig.subplots(1, 3)
        >>> img = datasets.ascent()
        >>> img_45 = ndimage.rotate(img, 45, reshape=False)
        >>> full_img_45 = ndimage.rotate(img, 45, reshape=True)
        >>> ax1.imshow(img, cmap='gray')
        >>> ax1.set_axis_off()
        >>> ax2.imshow(img_45, cmap='gray')
        >>> ax2.set_axis_off()
        >>> ax3.imshow(full_img_45, cmap='gray')
        >>> ax3.set_axis_off()
        >>> fig.set_layout_engine('tight')
        >>> plt.show()
        >>> print(img.shape)
        (512, 512)
        >>> print(img_45.shape)
        (512, 512)
        >>> print(full_img_45.shape)
        (724, 724)

    shift(input, shift, output=None, order=3, mode='constant', cval=0.0, prefilter=True)
        Shift an array.

        The array is shifted using spline interpolation of the requested order.
        Points outside the boundaries of the input are filled according to the
        given mode.

        Parameters
        ----------
        input : array_like
            The input array.
        shift : float or sequence
            The shift along the axes. If a float, `shift` is the same for each
            axis. If a sequence, `shift` should contain one value for each axis.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.

        Returns
        -------
        shift : ndarray
            The shifted input.

        See Also
        --------
        affine_transform : Affine transformations

        Notes
        -----
        For complex-valued `input`, this function shifts the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        Import the necessary modules and an exemplary image.

        >>> from scipy.ndimage import shift
        >>> import matplotlib.pyplot as plt
        >>> from scipy import datasets
        >>> image = datasets.ascent()

        Shift the image vertically by 20 pixels.

        >>> image_shifted_vertically = shift(image, (20, 0))

        Shift the image vertically by -200 pixels and horizontally by 100 pixels.

        >>> image_shifted_both_directions = shift(image, (-200, 100))

        Plot the original and the shifted images.

        >>> fig, axes = plt.subplots(3, 1, figsize=(4, 12))
        >>> plt.gray()  # show the filtered result in grayscale
        >>> top, middle, bottom = axes
        >>> for ax in axes:
        ...     ax.set_axis_off()  # remove coordinate system
        >>> top.imshow(image)
        >>> top.set_title("Original image")
        >>> middle.imshow(image_shifted_vertically)
        >>> middle.set_title("Vertically shifted image")
        >>> bottom.imshow(image_shifted_both_directions)
        >>> bottom.set_title("Image shifted in both directions")
        >>> fig.tight_layout()

    sobel(input, axis=-1, output=None, mode='reflect', cval=0.0)
        Calculate a Sobel filter.

        Parameters
        ----------
        input : array_like
            The input array.
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.

        Returns
        -------
        sobel : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        This function computes the axis-specific Sobel gradient.
        The horizontal edges can be emphasised with the horizontal transform (axis=0),
        the vertical edges with the vertical transform (axis=1) and so on for higher
        dimensions. These can be combined to give the magnitude.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np
        >>> ascent = datasets.ascent().astype('int32')
        >>> sobel_h = ndimage.sobel(ascent, 0)  # horizontal gradient
        >>> sobel_v = ndimage.sobel(ascent, 1)  # vertical gradient
        >>> magnitude = np.sqrt(sobel_h**2 + sobel_v**2)
        >>> magnitude *= 255.0 / np.max(magnitude)  # normalization
        >>> fig, axs = plt.subplots(2, 2, figsize=(8, 8))
        >>> plt.gray()  # show the filtered result in grayscale
        >>> axs[0, 0].imshow(ascent)
        >>> axs[0, 1].imshow(sobel_h)
        >>> axs[1, 0].imshow(sobel_v)
        >>> axs[1, 1].imshow(magnitude)
        >>> titles = ["original", "horizontal", "vertical", "magnitude"]
        >>> for i, ax in enumerate(axs.ravel()):
        ...     ax.set_title(titles[i])
        ...     ax.axis("off")
        >>> plt.show()

    spline_filter(input, order=3, output=<class 'numpy.float64'>, mode='mirror')
        Multidimensional spline filter.

        Parameters
        ----------
        input : array_like
            The input array.
        order : int, optional
            The order of the spline, default is 3.
        output : ndarray or dtype, optional
            The array in which to place the output, or the dtype of the returned
            array. Default is ``numpy.float64``.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'mirror'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.

        Returns
        -------
        spline_filter : ndarray
            Filtered array. Has the same shape as `input`.

        See Also
        --------
        spline_filter1d : Calculate a 1-D spline filter along the given axis.

        Notes
        -----
        The multidimensional filter is implemented as a sequence of
        1-D spline filters. The intermediate arrays are stored
        in the same data type as the output. Therefore, for output types
        with a limited precision, the results may be imprecise because
        intermediate results may be stored with insufficient precision.

        For complex-valued `input`, this function processes the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        We can filter an image using multidimentional splines:

        >>> from scipy.ndimage import spline_filter
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> orig_img = np.eye(20)  # create an image
        >>> orig_img[10, :] = 1.0
        >>> sp_filter = spline_filter(orig_img, order=3)
        >>> f, ax = plt.subplots(1, 2, sharex=True)
        >>> for ind, data in enumerate([[orig_img, "original image"],
        ...                             [sp_filter, "spline filter"]]):
        ...     ax[ind].imshow(data[0], cmap='gray_r')
        ...     ax[ind].set_title(data[1])
        >>> plt.tight_layout()
        >>> plt.show()

    spline_filter1d(input, order=3, axis=-1, output=<class 'numpy.float64'>, mode='mirror')
        Calculate a 1-D spline filter along the given axis.

        The lines of the array along the given axis are filtered by a
        spline filter. The order of the spline must be >= 2 and <= 5.

        Parameters
        ----------
        input : array_like
            The input array.
        order : int, optional
            The order of the spline, default is 3.
        axis : int, optional
            The axis along which the spline filter is applied. Default is the last
            axis.
        output : ndarray or dtype, optional
            The array in which to place the output, or the dtype of the returned
            array. Default is ``numpy.float64``.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'mirror'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.

        Returns
        -------
        spline_filter1d : ndarray
            The filtered input.

        See Also
        --------
        spline_filter : Multidimensional spline filter.

        Notes
        -----
        All of the interpolation functions in `ndimage` do spline interpolation of
        the input image. If using B-splines of `order > 1`, the input image
        values have to be converted to B-spline coefficients first, which is
        done by applying this 1-D filter sequentially along all
        axes of the input. All functions that require B-spline coefficients
        will automatically filter their inputs, a behavior controllable with
        the `prefilter` keyword argument. For functions that accept a `mode`
        parameter, the result will only be correct if it matches the `mode`
        used when filtering.

        For complex-valued `input`, this function processes the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        We can filter an image using 1-D spline along the given axis:

        >>> from scipy.ndimage import spline_filter1d
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> orig_img = np.eye(20)  # create an image
        >>> orig_img[10, :] = 1.0
        >>> sp_filter_axis_0 = spline_filter1d(orig_img, axis=0)
        >>> sp_filter_axis_1 = spline_filter1d(orig_img, axis=1)
        >>> f, ax = plt.subplots(1, 3, sharex=True)
        >>> for ind, data in enumerate([[orig_img, "original image"],
        ...             [sp_filter_axis_0, "spline filter (axis=0)"],
        ...             [sp_filter_axis_1, "spline filter (axis=1)"]]):
        ...     ax[ind].imshow(data[0], cmap='gray_r')
        ...     ax[ind].set_title(data[1])
        >>> plt.tight_layout()
        >>> plt.show()

    standard_deviation(input, labels=None, index=None)
        Calculate the standard deviation of the values of an N-D image array,
        optionally at specified sub-regions.

        Parameters
        ----------
        input : array_like
            N-D image data to process.
        labels : array_like, optional
            Labels to identify sub-regions in `input`.
            If not None, must be same shape as `input`.
        index : int or sequence of ints, optional
            `labels` to include in output. If None (default), all values where
            `labels` is non-zero are used.

        Returns
        -------
        standard_deviation : float or ndarray
            Values of standard deviation, for each sub-region if `labels` and
            `index` are specified.

        See Also
        --------
        label, variance, maximum, minimum, extrema

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> from scipy import ndimage
        >>> ndimage.standard_deviation(a)
        2.7585095613392387

        Features to process can be specified using `labels` and `index`:

        >>> lbl, nlbl = ndimage.label(a)
        >>> ndimage.standard_deviation(a, lbl, index=np.arange(1, nlbl+1))
        array([ 1.479,  1.5  ,  3.   ])

        If no index is given, non-zero `labels` are processed:

        >>> ndimage.standard_deviation(a, lbl)
        2.4874685927665499

    sum(input, labels=None, index=None)
        Calculate the sum of the values of the array.

        Notes
        -----
        This is an alias for `ndimage.sum_labels` kept for backwards compatibility
        reasons, for new code please prefer `sum_labels`.  See the `sum_labels`
        docstring for more details.

    sum_labels(input, labels=None, index=None)
        Calculate the sum of the values of the array.

        Parameters
        ----------
        input : array_like
            Values of `input` inside the regions defined by `labels`
            are summed together.
        labels : array_like of ints, optional
            Assign labels to the values of the array. Has to have the same shape as
            `input`.
        index : array_like, optional
            A single label number or a sequence of label numbers of
            the objects to be measured.

        Returns
        -------
        sum : ndarray or scalar
            An array of the sums of values of `input` inside the regions defined
            by `labels` with the same shape as `index`. If 'index' is None or scalar,
            a scalar is returned.

        See Also
        --------
        mean, median

        Examples
        --------
        >>> from scipy import ndimage
        >>> input =  [0,1,2,3]
        >>> labels = [1,1,2,2]
        >>> ndimage.sum_labels(input, labels, index=[1,2])
        [1.0, 5.0]
        >>> ndimage.sum_labels(input, labels, index=1)
        1
        >>> ndimage.sum_labels(input, labels)
        6

    uniform_filter(input, size=3, output=None, mode='reflect', cval=0.0, origin=0, *, axes=None)
        Multidimensional uniform filter.

        Parameters
        ----------
        input : array_like
            The input array.
        size : int or sequence of ints, optional
            The sizes of the uniform filter are given for each axis as a
            sequence, or as a single number, in which case the size is
            equal for all axes.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : str or sequence, optional
            The `mode` parameter determines how the input array is extended
            when the filter overlaps a border. By passing a sequence of modes
            with length equal to the number of dimensions of the input array,
            different modes can be specified along each axis. Default value is
            'reflect'. The valid values and their behavior is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int or sequence, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right. By passing a sequence of origins with length equal to
            the number of dimensions of the input array, different shifts can
            be specified along each axis.
        axes : tuple of int or None, optional
            If None, `input` is filtered along all axes. Otherwise,
            `input` is filtered along the specified axes. When `axes` is
            specified, any tuples used for `size`, `origin`, and/or `mode`
            must match the length of `axes`. The ith entry in any of these tuples
            corresponds to the ith entry in `axes`.

        Returns
        -------
        uniform_filter : ndarray
            Filtered array. Has the same shape as `input`.

        Notes
        -----
        The multidimensional filter is implemented as a sequence of
        1-D uniform filters. The intermediate arrays are stored
        in the same data type as the output. Therefore, for output types
        with a limited precision, the results may be imprecise because
        intermediate results may be stored with insufficient precision.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> plt.gray()  # show the filtered result in grayscale
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.uniform_filter(ascent, size=20)
        >>> ax1.imshow(ascent)
        >>> ax2.imshow(result)
        >>> plt.show()

    uniform_filter1d(input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0)
        Calculate a 1-D uniform filter along the given axis.

        The lines of the array along the given axis are filtered with a
        uniform filter of given size.

        Parameters
        ----------
        input : array_like
            The input array.
        size : int
            length of uniform filter
        axis : int, optional
            The axis of `input` along which to calculate. Default is -1.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'reflect'. Behavior for each valid
            value is as follows:

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            For consistency with the interpolation functions, the following mode
            names can also be used:

            'grid-mirror'
                This is a synonym for 'reflect'.

            'grid-constant'
                This is a synonym for 'constant'.

            'grid-wrap'
                This is a synonym for 'wrap'.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        origin : int, optional
            Controls the placement of the filter on the input array's pixels.
            A value of 0 (the default) centers the filter over the pixel, with
            positive values shifting the filter to the left, and negative ones
            to the right.

        Returns
        -------
        result : ndarray
            Filtered array. Has same shape as `input`.

        Examples
        --------
        >>> from scipy.ndimage import uniform_filter1d
        >>> uniform_filter1d([2, 8, 0, 4, 1, 9, 9, 0], size=3)
        array([4, 3, 4, 1, 4, 6, 6, 3])

    value_indices(arr, *, ignore_value=None)
        Find indices of each distinct value in given array.

        Parameters
        ----------
        arr : ndarray of ints
            Array containing integer values.
        ignore_value : int, optional
            This value will be ignored in searching the `arr` array. If not
            given, all values found will be included in output. Default
            is None.

        Returns
        -------
        indices : dictionary
            A Python dictionary of array indices for each distinct value. The
            dictionary is keyed by the distinct values, the entries are array
            index tuples covering all occurrences of the value within the
            array.

            This dictionary can occupy significant memory, usually several times
            the size of the input array.

        See Also
        --------
        label, maximum, median, minimum_position, extrema, sum, mean, variance,
        standard_deviation, numpy.where, numpy.unique

        Notes
        -----
        For a small array with few distinct values, one might use
        `numpy.unique()` to find all possible values, and ``(arr == val)`` to
        locate each value within that array. However, for large arrays,
        with many distinct values, this can become extremely inefficient,
        as locating each value would require a new search through the entire
        array. Using this function, there is essentially one search, with
        the indices saved for all distinct values.

        This is useful when matching a categorical image (e.g. a segmentation
        or classification) to an associated image of other data, allowing
        any per-class statistic(s) to then be calculated. Provides a
        more flexible alternative to functions like ``scipy.ndimage.mean()``
        and ``scipy.ndimage.variance()``.

        Some other closely related functionality, with different strengths and
        weaknesses, can also be found in ``scipy.stats.binned_statistic()`` and
        the `scikit-image <https://scikit-image.org/>`_ function
        ``skimage.measure.regionprops()``.

        Note for IDL users: this provides functionality equivalent to IDL's
        REVERSE_INDICES option (as per the IDL documentation for the
        `HISTOGRAM <https://www.l3harrisgeospatial.com/docs/histogram.html>`_
        function).

        .. versionadded:: 1.10.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import ndimage
        >>> a = np.zeros((6, 6), dtype=int)
        >>> a[2:4, 2:4] = 1
        >>> a[4, 4] = 1
        >>> a[:2, :3] = 2
        >>> a[0, 5] = 3
        >>> a
        array([[2, 2, 2, 0, 0, 3],
               [2, 2, 2, 0, 0, 0],
               [0, 0, 1, 1, 0, 0],
               [0, 0, 1, 1, 0, 0],
               [0, 0, 0, 0, 1, 0],
               [0, 0, 0, 0, 0, 0]])
        >>> val_indices = ndimage.value_indices(a)

        The dictionary `val_indices` will have an entry for each distinct
        value in the input array.

        >>> val_indices.keys()
        dict_keys([np.int64(0), np.int64(1), np.int64(2), np.int64(3)])

        The entry for each value is an index tuple, locating the elements
        with that value.

        >>> ndx1 = val_indices[1]
        >>> ndx1
        (array([2, 2, 3, 3, 4]), array([2, 3, 2, 3, 4]))

        This can be used to index into the original array, or any other
        array with the same shape.

        >>> a[ndx1]
        array([1, 1, 1, 1, 1])

        If the zeros were to be ignored, then the resulting dictionary
        would no longer have an entry for zero.

        >>> val_indices = ndimage.value_indices(a, ignore_value=0)
        >>> val_indices.keys()
        dict_keys([np.int64(1), np.int64(2), np.int64(3)])

    variance(input, labels=None, index=None)
        Calculate the variance of the values of an N-D image array, optionally at
        specified sub-regions.

        Parameters
        ----------
        input : array_like
            Nd-image data to process.
        labels : array_like, optional
            Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index : int or sequence of ints, optional
            `labels` to include in output.  If None (default), all values where
            `labels` is non-zero are used.

        Returns
        -------
        variance : float or ndarray
            Values of variance, for each sub-region if `labels` and `index` are
            specified.

        See Also
        --------
        label, standard_deviation, maximum, minimum, extrema

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[1, 2, 0, 0],
        ...               [5, 3, 0, 4],
        ...               [0, 0, 0, 7],
        ...               [9, 3, 0, 0]])
        >>> from scipy import ndimage
        >>> ndimage.variance(a)
        7.609375

        Features to process can be specified using `labels` and `index`:

        >>> lbl, nlbl = ndimage.label(a)
        >>> ndimage.variance(a, lbl, index=np.arange(1, nlbl+1))
        array([ 2.1875,  2.25  ,  9.    ])

        If no index is given, all non-zero `labels` are processed:

        >>> ndimage.variance(a, lbl)
        6.1875

    watershed_ift(input, markers, structure=None, output=None)
        Apply watershed from markers using image foresting transform algorithm.

        Parameters
        ----------
        input : array_like
            Input.
        markers : array_like
            Markers are points within each watershed that form the beginning
            of the process. Negative markers are considered background markers
            which are processed after the other markers.
        structure : structure element, optional
            A structuring element defining the connectivity of the object can be
            provided. If None, an element is generated with a squared
            connectivity equal to one.
        output : ndarray, optional
            An output array can optionally be provided. The same shape as input.

        Returns
        -------
        watershed_ift : ndarray
            Output.  Same shape as `input`.

        References
        ----------
        .. [1] A.X. Falcao, J. Stolfi and R. de Alencar Lotufo, "The image
               foresting transform: theory, algorithms, and applications",
               Pattern Analysis and Machine Intelligence, vol. 26, pp. 19-29, 2004.

    white_tophat(input, size=None, footprint=None, structure=None, output=None, mode='reflect', cval=0.0, origin=0)
        Multidimensional white tophat filter.

        Parameters
        ----------
        input : array_like
            Input.
        size : tuple of ints
            Shape of a flat and full structuring element used for the filter.
            Optional if `footprint` or `structure` is provided.
        footprint : array of ints, optional
            Positions of elements of a flat structuring element
            used for the white tophat filter.
        structure : array of ints, optional
            Structuring element used for the filter. `structure` may be a non-flat
            structuring element. The `structure` array applies offsets to the
            pixels in a neighborhood (the offset is additive during dilation and
            subtractive during erosion)
        output : array, optional
            An array used for storing the output of the filter may be provided.
        mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
            The `mode` parameter determines how the array borders are
            handled, where `cval` is the value when mode is equal to
            'constant'. Default is 'reflect'
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'.
            Default is 0.0.
        origin : scalar, optional
            The `origin` parameter controls the placement of the filter.
            Default is 0.

        Returns
        -------
        output : ndarray
            Result of the filter of `input` with `structure`.

        See Also
        --------
        black_tophat

        Examples
        --------
        Subtract gray background from a bright peak.

        >>> from scipy.ndimage import generate_binary_structure, white_tophat
        >>> import numpy as np
        >>> square = generate_binary_structure(rank=2, connectivity=3)
        >>> bright_on_gray = np.array([[2, 3, 3, 3, 2],
        ...                            [3, 4, 5, 4, 3],
        ...                            [3, 5, 9, 5, 3],
        ...                            [3, 4, 5, 4, 3],
        ...                            [2, 3, 3, 3, 2]])
        >>> white_tophat(input=bright_on_gray, structure=square)
        array([[0, 0, 0, 0, 0],
               [0, 0, 1, 0, 0],
               [0, 1, 5, 1, 0],
               [0, 0, 1, 0, 0],
               [0, 0, 0, 0, 0]])

    zoom(input, zoom, output=None, order=3, mode='constant', cval=0.0, prefilter=True, *, grid_mode=False)
        Zoom an array.

        The array is zoomed using spline interpolation of the requested order.

        Parameters
        ----------
        input : array_like
            The input array.
        zoom : float or sequence
            The zoom factor along the axes. If a float, `zoom` is the same for each
            axis. If a sequence, `zoom` should contain one value for each axis.
        output : array or dtype, optional
            The array in which to place the output, or the dtype of the
            returned array. By default an array of the same dtype as input
            will be created.
        order : int, optional
            The order of the spline interpolation, default is 3.
            The order has to be in the range 0-5.
        mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', 'mirror', 'grid-wrap', 'wrap'}, optional
            The `mode` parameter determines how the input array is extended
            beyond its boundaries. Default is 'constant'. Behavior for each valid
            value is as follows (see additional plots and details on
            :ref:`boundary modes <ndimage-interpolation-modes>`):

            'reflect' (`d c b a | a b c d | d c b a`)
                The input is extended by reflecting about the edge of the last
                pixel. This mode is also sometimes referred to as half-sample
                symmetric.

            'grid-mirror'
                This is a synonym for 'reflect'.

            'constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. No
                interpolation is performed beyond the edges of the input.

            'grid-constant' (`k k k k | a b c d | k k k k`)
                The input is extended by filling all values beyond the edge with
                the same constant value, defined by the `cval` parameter. Interpolation
                occurs for samples outside the input's extent  as well.

            'nearest' (`a a a a | a b c d | d d d d`)
                The input is extended by replicating the last pixel.

            'mirror' (`d c b | a b c d | c b a`)
                The input is extended by reflecting about the center of the last
                pixel. This mode is also sometimes referred to as whole-sample
                symmetric.

            'grid-wrap' (`a b c d | a b c d | a b c d`)
                The input is extended by wrapping around to the opposite edge.

            'wrap' (`d b c d | a b c d | b c a b`)
                The input is extended by wrapping around to the opposite edge, but in a
                way such that the last point and initial point exactly overlap. In this
                case it is not well defined which sample will be chosen at the point of
                overlap.
        cval : scalar, optional
            Value to fill past edges of input if `mode` is 'constant'. Default
            is 0.0.
        prefilter : bool, optional
            Determines if the input array is prefiltered with `spline_filter`
            before interpolation. The default is True, which will create a
            temporary `float64` array of filtered values if `order > 1`. If
            setting this to False, the output will be slightly blurred if
            `order > 1`, unless the input is prefiltered, i.e. it is the result
            of calling `spline_filter` on the original input.
        grid_mode : bool, optional
            If False, the distance from the pixel centers is zoomed. Otherwise, the
            distance including the full pixel extent is used. For example, a 1d
            signal of length 5 is considered to have length 4 when `grid_mode` is
            False, but length 5 when `grid_mode` is True. See the following
            visual illustration:

            .. code-block:: text

                    | pixel 1 | pixel 2 | pixel 3 | pixel 4 | pixel 5 |
                         |<-------------------------------------->|
                                            vs.
                    |<----------------------------------------------->|

            The starting point of the arrow in the diagram above corresponds to
            coordinate location 0 in each mode.

        Returns
        -------
        zoom : ndarray
            The zoomed input.

        Notes
        -----
        For complex-valued `input`, this function zooms the real and imaginary
        components independently.

        .. versionadded:: 1.6.0
            Complex-valued support added.

        Examples
        --------
        >>> from scipy import ndimage, datasets
        >>> import matplotlib.pyplot as plt

        >>> fig = plt.figure()
        >>> ax1 = fig.add_subplot(121)  # left side
        >>> ax2 = fig.add_subplot(122)  # right side
        >>> ascent = datasets.ascent()
        >>> result = ndimage.zoom(ascent, 3.0)
        >>> ax1.imshow(ascent, vmin=0, vmax=255)
        >>> ax2.imshow(result, vmin=0, vmax=255)
        >>> plt.show()

        >>> print(ascent.shape)
        (512, 512)

        >>> print(result.shape)
        (1536, 1536)

DATA
    __all__ = ['affine_transform', 'binary_closing', 'binary_dilation', 'b...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\ndimage\__init__.py

scipy.odr
Python Library Documentation: package scipy.odr in scipy

NAME
    scipy.odr

DESCRIPTION
    =================================================
    Orthogonal distance regression (:mod:`scipy.odr`)
    =================================================

    .. currentmodule:: scipy.odr

    Package Content
    ===============

    .. autosummary::
       :toctree: generated/

       Data          -- The data to fit.
       RealData      -- Data with weights as actual std. dev.s and/or covariances.
       Model         -- Stores information about the function to be fit.
       ODR           -- Gathers all info & manages the main fitting routine.
       Output        -- Result from the fit.
       odr           -- Low-level function for ODR.

       OdrWarning    -- Warning about potential problems when running ODR.
       OdrError      -- Error exception.
       OdrStop       -- Stop exception.

       polynomial    -- Factory function for a general polynomial model.
       exponential   -- Exponential model
       multilinear   -- Arbitrary-dimensional linear model
       unilinear     -- Univariate linear model
       quadratic     -- Quadratic model

    Usage information
    =================

    Introduction
    ------------

    Why Orthogonal Distance Regression (ODR)? Sometimes one has
    measurement errors in the explanatory (a.k.a., "independent")
    variable(s), not just the response (a.k.a., "dependent") variable(s).
    Ordinary Least Squares (OLS) fitting procedures treat the data for
    explanatory variables as fixed, i.e., not subject to error of any kind.
    Furthermore, OLS procedures require that the response variables be an
    explicit function of the explanatory variables; sometimes making the
    equation explicit is impractical and/or introduces errors.  ODR can
    handle both of these cases with ease, and can even reduce to the OLS
    case if that is sufficient for the problem.

    ODRPACK is a FORTRAN-77 library for performing ODR with possibly
    non-linear fitting functions. It uses a modified trust-region
    Levenberg-Marquardt-type algorithm [1]_ to estimate the function
    parameters.  The fitting functions are provided by Python functions
    operating on NumPy arrays. The required derivatives may be provided
    by Python functions as well, or may be estimated numerically. ODRPACK
    can do explicit or implicit ODR fits, or it can do OLS. Input and
    output variables may be multidimensional. Weights can be provided to
    account for different variances of the observations, and even
    covariances between dimensions of the variables.

    The `scipy.odr` package offers an object-oriented interface to
    ODRPACK, in addition to the low-level `odr` function.

    Additional background information about ODRPACK can be found in the
    `ODRPACK User's Guide
    <https://docs.scipy.org/doc/external/odrpack_guide.pdf>`_, reading
    which is recommended.

    Basic usage
    -----------

    1. Define the function you want to fit against.::

           def f(B, x):
               '''Linear function y = m*x + b'''
               # B is a vector of the parameters.
               # x is an array of the current x values.
               # x is in the same format as the x passed to Data or RealData.
               #
               # Return an array in the same format as y passed to Data or RealData.
               return B[0]*x + B[1]

    2. Create a Model.::

           linear = Model(f)

    3. Create a Data or RealData instance.::

           mydata = Data(x, y, wd=1./power(sx,2), we=1./power(sy,2))

       or, when the actual covariances are known::

           mydata = RealData(x, y, sx=sx, sy=sy)

    4. Instantiate ODR with your data, model and initial parameter estimate.::

           myodr = ODR(mydata, linear, beta0=[1., 2.])

    5. Run the fit.::

           myoutput = myodr.run()

    6. Examine output.::

           myoutput.pprint()


    References
    ----------
    .. [1] P. T. Boggs and J. E. Rogers, "Orthogonal Distance Regression,"
       in "Statistical analysis of measurement error models and
       applications: proceedings of the AMS-IMS-SIAM joint summer research
       conference held June 10-16, 1989," Contemporary Mathematics,
       vol. 112, pg. 186, 1990.

PACKAGE CONTENTS
    __odrpack
    _add_newdocs
    _models
    _odrpack
    models
    odrpack
    tests (package)

CLASSES
    builtins.Exception(builtins.BaseException)
        scipy.odr._odrpack.OdrError
        scipy.odr._odrpack.OdrStop
    builtins.UserWarning(builtins.Warning)
        scipy.odr._odrpack.OdrWarning
    builtins.object
        scipy.odr._odrpack.Data
            scipy.odr._odrpack.RealData
        scipy.odr._odrpack.Model
        scipy.odr._odrpack.ODR
        scipy.odr._odrpack.Output

    class Data(builtins.object)
     |  Data(x, y=None, we=None, wd=None, fix=None, meta=None)
     |
     |  The data to fit.
     |
     |  Parameters
     |  ----------
     |  x : array_like
     |      Observed data for the independent variable of the regression
     |  y : array_like, optional
     |      If array-like, observed data for the dependent variable of the
     |      regression. A scalar input implies that the model to be used on
     |      the data is implicit.
     |  we : array_like, optional
     |      If `we` is a scalar, then that value is used for all data points (and
     |      all dimensions of the response variable).
     |      If `we` is a rank-1 array of length q (the dimensionality of the
     |      response variable), then this vector is the diagonal of the covariant
     |      weighting matrix for all data points.
     |      If `we` is a rank-1 array of length n (the number of data points), then
     |      the i'th element is the weight for the i'th response variable
     |      observation (single-dimensional only).
     |      If `we` is a rank-2 array of shape (q, q), then this is the full
     |      covariant weighting matrix broadcast to each observation.
     |      If `we` is a rank-2 array of shape (q, n), then `we[:,i]` is the
     |      diagonal of the covariant weighting matrix for the i'th observation.
     |      If `we` is a rank-3 array of shape (q, q, n), then `we[:,:,i]` is the
     |      full specification of the covariant weighting matrix for each
     |      observation.
     |      If the fit is implicit, then only a positive scalar value is used.
     |  wd : array_like, optional
     |      If `wd` is a scalar, then that value is used for all data points
     |      (and all dimensions of the input variable). If `wd` = 0, then the
     |      covariant weighting matrix for each observation is set to the identity
     |      matrix (so each dimension of each observation has the same weight).
     |      If `wd` is a rank-1 array of length m (the dimensionality of the input
     |      variable), then this vector is the diagonal of the covariant weighting
     |      matrix for all data points.
     |      If `wd` is a rank-1 array of length n (the number of data points), then
     |      the i'th element is the weight for the ith input variable observation
     |      (single-dimensional only).
     |      If `wd` is a rank-2 array of shape (m, m), then this is the full
     |      covariant weighting matrix broadcast to each observation.
     |      If `wd` is a rank-2 array of shape (m, n), then `wd[:,i]` is the
     |      diagonal of the covariant weighting matrix for the ith observation.
     |      If `wd` is a rank-3 array of shape (m, m, n), then `wd[:,:,i]` is the
     |      full specification of the covariant weighting matrix for each
     |      observation.
     |  fix : array_like of ints, optional
     |      The `fix` argument is the same as ifixx in the class ODR. It is an
     |      array of integers with the same shape as data.x that determines which
     |      input observations are treated as fixed. One can use a sequence of
     |      length m (the dimensionality of the input observations) to fix some
     |      dimensions for all observations. A value of 0 fixes the observation,
     |      a value > 0 makes it free.
     |  meta : dict, optional
     |      Free-form dictionary for metadata.
     |
     |  Notes
     |  -----
     |  Each argument is attached to the member of the instance of the same name.
     |  The structures of `x` and `y` are described in the Model class docstring.
     |  If `y` is an integer, then the Data instance can only be used to fit with
     |  implicit models where the dimensionality of the response is equal to the
     |  specified value of `y`.
     |
     |  The `we` argument weights the effect a deviation in the response variable
     |  has on the fit. The `wd` argument weights the effect a deviation in the
     |  input variable has on the fit. To handle multidimensional inputs and
     |  responses easily, the structure of these arguments has the n'th
     |  dimensional axis first. These arguments heavily use the structured
     |  arguments feature of ODRPACK to conveniently and flexibly support all
     |  options. See the ODRPACK User's Guide for a full explanation of how these
     |  weights are used in the algorithm. Basically, a higher value of the weight
     |  for a particular data point makes a deviation at that point more
     |  detrimental to the fit.
     |
     |  Methods defined here:
     |
     |  __getattr__(self, attr)
     |      Dispatch attribute access to the metadata dictionary.
     |
     |  __init__(self, x, y=None, we=None, wd=None, fix=None, meta=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  set_meta(self, **kwds)
     |      Update the metadata dictionary with the keywords and data provided
     |      by keywords.
     |
     |      Examples
     |      --------
     |      ::
     |
     |          data.set_meta(lab="Ph 7; Lab 26", title="Ag110 + Ag108 Decay")
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class Model(builtins.object)
     |  Model(fcn, fjacb=None, fjacd=None, extra_args=None, estimate=None, implicit=0, meta=None)
     |
     |  The Model class stores information about the function you wish to fit.
     |
     |  It stores the function itself, at the least, and optionally stores
     |  functions which compute the Jacobians used during fitting. Also, one
     |  can provide a function that will provide reasonable starting values
     |  for the fit parameters possibly given the set of data.
     |
     |  Parameters
     |  ----------
     |  fcn : function
     |        fcn(beta, x) --> y
     |  fjacb : function
     |        Jacobian of fcn wrt the fit parameters beta.
     |
     |        fjacb(beta, x) --> @f_i(x,B)/@B_j
     |  fjacd : function
     |        Jacobian of fcn wrt the (possibly multidimensional) input
     |        variable.
     |
     |        fjacd(beta, x) --> @f_i(x,B)/@x_j
     |  extra_args : tuple, optional
     |        If specified, `extra_args` should be a tuple of extra
     |        arguments to pass to `fcn`, `fjacb`, and `fjacd`. Each will be called
     |        by `apply(fcn, (beta, x) + extra_args)`
     |  estimate : array_like of rank-1
     |        Provides estimates of the fit parameters from the data
     |
     |        estimate(data) --> estbeta
     |  implicit : boolean
     |        If TRUE, specifies that the model
     |        is implicit; i.e `fcn(beta, x)` ~= 0 and there is no y data to fit
     |        against
     |  meta : dict, optional
     |        freeform dictionary of metadata for the model
     |
     |  Notes
     |  -----
     |  Note that the `fcn`, `fjacb`, and `fjacd` operate on NumPy arrays and
     |  return a NumPy array. The `estimate` object takes an instance of the
     |  Data class.
     |
     |  Here are the rules for the shapes of the argument and return
     |  arrays of the callback functions:
     |
     |  `x`
     |      if the input data is single-dimensional, then `x` is rank-1
     |      array; i.e., ``x = array([1, 2, 3, ...]); x.shape = (n,)``
     |      If the input data is multi-dimensional, then `x` is a rank-2 array;
     |      i.e., ``x = array([[1, 2, ...], [2, 4, ...]]); x.shape = (m, n)``.
     |      In all cases, it has the same shape as the input data array passed to
     |      `~scipy.odr.odr`. `m` is the dimensionality of the input data,
     |      `n` is the number of observations.
     |  `y`
     |      if the response variable is single-dimensional, then `y` is a
     |      rank-1 array, i.e., ``y = array([2, 4, ...]); y.shape = (n,)``.
     |      If the response variable is multi-dimensional, then `y` is a rank-2
     |      array, i.e., ``y = array([[2, 4, ...], [3, 6, ...]]); y.shape =
     |      (q, n)`` where `q` is the dimensionality of the response variable.
     |  `beta`
     |      rank-1 array of length `p` where `p` is the number of parameters;
     |      i.e. ``beta = array([B_1, B_2, ..., B_p])``
     |  `fjacb`
     |      if the response variable is multi-dimensional, then the
     |      return array's shape is `(q, p, n)` such that ``fjacb(x,beta)[l,k,i] =
     |      d f_l(X,B)/d B_k`` evaluated at the ith data point.  If `q == 1`, then
     |      the return array is only rank-2 and with shape `(p, n)`.
     |  `fjacd`
     |      as with fjacb, only the return array's shape is `(q, m, n)`
     |      such that ``fjacd(x,beta)[l,j,i] = d f_l(X,B)/d X_j`` at the ith data
     |      point.  If `q == 1`, then the return array's shape is `(m, n)`. If
     |      `m == 1`, the shape is (q, n). If `m == q == 1`, the shape is `(n,)`.
     |
     |  Methods defined here:
     |
     |  __getattr__(self, attr)
     |      Dispatch attribute access to the metadata.
     |
     |  __init__(self, fcn, fjacb=None, fjacd=None, extra_args=None, estimate=None, implicit=0, meta=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  set_meta(self, **kwds)
     |      Update the metadata dictionary with the keywords and data provided
     |      here.
     |
     |      Examples
     |      --------
     |      set_meta(name="Exponential", equation="y = a exp(b x) + c")
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ODR(builtins.object)
     |  ODR(data, model, beta0=None, delta0=None, ifixb=None, ifixx=None, job=None, iprint=None, errfile=None, rptfile=None, ndigit=None, taufac=None, sstol=None, partol=None, maxit=None, stpb=None, stpd=None, sclb=None, scld=None, work=None, iwork=None, overwrite=False)
     |
     |  The ODR class gathers all information and coordinates the running of the
     |  main fitting routine.
     |
     |  Members of instances of the ODR class have the same names as the arguments
     |  to the initialization routine.
     |
     |  Parameters
     |  ----------
     |  data : Data class instance
     |      instance of the Data class
     |  model : Model class instance
     |      instance of the Model class
     |
     |  Other Parameters
     |  ----------------
     |  beta0 : array_like of rank-1
     |      a rank-1 sequence of initial parameter values. Optional if
     |      model provides an "estimate" function to estimate these values.
     |  delta0 : array_like of floats of rank-1, optional
     |      a (double-precision) float array to hold the initial values of
     |      the errors in the input variables. Must be same shape as data.x
     |  ifixb : array_like of ints of rank-1, optional
     |      sequence of integers with the same length as beta0 that determines
     |      which parameters are held fixed. A value of 0 fixes the parameter,
     |      a value > 0 makes the parameter free.
     |  ifixx : array_like of ints with same shape as data.x, optional
     |      an array of integers with the same shape as data.x that determines
     |      which input observations are treated as fixed. One can use a sequence
     |      of length m (the dimensionality of the input observations) to fix some
     |      dimensions for all observations. A value of 0 fixes the observation,
     |      a value > 0 makes it free.
     |  job : int, optional
     |      an integer telling ODRPACK what tasks to perform. See p. 31 of the
     |      ODRPACK User's Guide if you absolutely must set the value here. Use the
     |      method set_job post-initialization for a more readable interface.
     |  iprint : int, optional
     |      an integer telling ODRPACK what to print. See pp. 33-34 of the
     |      ODRPACK User's Guide if you absolutely must set the value here. Use the
     |      method set_iprint post-initialization for a more readable interface.
     |  errfile : str, optional
     |      string with the filename to print ODRPACK errors to. If the file already
     |      exists, an error will be thrown. The `overwrite` argument can be used to
     |      prevent this. *Do Not Open This File Yourself!*
     |  rptfile : str, optional
     |      string with the filename to print ODRPACK summaries to. If the file
     |      already exists, an error will be thrown. The `overwrite` argument can be
     |      used to prevent this. *Do Not Open This File Yourself!*
     |  ndigit : int, optional
     |      integer specifying the number of reliable digits in the computation
     |      of the function.
     |  taufac : float, optional
     |      float specifying the initial trust region. The default value is 1.
     |      The initial trust region is equal to taufac times the length of the
     |      first computed Gauss-Newton step. taufac must be less than 1.
     |  sstol : float, optional
     |      float specifying the tolerance for convergence based on the relative
     |      change in the sum-of-squares. The default value is eps**(1/2) where eps
     |      is the smallest value such that 1 + eps > 1 for double precision
     |      computation on the machine. sstol must be less than 1.
     |  partol : float, optional
     |      float specifying the tolerance for convergence based on the relative
     |      change in the estimated parameters. The default value is eps**(2/3) for
     |      explicit models and ``eps**(1/3)`` for implicit models. partol must be less
     |      than 1.
     |  maxit : int, optional
     |      integer specifying the maximum number of iterations to perform. For
     |      first runs, maxit is the total number of iterations performed and
     |      defaults to 50. For restarts, maxit is the number of additional
     |      iterations to perform and defaults to 10.
     |  stpb : array_like, optional
     |      sequence (``len(stpb) == len(beta0)``) of relative step sizes to compute
     |      finite difference derivatives wrt the parameters.
     |  stpd : optional
     |      array (``stpd.shape == data.x.shape`` or ``stpd.shape == (m,)``) of relative
     |      step sizes to compute finite difference derivatives wrt the input
     |      variable errors. If stpd is a rank-1 array with length m (the
     |      dimensionality of the input variable), then the values are broadcast to
     |      all observations.
     |  sclb : array_like, optional
     |      sequence (``len(stpb) == len(beta0)``) of scaling factors for the
     |      parameters. The purpose of these scaling factors are to scale all of
     |      the parameters to around unity. Normally appropriate scaling factors
     |      are computed if this argument is not specified. Specify them yourself
     |      if the automatic procedure goes awry.
     |  scld : array_like, optional
     |      array (scld.shape == data.x.shape or scld.shape == (m,)) of scaling
     |      factors for the *errors* in the input variables. Again, these factors
     |      are automatically computed if you do not provide them. If scld.shape ==
     |      (m,), then the scaling factors are broadcast to all observations.
     |  work : ndarray, optional
     |      array to hold the double-valued working data for ODRPACK. When
     |      restarting, takes the value of self.output.work.
     |  iwork : ndarray, optional
     |      array to hold the integer-valued working data for ODRPACK. When
     |      restarting, takes the value of self.output.iwork.
     |  overwrite : bool, optional
     |      If it is True, output files defined by `errfile` and `rptfile` are
     |      overwritten. The default is False.
     |
     |  Attributes
     |  ----------
     |  data : Data
     |      The data for this fit
     |  model : Model
     |      The model used in fit
     |  output : Output
     |      An instance if the Output class containing all of the returned
     |      data from an invocation of ODR.run() or ODR.restart()
     |
     |  Methods defined here:
     |
     |  __init__(self, data, model, beta0=None, delta0=None, ifixb=None, ifixx=None, job=None, iprint=None, errfile=None, rptfile=None, ndigit=None, taufac=None, sstol=None, partol=None, maxit=None, stpb=None, stpd=None, sclb=None, scld=None, work=None, iwork=None, overwrite=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  restart(self, iter=None)
     |      Restarts the run with iter more iterations.
     |
     |      Parameters
     |      ----------
     |      iter : int, optional
     |          ODRPACK's default for the number of new iterations is 10.
     |
     |      Returns
     |      -------
     |      output : Output instance
     |          This object is also assigned to the attribute .output .
     |
     |  run(self)
     |      Run the fitting routine with all of the information given and with ``full_output=1``.
     |
     |      Returns
     |      -------
     |      output : Output instance
     |          This object is also assigned to the attribute .output .
     |
     |  set_iprint(self, init=None, so_init=None, iter=None, so_iter=None, iter_step=None, final=None, so_final=None)
     |      Set the iprint parameter for the printing of computation reports.
     |
     |      If any of the arguments are specified here, then they are set in the
     |      iprint member. If iprint is not set manually or with this method, then
     |      ODRPACK defaults to no printing. If no filename is specified with the
     |      member rptfile, then ODRPACK prints to stdout. One can tell ODRPACK to
     |      print to stdout in addition to the specified filename by setting the
     |      so_* arguments to this function, but one cannot specify to print to
     |      stdout but not a file since one can do that by not specifying a rptfile
     |      filename.
     |
     |      There are three reports: initialization, iteration, and final reports.
     |      They are represented by the arguments init, iter, and final
     |      respectively.  The permissible values are 0, 1, and 2 representing "no
     |      report", "short report", and "long report" respectively.
     |
     |      The argument iter_step (0 <= iter_step <= 9) specifies how often to make
     |      the iteration report; the report will be made for every iter_step'th
     |      iteration starting with iteration one. If iter_step == 0, then no
     |      iteration report is made, regardless of the other arguments.
     |
     |      If the rptfile is None, then any so_* arguments supplied will raise an
     |      exception.
     |
     |  set_job(self, fit_type=None, deriv=None, var_calc=None, del_init=None, restart=None)
     |      Sets the "job" parameter is a hopefully comprehensible way.
     |
     |      If an argument is not specified, then the value is left as is. The
     |      default value from class initialization is for all of these options set
     |      to 0.
     |
     |      Parameters
     |      ----------
     |      fit_type : {0, 1, 2} int
     |          0 -> explicit ODR
     |
     |          1 -> implicit ODR
     |
     |          2 -> ordinary least-squares
     |      deriv : {0, 1, 2, 3} int
     |          0 -> forward finite differences
     |
     |          1 -> central finite differences
     |
     |          2 -> user-supplied derivatives (Jacobians) with results
     |            checked by ODRPACK
     |
     |          3 -> user-supplied derivatives, no checking
     |      var_calc : {0, 1, 2} int
     |          0 -> calculate asymptotic covariance matrix and fit
     |               parameter uncertainties (V_B, s_B) using derivatives
     |               recomputed at the final solution
     |
     |          1 -> calculate V_B and s_B using derivatives from last iteration
     |
     |          2 -> do not calculate V_B and s_B
     |      del_init : {0, 1} int
     |          0 -> initial input variable offsets set to 0
     |
     |          1 -> initial offsets provided by user in variable "work"
     |      restart : {0, 1} int
     |          0 -> fit is not a restart
     |
     |          1 -> fit is a restart
     |
     |      Notes
     |      -----
     |      The permissible values are different from those given on pg. 31 of the
     |      ODRPACK User's Guide only in that one cannot specify numbers greater than
     |      the last value for each variable.
     |
     |      If one does not supply functions to compute the Jacobians, the fitting
     |      procedure will change deriv to 0, finite differences, as a default. To
     |      initialize the input variable offsets by yourself, set del_init to 1 and
     |      put the offsets into the "work" variable correctly.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class OdrError(builtins.Exception)
     |  Exception indicating an error in fitting.
     |
     |  This is raised by `~scipy.odr.odr` if an error occurs during fitting.
     |
     |  Method resolution order:
     |      OdrError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Exception:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Exception:
     |
     |  __new__(*args, **kwargs) class method of builtins.Exception
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class OdrStop(builtins.Exception)
     |  Exception stopping fitting.
     |
     |  You can raise this exception in your objective function to tell
     |  `~scipy.odr.odr` to stop fitting.
     |
     |  Method resolution order:
     |      OdrStop
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Exception:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Exception:
     |
     |  __new__(*args, **kwargs) class method of builtins.Exception
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class OdrWarning(builtins.UserWarning)
     |  Warning indicating that the data passed into
     |  ODR will cause problems when passed into 'odr'
     |  that the user should be aware of.
     |
     |  Method resolution order:
     |      OdrWarning
     |      builtins.UserWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.UserWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.UserWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.UserWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class Output(builtins.object)
     |  Output(output)
     |
     |  The Output class stores the output of an ODR run.
     |
     |  Attributes
     |  ----------
     |  beta : ndarray
     |      Estimated parameter values, of shape (q,).
     |  sd_beta : ndarray
     |      Standard deviations of the estimated parameters, of shape (p,).
     |  cov_beta : ndarray
     |      Covariance matrix of the estimated parameters, of shape (p,p).
     |      Note that this `cov_beta` is not scaled by the residual variance
     |      `res_var`, whereas `sd_beta` is. This means
     |      ``np.sqrt(np.diag(output.cov_beta * output.res_var))`` is the same
     |      result as `output.sd_beta`.
     |  delta : ndarray, optional
     |      Array of estimated errors in input variables, of same shape as `x`.
     |  eps : ndarray, optional
     |      Array of estimated errors in response variables, of same shape as `y`.
     |  xplus : ndarray, optional
     |      Array of ``x + delta``.
     |  y : ndarray, optional
     |      Array ``y = fcn(x + delta)``.
     |  res_var : float, optional
     |      Residual variance.
     |  sum_square : float, optional
     |      Sum of squares error.
     |  sum_square_delta : float, optional
     |      Sum of squares of delta error.
     |  sum_square_eps : float, optional
     |      Sum of squares of eps error.
     |  inv_condnum : float, optional
     |      Inverse condition number (cf. ODRPACK UG p. 77).
     |  rel_error : float, optional
     |      Relative error in function values computed within fcn.
     |  work : ndarray, optional
     |      Final work array.
     |  work_ind : dict, optional
     |      Indices into work for drawing out values (cf. ODRPACK UG p. 83).
     |  info : int, optional
     |      Reason for returning, as output by ODRPACK (cf. ODRPACK UG p. 38).
     |  stopreason : list of str, optional
     |      `info` interpreted into English.
     |
     |  Notes
     |  -----
     |  Takes one argument for initialization, the return value from the
     |  function `~scipy.odr.odr`. The attributes listed as "optional" above are
     |  only present if `~scipy.odr.odr` was run with ``full_output=1``.
     |
     |  Methods defined here:
     |
     |  __init__(self, output)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  pprint(self)
     |      Pretty-print important results.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class RealData(Data)
     |  RealData(x, y=None, sx=None, sy=None, covx=None, covy=None, fix=None, meta=None)
     |
     |  The data, with weightings as actual standard deviations and/or
     |  covariances.
     |
     |  Parameters
     |  ----------
     |  x : array_like
     |      Observed data for the independent variable of the regression
     |  y : array_like, optional
     |      If array-like, observed data for the dependent variable of the
     |      regression. A scalar input implies that the model to be used on
     |      the data is implicit.
     |  sx : array_like, optional
     |      Standard deviations of `x`.
     |      `sx` are standard deviations of `x` and are converted to weights by
     |      dividing 1.0 by their squares.
     |  sy : array_like, optional
     |      Standard deviations of `y`.
     |      `sy` are standard deviations of `y` and are converted to weights by
     |      dividing 1.0 by their squares.
     |  covx : array_like, optional
     |      Covariance of `x`
     |      `covx` is an array of covariance matrices of `x` and are converted to
     |      weights by performing a matrix inversion on each observation's
     |      covariance matrix.
     |  covy : array_like, optional
     |      Covariance of `y`
     |      `covy` is an array of covariance matrices and are converted to
     |      weights by performing a matrix inversion on each observation's
     |      covariance matrix.
     |  fix : array_like, optional
     |      The argument and member fix is the same as Data.fix and ODR.ifixx:
     |      It is an array of integers with the same shape as `x` that
     |      determines which input observations are treated as fixed. One can
     |      use a sequence of length m (the dimensionality of the input
     |      observations) to fix some dimensions for all observations. A value
     |      of 0 fixes the observation, a value > 0 makes it free.
     |  meta : dict, optional
     |      Free-form dictionary for metadata.
     |
     |  Notes
     |  -----
     |  The weights `wd` and `we` are computed from provided values as follows:
     |
     |  `sx` and `sy` are converted to weights by dividing 1.0 by their squares.
     |  For example, ``wd = 1./np.power(`sx`, 2)``.
     |
     |  `covx` and `covy` are arrays of covariance matrices and are converted to
     |  weights by performing a matrix inversion on each observation's covariance
     |  matrix. For example, ``we[i] = np.linalg.inv(covy[i])``.
     |
     |  These arguments follow the same structured argument conventions as wd and
     |  we only restricted by their natures: `sx` and `sy` can't be rank-3, but
     |  `covx` and `covy` can be.
     |
     |  Only set *either* `sx` or `covx` (not both). Setting both will raise an
     |  exception. Same with `sy` and `covy`.
     |
     |  Method resolution order:
     |      RealData
     |      Data
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __getattr__(self, attr)
     |      Dispatch attribute access to the metadata dictionary.
     |
     |  __init__(self, x, y=None, sx=None, sy=None, covx=None, covy=None, fix=None, meta=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from Data:
     |
     |  set_meta(self, **kwds)
     |      Update the metadata dictionary with the keywords and data provided
     |      by keywords.
     |
     |      Examples
     |      --------
     |      ::
     |
     |          data.set_meta(lab="Ph 7; Lab 26", title="Ag110 + Ag108 Decay")
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Data:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    odr(...)
        odr(fcn, beta0, y, x, we=None, wd=None, fjacb=None, fjacd=None, extra_args=None,
            ifixx=None, ifixb=None, job=0, iprint=0, errfile=None, rptfile=None, ndigit=0,
            taufac=0.0, sstol=-1.0, partol=-1.0, maxit=-1, stpb=None, stpd=None, sclb=None,
            scld=None, work=None, iwork=None, full_output=0)

        Low-level function for ODR.

        See Also
        --------
        ODR : The ODR class gathers all information and coordinates the running of the
              main fitting routine.
        Model : The Model class stores information about the function you wish to fit.
        Data : The data to fit.
        RealData : Data with weights as actual std. dev.s and/or covariances.

        Notes
        -----
        This is a function performing the same operation as the `ODR`,
        `Model`, and `Data` classes together. The parameters of this
        function are explained in the class documentation.

    polynomial(order)
        Factory function for a general polynomial model.

        Parameters
        ----------
        order : int or sequence
            If an integer, it becomes the order of the polynomial to fit. If
            a sequence of numbers, then these are the explicit powers in the
            polynomial.
            A constant term (power 0) is always included, so don't include 0.
            Thus, polynomial(n) is equivalent to polynomial(range(1, n+1)).

        Returns
        -------
        polynomial : Model instance
            Model instance.

        Examples
        --------
        We can fit an input data using orthogonal distance regression (ODR) with
        a polynomial model:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import odr
        >>> x = np.linspace(0.0, 5.0)
        >>> y = np.sin(x)
        >>> poly_model = odr.polynomial(3)  # using third order polynomial model
        >>> data = odr.Data(x, y)
        >>> odr_obj = odr.ODR(data, poly_model)
        >>> output = odr_obj.run()  # running ODR fitting
        >>> poly = np.poly1d(output.beta[::-1])
        >>> poly_y = poly(x)
        >>> plt.plot(x, y, label="input data")
        >>> plt.plot(x, poly_y, label="polynomial ODR")
        >>> plt.legend()
        >>> plt.show()

DATA
    __all__ = ['Data', 'Model', 'ODR', 'OdrError', 'OdrStop', 'OdrWarning'...
    exponential = <scipy.odr._models._ExponentialModel object>
    multilinear = <scipy.odr._models._MultilinearModel object>
    quadratic = <scipy.odr._models._QuadraticModel object>
    unilinear = <scipy.odr._models._UnilinearModel object>

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\odr\__init__.py

scipy.optimize
Python Library Documentation: package scipy.optimize in scipy

NAME
    scipy.optimize

DESCRIPTION
    =====================================================
    Optimization and root finding (:mod:`scipy.optimize`)
    =====================================================

    .. currentmodule:: scipy.optimize

    .. toctree::
       :hidden:

       optimize.cython_optimize

    SciPy ``optimize`` provides functions for minimizing (or maximizing)
    objective functions, possibly subject to constraints. It includes
    solvers for nonlinear problems (with support for both local and global
    optimization algorithms), linear programming, constrained
    and nonlinear least-squares, root finding, and curve fitting.

    Common functions and objects, shared across different solvers, are:

    .. autosummary::
       :toctree: generated/

       show_options - Show specific options optimization solvers.
       OptimizeResult - The optimization result returned by some optimizers.
       OptimizeWarning - The optimization encountered problems.


    Optimization
    ============

    Scalar functions optimization
    -----------------------------

    .. autosummary::
       :toctree: generated/

       minimize_scalar - Interface for minimizers of univariate functions

    The `minimize_scalar` function supports the following methods:

    .. toctree::

       optimize.minimize_scalar-brent
       optimize.minimize_scalar-bounded
       optimize.minimize_scalar-golden

    Local (multivariate) optimization
    ---------------------------------

    .. autosummary::
       :toctree: generated/

       minimize - Interface for minimizers of multivariate functions.

    The `minimize` function supports the following methods:

    .. toctree::

       optimize.minimize-neldermead
       optimize.minimize-powell
       optimize.minimize-cg
       optimize.minimize-bfgs
       optimize.minimize-newtoncg
       optimize.minimize-lbfgsb
       optimize.minimize-tnc
       optimize.minimize-cobyla
       optimize.minimize-cobyqa
       optimize.minimize-slsqp
       optimize.minimize-trustconstr
       optimize.minimize-dogleg
       optimize.minimize-trustncg
       optimize.minimize-trustkrylov
       optimize.minimize-trustexact

    Constraints are passed to `minimize` function as a single object or
    as a list of objects from the following classes:

    .. autosummary::
       :toctree: generated/

       NonlinearConstraint - Class defining general nonlinear constraints.
       LinearConstraint - Class defining general linear constraints.

    Simple bound constraints are handled separately and there is a special class
    for them:

    .. autosummary::
       :toctree: generated/

       Bounds - Bound constraints.

    Quasi-Newton strategies implementing `HessianUpdateStrategy`
    interface can be used to approximate the Hessian in `minimize`
    function (available only for the 'trust-constr' method). Available
    quasi-Newton methods implementing this interface are:

    .. autosummary::
       :toctree: generated/

       BFGS - Broyden-Fletcher-Goldfarb-Shanno (BFGS) Hessian update strategy.
       SR1 - Symmetric-rank-1 Hessian update strategy.

    .. _global_optimization:

    Global optimization
    -------------------

    .. autosummary::
       :toctree: generated/

       basinhopping - Basinhopping stochastic optimizer.
       brute - Brute force searching optimizer.
       differential_evolution - Stochastic optimizer using differential evolution.

       shgo - Simplicial homology global optimizer.
       dual_annealing - Dual annealing stochastic optimizer.
       direct - DIRECT (Dividing Rectangles) optimizer.

    Least-squares and curve fitting
    ===============================

    Nonlinear least-squares
    -----------------------

    .. autosummary::
       :toctree: generated/

       least_squares - Solve a nonlinear least-squares problem with bounds on the variables.

    Linear least-squares
    --------------------

    .. autosummary::
       :toctree: generated/

       nnls - Linear least-squares problem with non-negativity constraint.
       lsq_linear - Linear least-squares problem with bound constraints.
       isotonic_regression - Least squares problem of isotonic regression via PAVA.

    Curve fitting
    -------------

    .. autosummary::
       :toctree: generated/

       curve_fit -- Fit curve to a set of points.

    Root finding
    ============

    Scalar functions
    ----------------
    .. autosummary::
       :toctree: generated/

       root_scalar - Unified interface for nonlinear solvers of scalar functions.
       brentq - quadratic interpolation Brent method.
       brenth - Brent method, modified by Harris with hyperbolic extrapolation.
       ridder - Ridder's method.
       bisect - Bisection method.
       newton - Newton's method (also Secant and Halley's methods).
       toms748 - Alefeld, Potra & Shi Algorithm 748.
       RootResults - The root finding result returned by some root finders.

    The `root_scalar` function supports the following methods:

    .. toctree::

       optimize.root_scalar-brentq
       optimize.root_scalar-brenth
       optimize.root_scalar-bisect
       optimize.root_scalar-ridder
       optimize.root_scalar-newton
       optimize.root_scalar-toms748
       optimize.root_scalar-secant
       optimize.root_scalar-halley



    The table below lists situations and appropriate methods, along with
    *asymptotic* convergence rates per iteration (and per function evaluation)
    for successful convergence to a simple root(*).
    Bisection is the slowest of them all, adding one bit of accuracy for each
    function evaluation, but is guaranteed to converge.
    The other bracketing methods all (eventually) increase the number of accurate
    bits by about 50% for every function evaluation.
    The derivative-based methods, all built on `newton`, can converge quite quickly
    if the initial value is close to the root.  They can also be applied to
    functions defined on (a subset of) the complex plane.

    +-------------+----------+----------+-----------+-------------+-------------+----------------+
    | Domain of f | Bracket? |    Derivatives?      | Solvers     |        Convergence           |
    +             +          +----------+-----------+             +-------------+----------------+
    |             |          | `fprime` | `fprime2` |             | Guaranteed? |  Rate(s)(*)    |
    +=============+==========+==========+===========+=============+=============+================+
    | `R`         | Yes      | N/A      | N/A       | - bisection | - Yes       | - 1 "Linear"   |
    |             |          |          |           | - brentq    | - Yes       | - >=1, <= 1.62 |
    |             |          |          |           | - brenth    | - Yes       | - >=1, <= 1.62 |
    |             |          |          |           | - ridder    | - Yes       | - 2.0 (1.41)   |
    |             |          |          |           | - toms748   | - Yes       | - 2.7 (1.65)   |
    +-------------+----------+----------+-----------+-------------+-------------+----------------+
    | `R` or `C`  | No       | No       | No        | secant      | No          | 1.62 (1.62)    |
    +-------------+----------+----------+-----------+-------------+-------------+----------------+
    | `R` or `C`  | No       | Yes      | No        | newton      | No          | 2.00 (1.41)    |
    +-------------+----------+----------+-----------+-------------+-------------+----------------+
    | `R` or `C`  | No       | Yes      | Yes       | halley      | No          | 3.00 (1.44)    |
    +-------------+----------+----------+-----------+-------------+-------------+----------------+

    .. seealso::

       `scipy.optimize.cython_optimize` -- Typed Cython versions of root finding functions

    Fixed point finding:

    .. autosummary::
       :toctree: generated/

       fixed_point - Single-variable fixed-point solver.

    Multidimensional
    ----------------

    .. autosummary::
       :toctree: generated/

       root - Unified interface for nonlinear solvers of multivariate functions.

    The `root` function supports the following methods:

    .. toctree::

       optimize.root-hybr
       optimize.root-lm
       optimize.root-broyden1
       optimize.root-broyden2
       optimize.root-anderson
       optimize.root-linearmixing
       optimize.root-diagbroyden
       optimize.root-excitingmixing
       optimize.root-krylov
       optimize.root-dfsane

    Linear programming / MILP
    =========================

    .. autosummary::
       :toctree: generated/

       milp -- Mixed integer linear programming.
       linprog -- Unified interface for minimizers of linear programming problems.

    The `linprog` function supports the following methods:

    .. toctree::

       optimize.linprog-simplex
       optimize.linprog-interior-point
       optimize.linprog-revised_simplex
       optimize.linprog-highs-ipm
       optimize.linprog-highs-ds
       optimize.linprog-highs

    The simplex, interior-point, and revised simplex methods support callback
    functions, such as:

    .. autosummary::
       :toctree: generated/

       linprog_verbose_callback -- Sample callback function for linprog (simplex).

    Assignment problems
    ===================

    .. autosummary::
       :toctree: generated/

       linear_sum_assignment -- Solves the linear-sum assignment problem.
       quadratic_assignment -- Solves the quadratic assignment problem.

    The `quadratic_assignment` function supports the following methods:

    .. toctree::

       optimize.qap-faq
       optimize.qap-2opt

    Utilities
    =========

    Finite-difference approximation
    -------------------------------

    .. autosummary::
       :toctree: generated/

       approx_fprime - Approximate the gradient of a scalar function.
       check_grad - Check the supplied derivative using finite differences.


    Line search
    -----------

    .. autosummary::
       :toctree: generated/

       bracket - Bracket a minimum, given two starting points.
       line_search - Return a step that satisfies the strong Wolfe conditions.

    Hessian approximation
    ---------------------

    .. autosummary::
       :toctree: generated/

       LbfgsInvHessProduct - Linear operator for L-BFGS approximate inverse Hessian.
       HessianUpdateStrategy - Interface for implementing Hessian update strategies

    Benchmark problems
    ------------------

    .. autosummary::
       :toctree: generated/

       rosen - The Rosenbrock function.
       rosen_der - The derivative of the Rosenbrock function.
       rosen_hess - The Hessian matrix of the Rosenbrock function.
       rosen_hess_prod - Product of the Rosenbrock Hessian with a vector.

    Legacy functions
    ================

    The functions below are not recommended for use in new scripts;
    all of these methods are accessible via a newer, more consistent
    interfaces, provided by the interfaces above.

    Optimization
    ------------

    General-purpose multivariate methods:

    .. autosummary::
       :toctree: generated/

       fmin - Nelder-Mead Simplex algorithm.
       fmin_powell - Powell's (modified) conjugate direction method.
       fmin_cg - Non-linear (Polak-Ribiere) conjugate gradient algorithm.
       fmin_bfgs - Quasi-Newton method (Broydon-Fletcher-Goldfarb-Shanno).
       fmin_ncg - Line-search Newton Conjugate Gradient.

    Constrained multivariate methods:

    .. autosummary::
       :toctree: generated/

       fmin_l_bfgs_b - Zhu, Byrd, and Nocedal's constrained optimizer.
       fmin_tnc - Truncated Newton code.
       fmin_cobyla - Constrained optimization by linear approximation.
       fmin_slsqp - Minimization using sequential least-squares programming.

    Univariate (scalar) minimization methods:

    .. autosummary::
       :toctree: generated/

       fminbound - Bounded minimization of a scalar function.
       brent - 1-D function minimization using Brent method.
       golden - 1-D function minimization using Golden Section method.

    Least-squares
    -------------

    .. autosummary::
       :toctree: generated/

       leastsq - Minimize the sum of squares of M equations in N unknowns.

    Root finding
    ------------

    General nonlinear solvers:

    .. autosummary::
       :toctree: generated/

       fsolve - Non-linear multivariable equation solver.
       broyden1 - Broyden's first method.
       broyden2 - Broyden's second method.
       NoConvergence -  Exception raised when nonlinear solver does not converge.

    Large-scale nonlinear solvers:

    .. autosummary::
       :toctree: generated/

       newton_krylov
       anderson

       BroydenFirst
       InverseJacobian
       KrylovJacobian

    Simple iteration solvers:

    .. autosummary::
       :toctree: generated/

       excitingmixing
       linearmixing
       diagbroyden

PACKAGE CONTENTS
    _basinhopping
    _bglu_dense
    _bracket
    _chandrupatla
    _cobyla
    _cobyla_py
    _cobyqa_py
    _constraints
    _dcsrch
    _differentiable_functions
    _differentialevolution
    _differentiate
    _direct
    _direct_py
    _dual_annealing
    _group_columns
    _hessian_update_strategy
    _highs (package)
    _isotonic
    _lbfgsb
    _lbfgsb_py
    _linesearch
    _linprog
    _linprog_doc
    _linprog_highs
    _linprog_ip
    _linprog_rs
    _linprog_simplex
    _linprog_util
    _lsap
    _lsq (package)
    _milp
    _minimize
    _minpack
    _minpack2
    _minpack_py
    _moduleTNC
    _nnls
    _nonlin
    _numdiff
    _optimize
    _pava_pybind
    _qap
    _remove_redundancy
    _root
    _root_scalar
    _shgo
    _shgo_lib (package)
    _slsqp
    _slsqp_py
    _spectral
    _tnc
    _trlib (package)
    _trustregion
    _trustregion_constr (package)
    _trustregion_dogleg
    _trustregion_exact
    _trustregion_krylov
    _trustregion_ncg
    _tstutils
    _zeros
    _zeros_py
    cobyla
    cython_optimize (package)
    lbfgsb
    linesearch
    minpack
    minpack2
    moduleTNC
    nonlin
    optimize
    slsqp
    tests (package)
    tnc
    zeros

CLASSES
    builtins.Exception(builtins.BaseException)
        scipy.optimize._nonlin.NoConvergence
    builtins.UserWarning(builtins.Warning)
        scipy.optimize._optimize.OptimizeWarning
    builtins.object
        scipy.optimize._constraints.Bounds
        scipy.optimize._constraints.LinearConstraint
        scipy.optimize._constraints.NonlinearConstraint
        scipy.optimize._hessian_update_strategy.HessianUpdateStrategy
        scipy.optimize._nonlin.InverseJacobian
    scipy._lib._util._RichResult(builtins.dict)
        scipy.optimize._optimize.OptimizeResult
            scipy.optimize._zeros_py.RootResults
    scipy.optimize._hessian_update_strategy.FullHessianUpdateStrategy(scipy.optimize._hessian_update_strategy.HessianUpdateStrategy)
        scipy.optimize._hessian_update_strategy.BFGS
        scipy.optimize._hessian_update_strategy.SR1
    scipy.optimize._nonlin.GenericBroyden(scipy.optimize._nonlin.Jacobian)
        scipy.optimize._nonlin.BroydenFirst
    scipy.optimize._nonlin.Jacobian(builtins.object)
        scipy.optimize._nonlin.KrylovJacobian
    scipy.sparse.linalg._interface.LinearOperator(builtins.object)
        scipy.optimize._lbfgsb_py.LbfgsInvHessProduct

    class BFGS(FullHessianUpdateStrategy)
     |  BFGS(exception_strategy='skip_update', min_curvature=None, init_scale='auto')
     |
     |  Broyden-Fletcher-Goldfarb-Shanno (BFGS) Hessian update strategy.
     |
     |  Parameters
     |  ----------
     |  exception_strategy : {'skip_update', 'damp_update'}, optional
     |      Define how to proceed when the curvature condition is violated.
     |      Set it to 'skip_update' to just skip the update. Or, alternatively,
     |      set it to 'damp_update' to interpolate between the actual BFGS
     |      result and the unmodified matrix. Both exceptions strategies
     |      are explained  in [1]_, p.536-537.
     |  min_curvature : float
     |      This number, scaled by a normalization factor, defines the
     |      minimum curvature ``dot(delta_grad, delta_x)`` allowed to go
     |      unaffected by the exception strategy. By default is equal to
     |      1e-8 when ``exception_strategy = 'skip_update'`` and equal
     |      to 0.2 when ``exception_strategy = 'damp_update'``.
     |  init_scale : {float, np.array, 'auto'}
     |      This parameter can be used to initialize the Hessian or its
     |      inverse. When a float is given, the relevant array is initialized
     |      to ``np.eye(n) * init_scale``, where ``n`` is the problem dimension.
     |      Alternatively, if a precisely ``(n, n)`` shaped, symmetric array is given,
     |      this array will be used. Otherwise an error is generated.
     |      Set it to 'auto' in order to use an automatic heuristic for choosing
     |      the initial scale. The heuristic is described in [1]_, p.143.
     |      The default is 'auto'.
     |
     |  Notes
     |  -----
     |  The update is based on the description in [1]_, p.140.
     |
     |  References
     |  ----------
     |  .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
     |         Second Edition (2006).
     |
     |  Method resolution order:
     |      BFGS
     |      FullHessianUpdateStrategy
     |      HessianUpdateStrategy
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, exception_strategy='skip_update', min_curvature=None, init_scale='auto')
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from FullHessianUpdateStrategy:
     |
     |  dot(self, p)
     |      Compute the product of the internal matrix with the given vector.
     |
     |      Parameters
     |      ----------
     |      p : array_like
     |          1-D array representing a vector.
     |
     |      Returns
     |      -------
     |      Hp : array
     |          1-D represents the result of multiplying the approximation matrix
     |          by vector p.
     |
     |  get_matrix(self)
     |      Return the current internal matrix.
     |
     |      Returns
     |      -------
     |      M : ndarray, shape (n, n)
     |          Dense matrix containing either the Hessian or its inverse
     |          (depending on how `approx_type` was defined).
     |
     |  initialize(self, n, approx_type)
     |      Initialize internal matrix.
     |
     |      Allocate internal memory for storing and updating
     |      the Hessian or its inverse.
     |
     |      Parameters
     |      ----------
     |      n : int
     |          Problem dimension.
     |      approx_type : {'hess', 'inv_hess'}
     |          Selects either the Hessian or the inverse Hessian.
     |          When set to 'hess' the Hessian will be stored and updated.
     |          When set to 'inv_hess' its inverse will be used instead.
     |
     |  update(self, delta_x, delta_grad)
     |      Update internal matrix.
     |
     |      Update Hessian matrix or its inverse (depending on how 'approx_type'
     |      is defined) using information about the last evaluated points.
     |
     |      Parameters
     |      ----------
     |      delta_x : ndarray
     |          The difference between two points the gradient
     |          function have been evaluated at: ``delta_x = x2 - x1``.
     |      delta_grad : ndarray
     |          The difference between the gradients:
     |          ``delta_grad = grad(x2) - grad(x1)``.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from HessianUpdateStrategy:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class Bounds(builtins.object)
     |  Bounds(lb=-inf, ub=inf, keep_feasible=False)
     |
     |  Bounds constraint on the variables.
     |
     |  The constraint has the general inequality form::
     |
     |      lb <= x <= ub
     |
     |  It is possible to use equal bounds to represent an equality constraint or
     |  infinite bounds to represent a one-sided constraint.
     |
     |  Parameters
     |  ----------
     |  lb, ub : dense array_like, optional
     |      Lower and upper bounds on independent variables. `lb`, `ub`, and
     |      `keep_feasible` must be the same shape or broadcastable.
     |      Set components of `lb` and `ub` equal
     |      to fix a variable. Use ``np.inf`` with an appropriate sign to disable
     |      bounds on all or some variables. Note that you can mix constraints of
     |      different types: interval, one-sided or equality, by setting different
     |      components of `lb` and `ub` as necessary. Defaults to ``lb = -np.inf``
     |      and ``ub = np.inf`` (no bounds).
     |  keep_feasible : dense array_like of bool, optional
     |      Whether to keep the constraint components feasible throughout
     |      iterations. Must be broadcastable with `lb` and `ub`.
     |      Default is False. Has no effect for equality constraints.
     |
     |  Methods defined here:
     |
     |  __init__(self, lb=-inf, ub=inf, keep_feasible=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  residual(self, x)
     |      Calculate the residual (slack) between the input and the bounds
     |
     |      For a bound constraint of the form::
     |
     |          lb <= x <= ub
     |
     |      the lower and upper residuals between `x` and the bounds are values
     |      ``sl`` and ``sb`` such that::
     |
     |          lb + sl == x == ub - sb
     |
     |      When all elements of ``sl`` and ``sb`` are positive, all elements of
     |      ``x`` lie within the bounds; a negative element in ``sl`` or ``sb``
     |      indicates that the corresponding element of ``x`` is out of bounds.
     |
     |      Parameters
     |      ----------
     |      x: array_like
     |          Vector of independent variables
     |
     |      Returns
     |      -------
     |      sl, sb : array-like
     |          The lower and upper residuals
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class BroydenFirst(GenericBroyden)
     |  BroydenFirst(alpha=None, reduction_method='restart', max_rank=None)
     |
     |  Find a root of a function, using Broyden's first Jacobian approximation.
     |
     |  This method is also known as \"Broyden's good method\".
     |
     |  Parameters
     |  ----------
     |  %(params_basic)s
     |  %(broyden_params)s
     |  %(params_extra)s
     |
     |  See Also
     |  --------
     |  root : Interface to root finding algorithms for multivariate
     |         functions. See ``method='broyden1'`` in particular.
     |
     |  Notes
     |  -----
     |  This algorithm implements the inverse Jacobian Quasi-Newton update
     |
     |  .. math:: H_+ = H + (dx - H df) dx^\dagger H / ( dx^\dagger H df)
     |
     |  which corresponds to Broyden's first Jacobian update
     |
     |  .. math:: J_+ = J + (df - J dx) dx^\dagger / dx^\dagger dx
     |
     |
     |  References
     |  ----------
     |  .. [1] B.A. van der Rotten, PhD thesis,
     |     \"A limited memory Broyden method to solve high-dimensional
     |     systems of nonlinear equations\". Mathematisch Instituut,
     |     Universiteit Leiden, The Netherlands (2003).
     |
     |     https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf
     |
     |  Examples
     |  --------
     |  The following functions define a system of nonlinear equations
     |
     |  >>> def fun(x):
     |  ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
     |  ...             0.5 * (x[1] - x[0])**3 + x[1]]
     |
     |  A solution can be obtained as follows.
     |
     |  >>> from scipy import optimize
     |  >>> sol = optimize.broyden1(fun, [0, 0])
     |  >>> sol
     |  array([0.84116396, 0.15883641])
     |
     |  Method resolution order:
     |      BroydenFirst
     |      GenericBroyden
     |      Jacobian
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, alpha=None, reduction_method='restart', max_rank=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  matvec(self, f)
     |
     |  rmatvec(self, f)
     |
     |  rsolve(self, f, tol=0)
     |
     |  setup(self, x, F, func)
     |
     |  solve(self, f, tol=0)
     |
     |  todense(self)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from GenericBroyden:
     |
     |  update(self, x, f)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from Jacobian:
     |
     |  aspreconditioner(self)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Jacobian:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class HessianUpdateStrategy(builtins.object)
     |  Interface for implementing Hessian update strategies.
     |
     |  Many optimization methods make use of Hessian (or inverse Hessian)
     |  approximations, such as the quasi-Newton methods BFGS, SR1, L-BFGS.
     |  Some of these  approximations, however, do not actually need to store
     |  the entire matrix or can compute the internal matrix product with a
     |  given vector in a very efficiently manner. This class serves as an
     |  abstract interface between the optimization algorithm and the
     |  quasi-Newton update strategies, giving freedom of implementation
     |  to store and update the internal matrix as efficiently as possible.
     |  Different choices of initialization and update procedure will result
     |  in different quasi-Newton strategies.
     |
     |  Four methods should be implemented in derived classes: ``initialize``,
     |  ``update``, ``dot`` and ``get_matrix``.
     |
     |  Notes
     |  -----
     |  Any instance of a class that implements this interface,
     |  can be accepted by the method ``minimize`` and used by
     |  the compatible solvers to approximate the Hessian (or
     |  inverse Hessian) used by the optimization algorithms.
     |
     |  Methods defined here:
     |
     |  dot(self, p)
     |      Compute the product of the internal matrix with the given vector.
     |
     |      Parameters
     |      ----------
     |      p : array_like
     |          1-D array representing a vector.
     |
     |      Returns
     |      -------
     |      Hp : array
     |          1-D represents the result of multiplying the approximation matrix
     |          by vector p.
     |
     |  get_matrix(self)
     |      Return current internal matrix.
     |
     |      Returns
     |      -------
     |      H : ndarray, shape (n, n)
     |          Dense matrix containing either the Hessian
     |          or its inverse (depending on how 'approx_type'
     |          is defined).
     |
     |  initialize(self, n, approx_type)
     |      Initialize internal matrix.
     |
     |      Allocate internal memory for storing and updating
     |      the Hessian or its inverse.
     |
     |      Parameters
     |      ----------
     |      n : int
     |          Problem dimension.
     |      approx_type : {'hess', 'inv_hess'}
     |          Selects either the Hessian or the inverse Hessian.
     |          When set to 'hess' the Hessian will be stored and updated.
     |          When set to 'inv_hess' its inverse will be used instead.
     |
     |  update(self, delta_x, delta_grad)
     |      Update internal matrix.
     |
     |      Update Hessian matrix or its inverse (depending on how 'approx_type'
     |      is defined) using information about the last evaluated points.
     |
     |      Parameters
     |      ----------
     |      delta_x : ndarray
     |          The difference between two points the gradient
     |          function have been evaluated at: ``delta_x = x2 - x1``.
     |      delta_grad : ndarray
     |          The difference between the gradients:
     |          ``delta_grad = grad(x2) - grad(x1)``.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class InverseJacobian(builtins.object)
     |  InverseJacobian(jacobian)
     |
     |  Methods defined here:
     |
     |  __init__(self, jacobian)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  dtype
     |
     |  shape
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class KrylovJacobian(Jacobian)
     |  KrylovJacobian(rdiff=None, method='lgmres', inner_maxiter=20, inner_M=None, outer_k=10, **kw)
     |
     |  Find a root of a function, using Krylov approximation for inverse Jacobian.
     |
     |  This method is suitable for solving large-scale problems.
     |
     |  Parameters
     |  ----------
     |  %(params_basic)s
     |  rdiff : float, optional
     |      Relative step size to use in numerical differentiation.
     |  method : str or callable, optional
     |      Krylov method to use to approximate the Jacobian.  Can be a string,
     |      or a function implementing the same interface as the iterative
     |      solvers in `scipy.sparse.linalg`. If a string, needs to be one of:
     |      ``'lgmres'``, ``'gmres'``, ``'bicgstab'``, ``'cgs'``, ``'minres'``,
     |      ``'tfqmr'``.
     |
     |      The default is `scipy.sparse.linalg.lgmres`.
     |  inner_maxiter : int, optional
     |      Parameter to pass to the "inner" Krylov solver: maximum number of
     |      iterations. Iteration will stop after maxiter steps even if the
     |      specified tolerance has not been achieved.
     |  inner_M : LinearOperator or InverseJacobian
     |      Preconditioner for the inner Krylov iteration.
     |      Note that you can use also inverse Jacobians as (adaptive)
     |      preconditioners. For example,
     |
     |      >>> from scipy.optimize import BroydenFirst, KrylovJacobian
     |      >>> from scipy.optimize import InverseJacobian
     |      >>> jac = BroydenFirst()
     |      >>> kjac = KrylovJacobian(inner_M=InverseJacobian(jac))
     |
     |      If the preconditioner has a method named 'update', it will be called
     |      as ``update(x, f)`` after each nonlinear step, with ``x`` giving
     |      the current point, and ``f`` the current function value.
     |  outer_k : int, optional
     |      Size of the subspace kept across LGMRES nonlinear iterations.
     |      See `scipy.sparse.linalg.lgmres` for details.
     |  inner_kwargs : kwargs
     |      Keyword parameters for the "inner" Krylov solver
     |      (defined with `method`). Parameter names must start with
     |      the `inner_` prefix which will be stripped before passing on
     |      the inner method. See, e.g., `scipy.sparse.linalg.gmres` for details.
     |  %(params_extra)s
     |
     |  See Also
     |  --------
     |  root : Interface to root finding algorithms for multivariate
     |         functions. See ``method='krylov'`` in particular.
     |  scipy.sparse.linalg.gmres
     |  scipy.sparse.linalg.lgmres
     |
     |  Notes
     |  -----
     |  This function implements a Newton-Krylov solver. The basic idea is
     |  to compute the inverse of the Jacobian with an iterative Krylov
     |  method. These methods require only evaluating the Jacobian-vector
     |  products, which are conveniently approximated by a finite difference:
     |
     |  .. math:: J v \approx (f(x + \omega*v/|v|) - f(x)) / \omega
     |
     |  Due to the use of iterative matrix inverses, these methods can
     |  deal with large nonlinear problems.
     |
     |  SciPy's `scipy.sparse.linalg` module offers a selection of Krylov
     |  solvers to choose from. The default here is `lgmres`, which is a
     |  variant of restarted GMRES iteration that reuses some of the
     |  information obtained in the previous Newton steps to invert
     |  Jacobians in subsequent steps.
     |
     |  For a review on Newton-Krylov methods, see for example [1]_,
     |  and for the LGMRES sparse inverse method, see [2]_.
     |
     |  References
     |  ----------
     |  .. [1] C. T. Kelley, Solving Nonlinear Equations with Newton's Method,
     |         SIAM, pp.57-83, 2003.
     |         :doi:`10.1137/1.9780898718898.ch3`
     |  .. [2] D.A. Knoll and D.E. Keyes, J. Comp. Phys. 193, 357 (2004).
     |         :doi:`10.1016/j.jcp.2003.08.010`
     |  .. [3] A.H. Baker and E.R. Jessup and T. Manteuffel,
     |         SIAM J. Matrix Anal. Appl. 26, 962 (2005).
     |         :doi:`10.1137/S0895479803422014`
     |
     |  Examples
     |  --------
     |  The following functions define a system of nonlinear equations
     |
     |  >>> def fun(x):
     |  ...     return [x[0] + 0.5 * x[1] - 1.0,
     |  ...             0.5 * (x[1] - x[0]) ** 2]
     |
     |  A solution can be obtained as follows.
     |
     |  >>> from scipy import optimize
     |  >>> sol = optimize.newton_krylov(fun, [0, 0])
     |  >>> sol
     |  array([0.66731771, 0.66536458])
     |
     |  Method resolution order:
     |      KrylovJacobian
     |      Jacobian
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, rdiff=None, method='lgmres', inner_maxiter=20, inner_M=None, outer_k=10, **kw)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  matvec(self, v)
     |
     |  setup(self, x, f, func)
     |
     |  solve(self, rhs, tol=0)
     |
     |  update(self, x, f)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from Jacobian:
     |
     |  aspreconditioner(self)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Jacobian:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class LbfgsInvHessProduct(scipy.sparse.linalg._interface.LinearOperator)
     |  LbfgsInvHessProduct(sk, yk)
     |
     |  Linear operator for the L-BFGS approximate inverse Hessian.
     |
     |  This operator computes the product of a vector with the approximate inverse
     |  of the Hessian of the objective function, using the L-BFGS limited
     |  memory approximation to the inverse Hessian, accumulated during the
     |  optimization.
     |
     |  Objects of this class implement the ``scipy.sparse.linalg.LinearOperator``
     |  interface.
     |
     |  Parameters
     |  ----------
     |  sk : array_like, shape=(n_corr, n)
     |      Array of `n_corr` most recent updates to the solution vector.
     |      (See [1]).
     |  yk : array_like, shape=(n_corr, n)
     |      Array of `n_corr` most recent updates to the gradient. (See [1]).
     |
     |  References
     |  ----------
     |  .. [1] Nocedal, Jorge. "Updating quasi-Newton matrices with limited
     |     storage." Mathematics of computation 35.151 (1980): 773-782.
     |
     |  Method resolution order:
     |      LbfgsInvHessProduct
     |      scipy.sparse.linalg._interface.LinearOperator
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, sk, yk)
     |      Construct the operator.
     |
     |  todense(self)
     |      Return a dense array representation of this operator.
     |
     |      Returns
     |      -------
     |      arr : ndarray, shape=(n, n)
     |          An array with the same shape and containing
     |          the same data represented by this `LinearOperator`.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse.linalg._interface.LinearOperator:
     |
     |  __add__(self, x)
     |
     |  __call__(self, x)
     |      Call self as a function.
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, x)
     |
     |  __neg__(self)
     |
     |  __pow__(self, p)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, x)
     |
     |  __sub__(self, x)
     |
     |  __truediv__(self, other)
     |
     |  adjoint(self)
     |      Hermitian adjoint.
     |
     |      Returns the Hermitian adjoint of self, aka the Hermitian
     |      conjugate or Hermitian transpose. For a complex matrix, the
     |      Hermitian adjoint is equal to the conjugate transpose.
     |
     |      Can be abbreviated self.H instead of self.adjoint().
     |
     |      Returns
     |      -------
     |      A_H : LinearOperator
     |          Hermitian adjoint of self.
     |
     |  dot(self, x)
     |      Matrix-matrix or matrix-vector multiplication.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          1-d or 2-d array, representing a vector or matrix.
     |
     |      Returns
     |      -------
     |      Ax : array
     |          1-d or 2-d array (depending on the shape of x) that represents
     |          the result of applying this linear operator on x.
     |
     |  matmat(self, X)
     |      Matrix-matrix multiplication.
     |
     |      Performs the operation y=A*X where A is an MxN linear
     |      operator and X dense N*K matrix or ndarray.
     |
     |      Parameters
     |      ----------
     |      X : {matrix, ndarray}
     |          An array with shape (N,K).
     |
     |      Returns
     |      -------
     |      Y : {matrix, ndarray}
     |          A matrix or ndarray with shape (M,K) depending on
     |          the type of the X argument.
     |
     |      Notes
     |      -----
     |      This matmat wraps any user-specified matmat routine or overridden
     |      _matmat method to ensure that y has the correct type.
     |
     |  matvec(self, x)
     |      Matrix-vector multiplication.
     |
     |      Performs the operation y=A*x where A is an MxN linear
     |      operator and x is a column vector or 1-d array.
     |
     |      Parameters
     |      ----------
     |      x : {matrix, ndarray}
     |          An array with shape (N,) or (N,1).
     |
     |      Returns
     |      -------
     |      y : {matrix, ndarray}
     |          A matrix or ndarray with shape (M,) or (M,1) depending
     |          on the type and shape of the x argument.
     |
     |      Notes
     |      -----
     |      This matvec wraps the user-specified matvec routine or overridden
     |      _matvec method to ensure that y has the correct shape and type.
     |
     |  rmatmat(self, X)
     |      Adjoint matrix-matrix multiplication.
     |
     |      Performs the operation y = A^H * x where A is an MxN linear
     |      operator and x is a column vector or 1-d array, or 2-d array.
     |      The default implementation defers to the adjoint.
     |
     |      Parameters
     |      ----------
     |      X : {matrix, ndarray}
     |          A matrix or 2D array.
     |
     |      Returns
     |      -------
     |      Y : {matrix, ndarray}
     |          A matrix or 2D array depending on the type of the input.
     |
     |      Notes
     |      -----
     |      This rmatmat wraps the user-specified rmatmat routine.
     |
     |  rmatvec(self, x)
     |      Adjoint matrix-vector multiplication.
     |
     |      Performs the operation y = A^H * x where A is an MxN linear
     |      operator and x is a column vector or 1-d array.
     |
     |      Parameters
     |      ----------
     |      x : {matrix, ndarray}
     |          An array with shape (M,) or (M,1).
     |
     |      Returns
     |      -------
     |      y : {matrix, ndarray}
     |          A matrix or ndarray with shape (N,) or (N,1) depending
     |          on the type and shape of the x argument.
     |
     |      Notes
     |      -----
     |      This rmatvec wraps the user-specified rmatvec routine or overridden
     |      _rmatvec method to ensure that y has the correct shape and type.
     |
     |  transpose(self)
     |      Transpose this linear operator.
     |
     |      Returns a LinearOperator that represents the transpose of this one.
     |      Can be abbreviated self.T instead of self.transpose().
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from scipy.sparse.linalg._interface.LinearOperator:
     |
     |  __new__(cls, *args, **kwargs)
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse.linalg._interface.LinearOperator:
     |
     |  H
     |      Hermitian adjoint.
     |
     |      Returns the Hermitian adjoint of self, aka the Hermitian
     |      conjugate or Hermitian transpose. For a complex matrix, the
     |      Hermitian adjoint is equal to the conjugate transpose.
     |
     |      Can be abbreviated self.H instead of self.adjoint().
     |
     |      Returns
     |      -------
     |      A_H : LinearOperator
     |          Hermitian adjoint of self.
     |
     |  T
     |      Transpose this linear operator.
     |
     |      Returns a LinearOperator that represents the transpose of this one.
     |      Can be abbreviated self.T instead of self.transpose().
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse.linalg._interface.LinearOperator:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse.linalg._interface.LinearOperator:
     |
     |  __array_ufunc__ = None
     |
     |  ndim = 2

    class LinearConstraint(builtins.object)
     |  LinearConstraint(A, lb=-inf, ub=inf, keep_feasible=False)
     |
     |  Linear constraint on the variables.
     |
     |  The constraint has the general inequality form::
     |
     |      lb <= A.dot(x) <= ub
     |
     |  Here the vector of independent variables x is passed as ndarray of shape
     |  (n,) and the matrix A has shape (m, n).
     |
     |  It is possible to use equal bounds to represent an equality constraint or
     |  infinite bounds to represent a one-sided constraint.
     |
     |  Parameters
     |  ----------
     |  A : {array_like, sparse matrix}, shape (m, n)
     |      Matrix defining the constraint.
     |  lb, ub : dense array_like, optional
     |      Lower and upper limits on the constraint. Each array must have the
     |      shape (m,) or be a scalar, in the latter case a bound will be the same
     |      for all components of the constraint. Use ``np.inf`` with an
     |      appropriate sign to specify a one-sided constraint.
     |      Set components of `lb` and `ub` equal to represent an equality
     |      constraint. Note that you can mix constraints of different types:
     |      interval, one-sided or equality, by setting different components of
     |      `lb` and `ub` as  necessary. Defaults to ``lb = -np.inf``
     |      and ``ub = np.inf`` (no limits).
     |  keep_feasible : dense array_like of bool, optional
     |      Whether to keep the constraint components feasible throughout
     |      iterations. A single value set this property for all components.
     |      Default is False. Has no effect for equality constraints.
     |
     |  Methods defined here:
     |
     |  __init__(self, A, lb=-inf, ub=inf, keep_feasible=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  residual(self, x)
     |      Calculate the residual between the constraint function and the limits
     |
     |      For a linear constraint of the form::
     |
     |          lb <= A@x <= ub
     |
     |      the lower and upper residuals between ``A@x`` and the limits are values
     |      ``sl`` and ``sb`` such that::
     |
     |          lb + sl == A@x == ub - sb
     |
     |      When all elements of ``sl`` and ``sb`` are positive, all elements of
     |      the constraint are satisfied; a negative element in ``sl`` or ``sb``
     |      indicates that the corresponding element of the constraint is not
     |      satisfied.
     |
     |      Parameters
     |      ----------
     |      x: array_like
     |          Vector of independent variables
     |
     |      Returns
     |      -------
     |      sl, sb : array-like
     |          The lower and upper residuals
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class NoConvergence(builtins.Exception)
     |  Exception raised when nonlinear solver fails to converge within the specified
     |  `maxiter`.
     |
     |  Method resolution order:
     |      NoConvergence
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Exception:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Exception:
     |
     |  __new__(*args, **kwargs) class method of builtins.Exception
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class NonlinearConstraint(builtins.object)
     |  NonlinearConstraint(fun, lb, ub, jac='2-point', hess=<scipy.optimize._hessian_update_strategy.BFGS object at 0x000001D8F14FFC50>, keep_feasible=False, finite_diff_rel_step=None, finite_diff_jac_sparsity=None)
     |
     |  Nonlinear constraint on the variables.
     |
     |  The constraint has the general inequality form::
     |
     |      lb <= fun(x) <= ub
     |
     |  Here the vector of independent variables x is passed as ndarray of shape
     |  (n,) and ``fun`` returns a vector with m components.
     |
     |  It is possible to use equal bounds to represent an equality constraint or
     |  infinite bounds to represent a one-sided constraint.
     |
     |  Parameters
     |  ----------
     |  fun : callable
     |      The function defining the constraint.
     |      The signature is ``fun(x) -> array_like, shape (m,)``.
     |  lb, ub : array_like
     |      Lower and upper bounds on the constraint. Each array must have the
     |      shape (m,) or be a scalar, in the latter case a bound will be the same
     |      for all components of the constraint. Use ``np.inf`` with an
     |      appropriate sign to specify a one-sided constraint.
     |      Set components of `lb` and `ub` equal to represent an equality
     |      constraint. Note that you can mix constraints of different types:
     |      interval, one-sided or equality, by setting different components of
     |      `lb` and `ub` as  necessary.
     |  jac : {callable,  '2-point', '3-point', 'cs'}, optional
     |      Method of computing the Jacobian matrix (an m-by-n matrix,
     |      where element (i, j) is the partial derivative of f[i] with
     |      respect to x[j]).  The keywords {'2-point', '3-point',
     |      'cs'} select a finite difference scheme for the numerical estimation.
     |      A callable must have the following signature:
     |      ``jac(x) -> {ndarray, sparse matrix}, shape (m, n)``.
     |      Default is '2-point'.
     |  hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy, None}, optional
     |      Method for computing the Hessian matrix. The keywords
     |      {'2-point', '3-point', 'cs'} select a finite difference scheme for
     |      numerical  estimation.  Alternatively, objects implementing
     |      `HessianUpdateStrategy` interface can be used to approximate the
     |      Hessian. Currently available implementations are:
     |
     |          - `BFGS` (default option)
     |          - `SR1`
     |
     |      A callable must return the Hessian matrix of ``dot(fun, v)`` and
     |      must have the following signature:
     |      ``hess(x, v) -> {LinearOperator, sparse matrix, array_like}, shape (n, n)``.
     |      Here ``v`` is ndarray with shape (m,) containing Lagrange multipliers.
     |  keep_feasible : array_like of bool, optional
     |      Whether to keep the constraint components feasible throughout
     |      iterations. A single value set this property for all components.
     |      Default is False. Has no effect for equality constraints.
     |  finite_diff_rel_step: None or array_like, optional
     |      Relative step size for the finite difference approximation. Default is
     |      None, which will select a reasonable value automatically depending
     |      on a finite difference scheme.
     |  finite_diff_jac_sparsity: {None, array_like, sparse matrix}, optional
     |      Defines the sparsity structure of the Jacobian matrix for finite
     |      difference estimation, its shape must be (m, n). If the Jacobian has
     |      only few non-zero elements in *each* row, providing the sparsity
     |      structure will greatly speed up the computations. A zero entry means
     |      that a corresponding element in the Jacobian is identically zero.
     |      If provided, forces the use of 'lsmr' trust-region solver.
     |      If None (default) then dense differencing will be used.
     |
     |  Notes
     |  -----
     |  Finite difference schemes {'2-point', '3-point', 'cs'} may be used for
     |  approximating either the Jacobian or the Hessian. We, however, do not allow
     |  its use for approximating both simultaneously. Hence whenever the Jacobian
     |  is estimated via finite-differences, we require the Hessian to be estimated
     |  using one of the quasi-Newton strategies.
     |
     |  The scheme 'cs' is potentially the most accurate, but requires the function
     |  to correctly handles complex inputs and be analytically continuable to the
     |  complex plane. The scheme '3-point' is more accurate than '2-point' but
     |  requires twice as many operations.
     |
     |  Examples
     |  --------
     |  Constrain ``x[0] < sin(x[1]) + 1.9``
     |
     |  >>> from scipy.optimize import NonlinearConstraint
     |  >>> import numpy as np
     |  >>> con = lambda x: x[0] - np.sin(x[1])
     |  >>> nlc = NonlinearConstraint(con, -np.inf, 1.9)
     |
     |  Methods defined here:
     |
     |  __init__(self, fun, lb, ub, jac='2-point', hess=<scipy.optimize._hessian_update_strategy.BFGS object at 0x000001D8F14FFC50>, keep_feasible=False, finite_diff_rel_step=None, finite_diff_jac_sparsity=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class OptimizeResult(scipy._lib._util._RichResult)
     |  Represents the optimization result.
     |
     |  Attributes
     |  ----------
     |  x : ndarray
     |      The solution of the optimization.
     |  success : bool
     |      Whether or not the optimizer exited successfully.
     |  status : int
     |      Termination status of the optimizer. Its value depends on the
     |      underlying solver. Refer to `message` for details.
     |  message : str
     |      Description of the cause of the termination.
     |  fun, jac, hess: ndarray
     |      Values of objective function, its Jacobian and its Hessian (if
     |      available). The Hessians may be approximations, see the documentation
     |      of the function in question.
     |  hess_inv : object
     |      Inverse of the objective function's Hessian; may be an approximation.
     |      Not available for all solvers. The type of this attribute may be
     |      either np.ndarray or scipy.sparse.linalg.LinearOperator.
     |  nfev, njev, nhev : int
     |      Number of evaluations of the objective functions and of its
     |      Jacobian and Hessian.
     |  nit : int
     |      Number of iterations performed by the optimizer.
     |  maxcv : float
     |      The maximum constraint violation.
     |
     |  Notes
     |  -----
     |  Depending on the specific solver being used, `OptimizeResult` may
     |  not have all attributes listed here, and they may have additional
     |  attributes not listed here. Since this class is essentially a
     |  subclass of dict with attribute accessors, one can see which
     |  attributes are available using the `OptimizeResult.keys` method.
     |
     |  Method resolution order:
     |      OptimizeResult
     |      scipy._lib._util._RichResult
     |      builtins.dict
     |      builtins.object
     |
     |  Methods inherited from scipy._lib._util._RichResult:
     |
     |  __delattr__ = __delitem__(self, key, /)
     |
     |  __dir__(self)
     |      Default dir() implementation.
     |
     |  __getattr__(self, name)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __setattr__ = __setitem__(self, key, value, /)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy._lib._util._RichResult:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.dict:
     |
     |  __contains__(self, key, /)
     |      True if the dictionary has the specified key, else False.
     |
     |  __delitem__(self, key, /)
     |      Delete self[key].
     |
     |  __eq__(self, value, /)
     |      Return self==value.
     |
     |  __ge__(self, value, /)
     |      Return self>=value.
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __getitem__(self, key, /)
     |      Return self[key].
     |
     |  __gt__(self, value, /)
     |      Return self>value.
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __ior__(self, value, /)
     |      Return self|=value.
     |
     |  __iter__(self, /)
     |      Implement iter(self).
     |
     |  __le__(self, value, /)
     |      Return self<=value.
     |
     |  __len__(self, /)
     |      Return len(self).
     |
     |  __lt__(self, value, /)
     |      Return self<value.
     |
     |  __ne__(self, value, /)
     |      Return self!=value.
     |
     |  __or__(self, value, /)
     |      Return self|value.
     |
     |  __reversed__(self, /)
     |      Return a reverse iterator over the dict keys.
     |
     |  __ror__(self, value, /)
     |      Return value|self.
     |
     |  __setitem__(self, key, value, /)
     |      Set self[key] to value.
     |
     |  __sizeof__(...)
     |      D.__sizeof__() -> size of D in memory, in bytes
     |
     |  clear(...)
     |      D.clear() -> None.  Remove all items from D.
     |
     |  copy(...)
     |      D.copy() -> a shallow copy of D
     |
     |  get(self, key, default=None, /)
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  items(...)
     |      D.items() -> a set-like object providing a view on D's items
     |
     |  keys(...)
     |      D.keys() -> a set-like object providing a view on D's keys
     |
     |  pop(...)
     |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
     |
     |      If the key is not found, return the default if given; otherwise,
     |      raise a KeyError.
     |
     |  popitem(self, /)
     |      Remove and return a (key, value) pair as a 2-tuple.
     |
     |      Pairs are returned in LIFO (last-in, first-out) order.
     |      Raises KeyError if the dict is empty.
     |
     |  setdefault(self, key, default=None, /)
     |      Insert key with a value of default if key is not in the dictionary.
     |
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  update(...)
     |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
     |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
     |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
     |      In either case, this is followed by: for k in F:  D[k] = F[k]
     |
     |  values(...)
     |      D.values() -> an object providing a view on D's values
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from builtins.dict:
     |
     |  __class_getitem__(...)
     |      See PEP 585
     |
     |  fromkeys(iterable, value=None, /)
     |      Create a new dictionary with keys from iterable and values set to value.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.dict:
     |
     |  __new__(*args, **kwargs) class method of builtins.dict
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from builtins.dict:
     |
     |  __hash__ = None

    class OptimizeWarning(builtins.UserWarning)
     |  Method resolution order:
     |      OptimizeWarning
     |      builtins.UserWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.UserWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.UserWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.UserWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class RootResults(scipy.optimize._optimize.OptimizeResult)
     |  RootResults(root, iterations, function_calls, flag, method)
     |
     |  Represents the root finding result.
     |
     |  Attributes
     |  ----------
     |  root : float
     |      Estimated root location.
     |  iterations : int
     |      Number of iterations needed to find the root.
     |  function_calls : int
     |      Number of times the function was called.
     |  converged : bool
     |      True if the routine converged.
     |  flag : str
     |      Description of the cause of termination.
     |  method : str
     |      Root finding method used.
     |
     |  Method resolution order:
     |      RootResults
     |      scipy.optimize._optimize.OptimizeResult
     |      scipy._lib._util._RichResult
     |      builtins.dict
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, root, iterations, function_calls, flag, method)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy._lib._util._RichResult:
     |
     |  __delattr__ = __delitem__(self, key, /)
     |
     |  __dir__(self)
     |      Default dir() implementation.
     |
     |  __getattr__(self, name)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __setattr__ = __setitem__(self, key, value, /)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy._lib._util._RichResult:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.dict:
     |
     |  __contains__(self, key, /)
     |      True if the dictionary has the specified key, else False.
     |
     |  __delitem__(self, key, /)
     |      Delete self[key].
     |
     |  __eq__(self, value, /)
     |      Return self==value.
     |
     |  __ge__(self, value, /)
     |      Return self>=value.
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __getitem__(self, key, /)
     |      Return self[key].
     |
     |  __gt__(self, value, /)
     |      Return self>value.
     |
     |  __ior__(self, value, /)
     |      Return self|=value.
     |
     |  __iter__(self, /)
     |      Implement iter(self).
     |
     |  __le__(self, value, /)
     |      Return self<=value.
     |
     |  __len__(self, /)
     |      Return len(self).
     |
     |  __lt__(self, value, /)
     |      Return self<value.
     |
     |  __ne__(self, value, /)
     |      Return self!=value.
     |
     |  __or__(self, value, /)
     |      Return self|value.
     |
     |  __reversed__(self, /)
     |      Return a reverse iterator over the dict keys.
     |
     |  __ror__(self, value, /)
     |      Return value|self.
     |
     |  __setitem__(self, key, value, /)
     |      Set self[key] to value.
     |
     |  __sizeof__(...)
     |      D.__sizeof__() -> size of D in memory, in bytes
     |
     |  clear(...)
     |      D.clear() -> None.  Remove all items from D.
     |
     |  copy(...)
     |      D.copy() -> a shallow copy of D
     |
     |  get(self, key, default=None, /)
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  items(...)
     |      D.items() -> a set-like object providing a view on D's items
     |
     |  keys(...)
     |      D.keys() -> a set-like object providing a view on D's keys
     |
     |  pop(...)
     |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
     |
     |      If the key is not found, return the default if given; otherwise,
     |      raise a KeyError.
     |
     |  popitem(self, /)
     |      Remove and return a (key, value) pair as a 2-tuple.
     |
     |      Pairs are returned in LIFO (last-in, first-out) order.
     |      Raises KeyError if the dict is empty.
     |
     |  setdefault(self, key, default=None, /)
     |      Insert key with a value of default if key is not in the dictionary.
     |
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  update(...)
     |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
     |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
     |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
     |      In either case, this is followed by: for k in F:  D[k] = F[k]
     |
     |  values(...)
     |      D.values() -> an object providing a view on D's values
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from builtins.dict:
     |
     |  __class_getitem__(...)
     |      See PEP 585
     |
     |  fromkeys(iterable, value=None, /)
     |      Create a new dictionary with keys from iterable and values set to value.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.dict:
     |
     |  __new__(*args, **kwargs) class method of builtins.dict
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from builtins.dict:
     |
     |  __hash__ = None

    class SR1(FullHessianUpdateStrategy)
     |  SR1(min_denominator=1e-08, init_scale='auto')
     |
     |  Symmetric-rank-1 Hessian update strategy.
     |
     |  Parameters
     |  ----------
     |  min_denominator : float
     |      This number, scaled by a normalization factor,
     |      defines the minimum denominator magnitude allowed
     |      in the update. When the condition is violated we skip
     |      the update. By default uses ``1e-8``.
     |  init_scale : {float, np.array, 'auto'}, optional
     |      This parameter can be used to initialize the Hessian or its
     |      inverse. When a float is given, the relevant array is initialized
     |      to ``np.eye(n) * init_scale``, where ``n`` is the problem dimension.
     |      Alternatively, if a precisely ``(n, n)`` shaped, symmetric array is given,
     |      this array will be used. Otherwise an error is generated.
     |      Set it to 'auto' in order to use an automatic heuristic for choosing
     |      the initial scale. The heuristic is described in [1]_, p.143.
     |      The default is 'auto'.
     |
     |  Notes
     |  -----
     |  The update is based on the description in [1]_, p.144-146.
     |
     |  References
     |  ----------
     |  .. [1] Nocedal, Jorge, and Stephen J. Wright. "Numerical optimization"
     |         Second Edition (2006).
     |
     |  Method resolution order:
     |      SR1
     |      FullHessianUpdateStrategy
     |      HessianUpdateStrategy
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, min_denominator=1e-08, init_scale='auto')
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from FullHessianUpdateStrategy:
     |
     |  dot(self, p)
     |      Compute the product of the internal matrix with the given vector.
     |
     |      Parameters
     |      ----------
     |      p : array_like
     |          1-D array representing a vector.
     |
     |      Returns
     |      -------
     |      Hp : array
     |          1-D represents the result of multiplying the approximation matrix
     |          by vector p.
     |
     |  get_matrix(self)
     |      Return the current internal matrix.
     |
     |      Returns
     |      -------
     |      M : ndarray, shape (n, n)
     |          Dense matrix containing either the Hessian or its inverse
     |          (depending on how `approx_type` was defined).
     |
     |  initialize(self, n, approx_type)
     |      Initialize internal matrix.
     |
     |      Allocate internal memory for storing and updating
     |      the Hessian or its inverse.
     |
     |      Parameters
     |      ----------
     |      n : int
     |          Problem dimension.
     |      approx_type : {'hess', 'inv_hess'}
     |          Selects either the Hessian or the inverse Hessian.
     |          When set to 'hess' the Hessian will be stored and updated.
     |          When set to 'inv_hess' its inverse will be used instead.
     |
     |  update(self, delta_x, delta_grad)
     |      Update internal matrix.
     |
     |      Update Hessian matrix or its inverse (depending on how 'approx_type'
     |      is defined) using information about the last evaluated points.
     |
     |      Parameters
     |      ----------
     |      delta_x : ndarray
     |          The difference between two points the gradient
     |          function have been evaluated at: ``delta_x = x2 - x1``.
     |      delta_grad : ndarray
     |          The difference between the gradients:
     |          ``delta_grad = grad(x2) - grad(x1)``.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from HessianUpdateStrategy:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    anderson(F, xin, iter=None, alpha=None, w0=0.01, M=5, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using (extended) Anderson mixing.

        The Jacobian is formed by for a 'best' solution in the space
        spanned by last `M` vectors. As a result, only a MxM matrix
        inversions and MxN multiplications are required. [Ey]_

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            Initial guess for the Jacobian is (-1/alpha).
        M : float, optional
            Number of previous vectors to retain. Defaults to 5.
        w0 : float, optional
            Regularization parameter for numerical stability.
            Compared to unity, good values of the order of 0.01.
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='anderson'`` in particular.

        References
        ----------
        .. [Ey] V. Eyert, J. Comp. Phys., 124, 271 (1996).

        Examples
        --------
        The following functions define a system of nonlinear equations

        >>> def fun(x):
        ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
        ...             0.5 * (x[1] - x[0])**3 + x[1]]

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.anderson(fun, [0, 0])
        >>> sol
        array([0.84116588, 0.15883789])

    approx_fprime(xk, f, epsilon=np.float64(1.4901161193847656e-08), *args)
        Finite difference approximation of the derivatives of a
        scalar or vector-valued function.

        If a function maps from :math:`R^n` to :math:`R^m`, its derivatives form
        an m-by-n matrix
        called the Jacobian, where an element :math:`(i, j)` is a partial
        derivative of f[i] with respect to ``xk[j]``.

        Parameters
        ----------
        xk : array_like
            The coordinate vector at which to determine the gradient of `f`.
        f : callable
            Function of which to estimate the derivatives of. Has the signature
            ``f(xk, *args)`` where `xk` is the argument in the form of a 1-D array
            and `args` is a tuple of any additional fixed parameters needed to
            completely specify the function. The argument `xk` passed to this
            function is an ndarray of shape (n,) (never a scalar even if n=1).
            It must return a 1-D array_like of shape (m,) or a scalar.

            .. versionchanged:: 1.9.0
                `f` is now able to return a 1-D array-like, with the :math:`(m, n)`
                Jacobian being estimated.

        epsilon : {float, array_like}, optional
            Increment to `xk` to use for determining the function gradient.
            If a scalar, uses the same finite difference delta for all partial
            derivatives. If an array, should contain one value per element of
            `xk`. Defaults to ``sqrt(np.finfo(float).eps)``, which is approximately
            1.49e-08.
        \*args : args, optional
            Any other arguments that are to be passed to `f`.

        Returns
        -------
        jac : ndarray
            The partial derivatives of `f` to `xk`.

        See Also
        --------
        check_grad : Check correctness of gradient function against approx_fprime.

        Notes
        -----
        The function gradient is determined by the forward finite difference
        formula::

                     f(xk[i] + epsilon[i]) - f(xk[i])
            f'[i] = ---------------------------------
                                epsilon[i]

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import optimize
        >>> def func(x, c0, c1):
        ...     "Coordinate vector `x` should be an array of size two."
        ...     return c0 * x[0]**2 + c1*x[1]**2

        >>> x = np.ones(2)
        >>> c0, c1 = (1, 200)
        >>> eps = np.sqrt(np.finfo(float).eps)
        >>> optimize.approx_fprime(x, func, [eps, np.sqrt(200) * eps], c0, c1)
        array([   2.        ,  400.00004208])

    basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5, minimizer_kwargs=None, take_step=None, accept_test=None, callback=None, interval=50, disp=False, niter_success=None, seed=None, *, target_accept_rate=0.5, stepwise_factor=0.9)
        Find the global minimum of a function using the basin-hopping algorithm.

        Basin-hopping is a two-phase method that combines a global stepping
        algorithm with local minimization at each step. Designed to mimic
        the natural process of energy minimization of clusters of atoms, it works
        well for similar problems with "funnel-like, but rugged" energy landscapes
        [5]_.

        As the step-taking, step acceptance, and minimization methods are all
        customizable, this function can also be used to implement other two-phase
        methods.

        Parameters
        ----------
        func : callable ``f(x, *args)``
            Function to be optimized.  ``args`` can be passed as an optional item
            in the dict `minimizer_kwargs`
        x0 : array_like
            Initial guess.
        niter : integer, optional
            The number of basin-hopping iterations. There will be a total of
            ``niter + 1`` runs of the local minimizer.
        T : float, optional
            The "temperature" parameter for the acceptance or rejection criterion.
            Higher "temperatures" mean that larger jumps in function value will be
            accepted.  For best results `T` should be comparable to the
            separation (in function value) between local minima.
        stepsize : float, optional
            Maximum step size for use in the random displacement.
        minimizer_kwargs : dict, optional
            Extra keyword arguments to be passed to the local minimizer
            `scipy.optimize.minimize` Some important options could be:

                method : str
                    The minimization method (e.g. ``"L-BFGS-B"``)
                args : tuple
                    Extra arguments passed to the objective function (`func`) and
                    its derivatives (Jacobian, Hessian).

        take_step : callable ``take_step(x)``, optional
            Replace the default step-taking routine with this routine. The default
            step-taking routine is a random displacement of the coordinates, but
            other step-taking algorithms may be better for some systems.
            `take_step` can optionally have the attribute ``take_step.stepsize``.
            If this attribute exists, then `basinhopping` will adjust
            ``take_step.stepsize`` in order to try to optimize the global minimum
            search.
        accept_test : callable, ``accept_test(f_new=f_new, x_new=x_new, f_old=fold, x_old=x_old)``, optional
            Define a test which will be used to judge whether to accept the
            step. This will be used in addition to the Metropolis test based on
            "temperature" `T`. The acceptable return values are True,
            False, or ``"force accept"``. If any of the tests return False
            then the step is rejected. If the latter, then this will override any
            other tests in order to accept the step. This can be used, for example,
            to forcefully escape from a local minimum that `basinhopping` is
            trapped in.
        callback : callable, ``callback(x, f, accept)``, optional
            A callback function which will be called for all minima found. ``x``
            and ``f`` are the coordinates and function value of the trial minimum,
            and ``accept`` is whether that minimum was accepted. This can
            be used, for example, to save the lowest N minima found. Also,
            `callback` can be used to specify a user defined stop criterion by
            optionally returning True to stop the `basinhopping` routine.
        interval : integer, optional
            interval for how often to update the `stepsize`
        disp : bool, optional
            Set to True to print status messages
        niter_success : integer, optional
            Stop the run if the global minimum candidate remains the same for this
            number of iterations.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional

            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.
            Specify `seed` for repeatable minimizations. The random numbers
            generated with this seed only affect the default Metropolis
            `accept_test` and the default `take_step`. If you supply your own
            `take_step` and `accept_test`, and these functions use random
            number generation, then those functions are responsible for the state
            of their random number generator.
        target_accept_rate : float, optional
            The target acceptance rate that is used to adjust the `stepsize`.
            If the current acceptance rate is greater than the target,
            then the `stepsize` is increased. Otherwise, it is decreased.
            Range is (0, 1). Default is 0.5.

            .. versionadded:: 1.8.0

        stepwise_factor : float, optional
            The `stepsize` is multiplied or divided by this stepwise factor upon
            each update. Range is (0, 1). Default is 0.9.

            .. versionadded:: 1.8.0

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a `OptimizeResult` object.
            Important attributes are: ``x`` the solution array, ``fun`` the value
            of the function at the solution, and ``message`` which describes the
            cause of the termination. The ``OptimizeResult`` object returned by the
            selected minimizer at the lowest minimum is also contained within this
            object and can be accessed through the ``lowest_optimization_result``
            attribute.  See `OptimizeResult` for a description of other attributes.

        See Also
        --------
        minimize :
            The local minimization function called once for each basinhopping step.
            `minimizer_kwargs` is passed to this routine.

        Notes
        -----
        Basin-hopping is a stochastic algorithm which attempts to find the global
        minimum of a smooth scalar function of one or more variables [1]_ [2]_ [3]_
        [4]_. The algorithm in its current form was described by David Wales and
        Jonathan Doye [2]_ http://www-wales.ch.cam.ac.uk/.

        The algorithm is iterative with each cycle composed of the following
        features

        1) random perturbation of the coordinates

        2) local minimization

        3) accept or reject the new coordinates based on the minimized function
           value

        The acceptance test used here is the Metropolis criterion of standard Monte
        Carlo algorithms, although there are many other possibilities [3]_.

        This global minimization method has been shown to be extremely efficient
        for a wide variety of problems in physics and chemistry. It is
        particularly useful when the function has many minima separated by large
        barriers. See the `Cambridge Cluster Database
        <https://www-wales.ch.cam.ac.uk/CCD.html>`_ for databases of molecular
        systems that have been optimized primarily using basin-hopping. This
        database includes minimization problems exceeding 300 degrees of freedom.

        See the free software program `GMIN <https://www-wales.ch.cam.ac.uk/GMIN>`_
        for a Fortran implementation of basin-hopping. This implementation has many
        variations of the procedure described above, including more
        advanced step taking algorithms and alternate acceptance criterion.

        For stochastic global optimization there is no way to determine if the true
        global minimum has actually been found. Instead, as a consistency check,
        the algorithm can be run from a number of different random starting points
        to ensure the lowest minimum found in each example has converged to the
        global minimum. For this reason, `basinhopping` will by default simply
        run for the number of iterations `niter` and return the lowest minimum
        found. It is left to the user to ensure that this is in fact the global
        minimum.

        Choosing `stepsize`:  This is a crucial parameter in `basinhopping` and
        depends on the problem being solved. The step is chosen uniformly in the
        region from x0-stepsize to x0+stepsize, in each dimension. Ideally, it
        should be comparable to the typical separation (in argument values) between
        local minima of the function being optimized. `basinhopping` will, by
        default, adjust `stepsize` to find an optimal value, but this may take
        many iterations. You will get quicker results if you set a sensible
        initial value for ``stepsize``.

        Choosing `T`: The parameter `T` is the "temperature" used in the
        Metropolis criterion. Basinhopping steps are always accepted if
        ``func(xnew) < func(xold)``. Otherwise, they are accepted with
        probability::

            exp( -(func(xnew) - func(xold)) / T )

        So, for best results, `T` should to be comparable to the typical
        difference (in function values) between local minima. (The height of
        "walls" between local minima is irrelevant.)

        If `T` is 0, the algorithm becomes Monotonic Basin-Hopping, in which all
        steps that increase energy are rejected.

        .. versionadded:: 0.12.0

        References
        ----------
        .. [1] Wales, David J. 2003, Energy Landscapes, Cambridge University Press,
            Cambridge, UK.
        .. [2] Wales, D J, and Doye J P K, Global Optimization by Basin-Hopping and
            the Lowest Energy Structures of Lennard-Jones Clusters Containing up to
            110 Atoms.  Journal of Physical Chemistry A, 1997, 101, 5111.
        .. [3] Li, Z. and Scheraga, H. A., Monte Carlo-minimization approach to the
            multiple-minima problem in protein folding, Proc. Natl. Acad. Sci. USA,
            1987, 84, 6611.
        .. [4] Wales, D. J. and Scheraga, H. A., Global optimization of clusters,
            crystals, and biomolecules, Science, 1999, 285, 1368.
        .. [5] Olson, B., Hashmi, I., Molloy, K., and Shehu1, A., Basin Hopping as
            a General and Versatile Optimization Framework for the Characterization
            of Biological Macromolecules, Advances in Artificial Intelligence,
            Volume 2012 (2012), Article ID 674832, :doi:`10.1155/2012/674832`

        Examples
        --------
        The following example is a 1-D minimization problem, with many
        local minima superimposed on a parabola.

        >>> import numpy as np
        >>> from scipy.optimize import basinhopping
        >>> func = lambda x: np.cos(14.5 * x - 0.3) + (x + 0.2) * x
        >>> x0 = [1.]

        Basinhopping, internally, uses a local minimization algorithm. We will use
        the parameter `minimizer_kwargs` to tell basinhopping which algorithm to
        use and how to set up that minimizer. This parameter will be passed to
        `scipy.optimize.minimize`.

        >>> minimizer_kwargs = {"method": "BFGS"}
        >>> ret = basinhopping(func, x0, minimizer_kwargs=minimizer_kwargs,
        ...                    niter=200)
        >>> # the global minimum is:
        >>> ret.x, ret.fun
        -0.1951, -1.0009

        Next consider a 2-D minimization problem. Also, this time, we
        will use gradient information to significantly speed up the search.

        >>> def func2d(x):
        ...     f = np.cos(14.5 * x[0] - 0.3) + (x[1] + 0.2) * x[1] + (x[0] +
        ...                                                            0.2) * x[0]
        ...     df = np.zeros(2)
        ...     df[0] = -14.5 * np.sin(14.5 * x[0] - 0.3) + 2. * x[0] + 0.2
        ...     df[1] = 2. * x[1] + 0.2
        ...     return f, df

        We'll also use a different local minimization algorithm. Also, we must tell
        the minimizer that our function returns both energy and gradient (Jacobian).

        >>> minimizer_kwargs = {"method":"L-BFGS-B", "jac":True}
        >>> x0 = [1.0, 1.0]
        >>> ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs,
        ...                    niter=200)
        >>> print("global minimum: x = [%.4f, %.4f], f(x) = %.4f" % (ret.x[0],
        ...                                                           ret.x[1],
        ...                                                           ret.fun))
        global minimum: x = [-0.1951, -0.1000], f(x) = -1.0109

        Here is an example using a custom step-taking routine. Imagine you want
        the first coordinate to take larger steps than the rest of the coordinates.
        This can be implemented like so:

        >>> class MyTakeStep:
        ...    def __init__(self, stepsize=0.5):
        ...        self.stepsize = stepsize
        ...        self.rng = np.random.default_rng()
        ...    def __call__(self, x):
        ...        s = self.stepsize
        ...        x[0] += self.rng.uniform(-2.*s, 2.*s)
        ...        x[1:] += self.rng.uniform(-s, s, x[1:].shape)
        ...        return x

        Since ``MyTakeStep.stepsize`` exists basinhopping will adjust the magnitude
        of `stepsize` to optimize the search. We'll use the same 2-D function as
        before

        >>> mytakestep = MyTakeStep()
        >>> ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs,
        ...                    niter=200, take_step=mytakestep)
        >>> print("global minimum: x = [%.4f, %.4f], f(x) = %.4f" % (ret.x[0],
        ...                                                           ret.x[1],
        ...                                                           ret.fun))
        global minimum: x = [-0.1951, -0.1000], f(x) = -1.0109

        Now, let's do an example using a custom callback function which prints the
        value of every minimum found

        >>> def print_fun(x, f, accepted):
        ...         print("at minimum %.4f accepted %d" % (f, int(accepted)))

        We'll run it for only 10 basinhopping steps this time.

        >>> rng = np.random.default_rng()
        >>> ret = basinhopping(func2d, x0, minimizer_kwargs=minimizer_kwargs,
        ...                    niter=10, callback=print_fun, seed=rng)
        at minimum 0.4159 accepted 1
        at minimum -0.4317 accepted 1
        at minimum -1.0109 accepted 1
        at minimum -0.9073 accepted 1
        at minimum -0.4317 accepted 0
        at minimum -0.1021 accepted 1
        at minimum -0.7425 accepted 1
        at minimum -0.9073 accepted 1
        at minimum -0.4317 accepted 0
        at minimum -0.7425 accepted 1
        at minimum -0.9073 accepted 1

        The minimum at -1.0109 is actually the global minimum, found already on the
        8th iteration.

    bisect(f, a, b, args=(), xtol=2e-12, rtol=np.float64(8.881784197001252e-16), maxiter=100, full_output=False, disp=True)
        Find root of a function within an interval using bisection.

        Basic bisection routine to find a root of the function `f` between the
        arguments `a` and `b`. `f(a)` and `f(b)` cannot have the same signs.
        Slow but sure.

        Parameters
        ----------
        f : function
            Python function returning a number.  `f` must be continuous, and
            f(a) and f(b) must have opposite signs.
        a : scalar
            One end of the bracketing interval [a,b].
        b : scalar
            The other end of the bracketing interval [a,b].
        xtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter must be positive.
        rtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter cannot be smaller than its default value of
            ``4*np.finfo(float).eps``.
        maxiter : int, optional
            If convergence is not achieved in `maxiter` iterations, an error is
            raised. Must be >= 0.
        args : tuple, optional
            Containing extra arguments for the function `f`.
            `f` is called by ``apply(f, (x)+args)``.
        full_output : bool, optional
            If `full_output` is False, the root is returned. If `full_output` is
            True, the return value is ``(x, r)``, where x is the root, and r is
            a `RootResults` object.
        disp : bool, optional
            If True, raise RuntimeError if the algorithm didn't converge.
            Otherwise, the convergence status is recorded in a `RootResults`
            return object.

        Returns
        -------
        root : float
            Root of `f` between `a` and `b`.
        r : `RootResults` (present if ``full_output = True``)
            Object containing information about the convergence. In particular,
            ``r.converged`` is True if the routine converged.

        Examples
        --------

        >>> def f(x):
        ...     return (x**2 - 1)

        >>> from scipy import optimize

        >>> root = optimize.bisect(f, 0, 2)
        >>> root
        1.0

        >>> root = optimize.bisect(f, -2, 0)
        >>> root
        -1.0

        See Also
        --------
        brentq, brenth, bisect, newton
        fixed_point : scalar fixed-point finder
        fsolve : n-dimensional root-finding

    bracket(func, xa=0.0, xb=1.0, args=(), grow_limit=110.0, maxiter=1000)
        Bracket the minimum of a function.

        Given a function and distinct initial points, search in the
        downhill direction (as defined by the initial points) and return
        three points that bracket the minimum of the function.

        Parameters
        ----------
        func : callable f(x,*args)
            Objective function to minimize.
        xa, xb : float, optional
            Initial points. Defaults `xa` to 0.0, and `xb` to 1.0.
            A local minimum need not be contained within this interval.
        args : tuple, optional
            Additional arguments (if present), passed to `func`.
        grow_limit : float, optional
            Maximum grow limit.  Defaults to 110.0
        maxiter : int, optional
            Maximum number of iterations to perform. Defaults to 1000.

        Returns
        -------
        xa, xb, xc : float
            Final points of the bracket.
        fa, fb, fc : float
            Objective function values at the bracket points.
        funcalls : int
            Number of function evaluations made.

        Raises
        ------
        BracketError
            If no valid bracket is found before the algorithm terminates.
            See notes for conditions of a valid bracket.

        Notes
        -----
        The algorithm attempts to find three strictly ordered points (i.e.
        :math:`x_a < x_b < x_c` or :math:`x_c < x_b < x_a`) satisfying
        :math:`f(x_b) ≤ f(x_a)` and :math:`f(x_b) ≤ f(x_c)`, where one of the
        inequalities must be satistfied strictly and all :math:`x_i` must be
        finite.

        Examples
        --------
        This function can find a downward convex region of a function:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.optimize import bracket
        >>> def f(x):
        ...     return 10*x**2 + 3*x + 5
        >>> x = np.linspace(-2, 2)
        >>> y = f(x)
        >>> init_xa, init_xb = 0.1, 1
        >>> xa, xb, xc, fa, fb, fc, funcalls = bracket(f, xa=init_xa, xb=init_xb)
        >>> plt.axvline(x=init_xa, color="k", linestyle="--")
        >>> plt.axvline(x=init_xb, color="k", linestyle="--")
        >>> plt.plot(x, y, "-k")
        >>> plt.plot(xa, fa, "bx")
        >>> plt.plot(xb, fb, "rx")
        >>> plt.plot(xc, fc, "bx")
        >>> plt.show()

        Note that both initial points were to the right of the minimum, and the
        third point was found in the "downhill" direction: the direction
        in which the function appeared to be decreasing (to the left).
        The final points are strictly ordered, and the function value
        at the middle point is less than the function values at the endpoints;
        it follows that a minimum must lie within the bracket.

    brent(func, args=(), brack=None, tol=1.48e-08, full_output=0, maxiter=500)
        Given a function of one variable and a possible bracket, return
        a local minimizer of the function isolated to a fractional precision
        of tol.

        Parameters
        ----------
        func : callable f(x,*args)
            Objective function.
        args : tuple, optional
            Additional arguments (if present).
        brack : tuple, optional
            Either a triple ``(xa, xb, xc)`` satisfying ``xa < xb < xc`` and
            ``func(xb) < func(xa) and  func(xb) < func(xc)``, or a pair
            ``(xa, xb)`` to be used as initial points for a downhill bracket search
            (see `scipy.optimize.bracket`).
            The minimizer ``x`` will not necessarily satisfy ``xa <= x <= xb``.
        tol : float, optional
            Relative error in solution `xopt` acceptable for convergence.
        full_output : bool, optional
            If True, return all output args (xmin, fval, iter,
            funcalls).
        maxiter : int, optional
            Maximum number of iterations in solution.

        Returns
        -------
        xmin : ndarray
            Optimum point.
        fval : float
            (Optional output) Optimum function value.
        iter : int
            (Optional output) Number of iterations.
        funcalls : int
            (Optional output) Number of objective function evaluations made.

        See also
        --------
        minimize_scalar: Interface to minimization algorithms for scalar
            univariate functions. See the 'Brent' `method` in particular.

        Notes
        -----
        Uses inverse parabolic interpolation when possible to speed up
        convergence of golden section method.

        Does not ensure that the minimum lies in the range specified by
        `brack`. See `scipy.optimize.fminbound`.

        Examples
        --------
        We illustrate the behaviour of the function when `brack` is of
        size 2 and 3 respectively. In the case where `brack` is of the
        form ``(xa, xb)``, we can see for the given values, the output does
        not necessarily lie in the range ``(xa, xb)``.

        >>> def f(x):
        ...     return (x-1)**2

        >>> from scipy import optimize

        >>> minimizer = optimize.brent(f, brack=(1, 2))
        >>> minimizer
        1
        >>> res = optimize.brent(f, brack=(-1, 0.5, 2), full_output=True)
        >>> xmin, fval, iter, funcalls = res
        >>> f(xmin), fval
        (0.0, 0.0)

    brenth(f, a, b, args=(), xtol=2e-12, rtol=np.float64(8.881784197001252e-16), maxiter=100, full_output=False, disp=True)
        Find a root of a function in a bracketing interval using Brent's
        method with hyperbolic extrapolation.

        A variation on the classic Brent routine to find a root of the function f
        between the arguments a and b that uses hyperbolic extrapolation instead of
        inverse quadratic extrapolation. Bus & Dekker (1975) guarantee convergence
        for this method, claiming that the upper bound of function evaluations here
        is 4 or 5 times that of bisection.
        f(a) and f(b) cannot have the same signs. Generally, on a par with the
        brent routine, but not as heavily tested. It is a safe version of the
        secant method that uses hyperbolic extrapolation.
        The version here is by Chuck Harris, and implements Algorithm M of
        [BusAndDekker1975]_, where further details (convergence properties,
        additional remarks and such) can be found

        Parameters
        ----------
        f : function
            Python function returning a number. f must be continuous, and f(a) and
            f(b) must have opposite signs.
        a : scalar
            One end of the bracketing interval [a,b].
        b : scalar
            The other end of the bracketing interval [a,b].
        xtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter must be positive. As with `brentq`, for nice
            functions the method will often satisfy the above condition
            with ``xtol/2`` and ``rtol/2``.
        rtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter cannot be smaller than its default value of
            ``4*np.finfo(float).eps``. As with `brentq`, for nice functions
            the method will often satisfy the above condition with
            ``xtol/2`` and ``rtol/2``.
        maxiter : int, optional
            If convergence is not achieved in `maxiter` iterations, an error is
            raised. Must be >= 0.
        args : tuple, optional
            Containing extra arguments for the function `f`.
            `f` is called by ``apply(f, (x)+args)``.
        full_output : bool, optional
            If `full_output` is False, the root is returned. If `full_output` is
            True, the return value is ``(x, r)``, where `x` is the root, and `r` is
            a `RootResults` object.
        disp : bool, optional
            If True, raise RuntimeError if the algorithm didn't converge.
            Otherwise, the convergence status is recorded in any `RootResults`
            return object.

        Returns
        -------
        root : float
            Root of `f` between `a` and `b`.
        r : `RootResults` (present if ``full_output = True``)
            Object containing information about the convergence. In particular,
            ``r.converged`` is True if the routine converged.

        See Also
        --------
        fmin, fmin_powell, fmin_cg, fmin_bfgs, fmin_ncg : multivariate local optimizers
        leastsq : nonlinear least squares minimizer
        fmin_l_bfgs_b, fmin_tnc, fmin_cobyla : constrained multivariate optimizers
        basinhopping, differential_evolution, brute : global optimizers
        fminbound, brent, golden, bracket : local scalar minimizers
        fsolve : N-D root-finding
        brentq, brenth, ridder, bisect, newton : 1-D root-finding
        fixed_point : scalar fixed-point finder

        References
        ----------
        .. [BusAndDekker1975]
           Bus, J. C. P., Dekker, T. J.,
           "Two Efficient Algorithms with Guaranteed Convergence for Finding a Zero
           of a Function", ACM Transactions on Mathematical Software, Vol. 1, Issue
           4, Dec. 1975, pp. 330-345. Section 3: "Algorithm M".
           :doi:`10.1145/355656.355659`

        Examples
        --------
        >>> def f(x):
        ...     return (x**2 - 1)

        >>> from scipy import optimize

        >>> root = optimize.brenth(f, -2, 0)
        >>> root
        -1.0

        >>> root = optimize.brenth(f, 0, 2)
        >>> root
        1.0

    brentq(f, a, b, args=(), xtol=2e-12, rtol=np.float64(8.881784197001252e-16), maxiter=100, full_output=False, disp=True)
        Find a root of a function in a bracketing interval using Brent's method.

        Uses the classic Brent's method to find a root of the function `f` on
        the sign changing interval [a , b]. Generally considered the best of the
        rootfinding routines here. It is a safe version of the secant method that
        uses inverse quadratic extrapolation. Brent's method combines root
        bracketing, interval bisection, and inverse quadratic interpolation. It is
        sometimes known as the van Wijngaarden-Dekker-Brent method. Brent (1973)
        claims convergence is guaranteed for functions computable within [a,b].

        [Brent1973]_ provides the classic description of the algorithm. Another
        description can be found in a recent edition of Numerical Recipes, including
        [PressEtal1992]_. A third description is at
        http://mathworld.wolfram.com/BrentsMethod.html. It should be easy to
        understand the algorithm just by reading our code. Our code diverges a bit
        from standard presentations: we choose a different formula for the
        extrapolation step.

        Parameters
        ----------
        f : function
            Python function returning a number. The function :math:`f`
            must be continuous, and :math:`f(a)` and :math:`f(b)` must
            have opposite signs.
        a : scalar
            One end of the bracketing interval :math:`[a, b]`.
        b : scalar
            The other end of the bracketing interval :math:`[a, b]`.
        xtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter must be positive. For nice functions, Brent's
            method will often satisfy the above condition with ``xtol/2``
            and ``rtol/2``. [Brent1973]_
        rtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter cannot be smaller than its default value of
            ``4*np.finfo(float).eps``. For nice functions, Brent's
            method will often satisfy the above condition with ``xtol/2``
            and ``rtol/2``. [Brent1973]_
        maxiter : int, optional
            If convergence is not achieved in `maxiter` iterations, an error is
            raised. Must be >= 0.
        args : tuple, optional
            Containing extra arguments for the function `f`.
            `f` is called by ``apply(f, (x)+args)``.
        full_output : bool, optional
            If `full_output` is False, the root is returned. If `full_output` is
            True, the return value is ``(x, r)``, where `x` is the root, and `r` is
            a `RootResults` object.
        disp : bool, optional
            If True, raise RuntimeError if the algorithm didn't converge.
            Otherwise, the convergence status is recorded in any `RootResults`
            return object.

        Returns
        -------
        root : float
            Root of `f` between `a` and `b`.
        r : `RootResults` (present if ``full_output = True``)
            Object containing information about the convergence. In particular,
            ``r.converged`` is True if the routine converged.

        Notes
        -----
        `f` must be continuous.  f(a) and f(b) must have opposite signs.

        Related functions fall into several classes:

        multivariate local optimizers
          `fmin`, `fmin_powell`, `fmin_cg`, `fmin_bfgs`, `fmin_ncg`
        nonlinear least squares minimizer
          `leastsq`
        constrained multivariate optimizers
          `fmin_l_bfgs_b`, `fmin_tnc`, `fmin_cobyla`
        global optimizers
          `basinhopping`, `brute`, `differential_evolution`
        local scalar minimizers
          `fminbound`, `brent`, `golden`, `bracket`
        N-D root-finding
          `fsolve`
        1-D root-finding
          `brenth`, `ridder`, `bisect`, `newton`
        scalar fixed-point finder
          `fixed_point`

        References
        ----------
        .. [Brent1973]
           Brent, R. P.,
           *Algorithms for Minimization Without Derivatives*.
           Englewood Cliffs, NJ: Prentice-Hall, 1973. Ch. 3-4.

        .. [PressEtal1992]
           Press, W. H.; Flannery, B. P.; Teukolsky, S. A.; and Vetterling, W. T.
           *Numerical Recipes in FORTRAN: The Art of Scientific Computing*, 2nd ed.
           Cambridge, England: Cambridge University Press, pp. 352-355, 1992.
           Section 9.3:  "Van Wijngaarden-Dekker-Brent Method."

        Examples
        --------
        >>> def f(x):
        ...     return (x**2 - 1)

        >>> from scipy import optimize

        >>> root = optimize.brentq(f, -2, 0)
        >>> root
        -1.0

        >>> root = optimize.brentq(f, 0, 2)
        >>> root
        1.0

    broyden1(F, xin, iter=None, alpha=None, reduction_method='restart', max_rank=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using Broyden's first Jacobian approximation.

        This method is also known as \"Broyden's good method\".

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            Initial guess for the Jacobian is ``(-1/alpha)``.
        reduction_method : str or tuple, optional
            Method used in ensuring that the rank of the Broyden matrix
            stays low. Can either be a string giving the name of the method,
            or a tuple of the form ``(method, param1, param2, ...)``
            that gives the name of the method and values for additional parameters.

            Methods available:

                - ``restart``: drop all matrix columns. Has no extra parameters.
                - ``simple``: drop oldest matrix column. Has no extra parameters.
                - ``svd``: keep only the most significant SVD components.
                  Takes an extra parameter, ``to_retain``, which determines the
                  number of SVD components to retain when rank reduction is done.
                  Default is ``max_rank - 2``.

        max_rank : int, optional
            Maximum rank for the Broyden matrix.
            Default is infinity (i.e., no rank reduction).
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='broyden1'`` in particular.

        Notes
        -----
        This algorithm implements the inverse Jacobian Quasi-Newton update

        .. math:: H_+ = H + (dx - H df) dx^\dagger H / ( dx^\dagger H df)

        which corresponds to Broyden's first Jacobian update

        .. math:: J_+ = J + (df - J dx) dx^\dagger / dx^\dagger dx


        References
        ----------
        .. [1] B.A. van der Rotten, PhD thesis,
           \"A limited memory Broyden method to solve high-dimensional
           systems of nonlinear equations\". Mathematisch Instituut,
           Universiteit Leiden, The Netherlands (2003).

           https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf

        Examples
        --------
        The following functions define a system of nonlinear equations

        >>> def fun(x):
        ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
        ...             0.5 * (x[1] - x[0])**3 + x[1]]

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.broyden1(fun, [0, 0])
        >>> sol
        array([0.84116396, 0.15883641])

    broyden2(F, xin, iter=None, alpha=None, reduction_method='restart', max_rank=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using Broyden's second Jacobian approximation.

        This method is also known as "Broyden's bad method".

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            Initial guess for the Jacobian is ``(-1/alpha)``.
        reduction_method : str or tuple, optional
            Method used in ensuring that the rank of the Broyden matrix
            stays low. Can either be a string giving the name of the method,
            or a tuple of the form ``(method, param1, param2, ...)``
            that gives the name of the method and values for additional parameters.

            Methods available:

                - ``restart``: drop all matrix columns. Has no extra parameters.
                - ``simple``: drop oldest matrix column. Has no extra parameters.
                - ``svd``: keep only the most significant SVD components.
                  Takes an extra parameter, ``to_retain``, which determines the
                  number of SVD components to retain when rank reduction is done.
                  Default is ``max_rank - 2``.

        max_rank : int, optional
            Maximum rank for the Broyden matrix.
            Default is infinity (i.e., no rank reduction).
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='broyden2'`` in particular.

        Notes
        -----
        This algorithm implements the inverse Jacobian Quasi-Newton update

        .. math:: H_+ = H + (dx - H df) df^\dagger / ( df^\dagger df)

        corresponding to Broyden's second method.

        References
        ----------
        .. [1] B.A. van der Rotten, PhD thesis,
           "A limited memory Broyden method to solve high-dimensional
           systems of nonlinear equations". Mathematisch Instituut,
           Universiteit Leiden, The Netherlands (2003).

           https://web.archive.org/web/20161022015821/http://www.math.leidenuniv.nl/scripties/Rotten.pdf

        Examples
        --------
        The following functions define a system of nonlinear equations

        >>> def fun(x):
        ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
        ...             0.5 * (x[1] - x[0])**3 + x[1]]

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.broyden2(fun, [0, 0])
        >>> sol
        array([0.84116365, 0.15883529])

    brute(func, ranges, args=(), Ns=20, full_output=0, finish=<function fmin at 0x000001D8F1918900>, disp=False, workers=1)
        Minimize a function over a given range by brute force.

        Uses the "brute force" method, i.e., computes the function's value
        at each point of a multidimensional grid of points, to find the global
        minimum of the function.

        The function is evaluated everywhere in the range with the datatype of the
        first call to the function, as enforced by the ``vectorize`` NumPy
        function. The value and type of the function evaluation returned when
        ``full_output=True`` are affected in addition by the ``finish`` argument
        (see Notes).

        The brute force approach is inefficient because the number of grid points
        increases exponentially - the number of grid points to evaluate is
        ``Ns ** len(x)``. Consequently, even with coarse grid spacing, even
        moderately sized problems can take a long time to run, and/or run into
        memory limitations.

        Parameters
        ----------
        func : callable
            The objective function to be minimized. Must be in the
            form ``f(x, *args)``, where ``x`` is the argument in
            the form of a 1-D array and ``args`` is a tuple of any
            additional fixed parameters needed to completely specify
            the function.
        ranges : tuple
            Each component of the `ranges` tuple must be either a
            "slice object" or a range tuple of the form ``(low, high)``.
            The program uses these to create the grid of points on which
            the objective function will be computed. See `Note 2` for
            more detail.
        args : tuple, optional
            Any additional fixed parameters needed to completely specify
            the function.
        Ns : int, optional
            Number of grid points along the axes, if not otherwise
            specified. See `Note2`.
        full_output : bool, optional
            If True, return the evaluation grid and the objective function's
            values on it.
        finish : callable, optional
            An optimization function that is called with the result of brute force
            minimization as initial guess. `finish` should take `func` and
            the initial guess as positional arguments, and take `args` as
            keyword arguments. It may additionally take `full_output`
            and/or `disp` as keyword arguments. Use None if no "polishing"
            function is to be used. See Notes for more details.
        disp : bool, optional
            Set to True to print convergence messages from the `finish` callable.
        workers : int or map-like callable, optional
            If `workers` is an int the grid is subdivided into `workers`
            sections and evaluated in parallel (uses
            `multiprocessing.Pool <multiprocessing>`).
            Supply `-1` to use all cores available to the Process.
            Alternatively supply a map-like callable, such as
            `multiprocessing.Pool.map` for evaluating the grid in parallel.
            This evaluation is carried out as ``workers(func, iterable)``.
            Requires that `func` be pickleable.

            .. versionadded:: 1.3.0

        Returns
        -------
        x0 : ndarray
            A 1-D array containing the coordinates of a point at which the
            objective function had its minimum value. (See `Note 1` for
            which point is returned.)
        fval : float
            Function value at the point `x0`. (Returned when `full_output` is
            True.)
        grid : tuple
            Representation of the evaluation grid. It has the same
            length as `x0`. (Returned when `full_output` is True.)
        Jout : ndarray
            Function values at each point of the evaluation
            grid, i.e., ``Jout = func(*grid)``. (Returned
            when `full_output` is True.)

        See Also
        --------
        basinhopping, differential_evolution

        Notes
        -----
        *Note 1*: The program finds the gridpoint at which the lowest value
        of the objective function occurs. If `finish` is None, that is the
        point returned. When the global minimum occurs within (or not very far
        outside) the grid's boundaries, and the grid is fine enough, that
        point will be in the neighborhood of the global minimum.

        However, users often employ some other optimization program to
        "polish" the gridpoint values, i.e., to seek a more precise
        (local) minimum near `brute's` best gridpoint.
        The `brute` function's `finish` option provides a convenient way to do
        that. Any polishing program used must take `brute's` output as its
        initial guess as a positional argument, and take `brute's` input values
        for `args` as keyword arguments, otherwise an error will be raised.
        It may additionally take `full_output` and/or `disp` as keyword arguments.

        `brute` assumes that the `finish` function returns either an
        `OptimizeResult` object or a tuple in the form:
        ``(xmin, Jmin, ... , statuscode)``, where ``xmin`` is the minimizing
        value of the argument, ``Jmin`` is the minimum value of the objective
        function, "..." may be some other returned values (which are not used
        by `brute`), and ``statuscode`` is the status code of the `finish` program.

        Note that when `finish` is not None, the values returned are those
        of the `finish` program, *not* the gridpoint ones. Consequently,
        while `brute` confines its search to the input grid points,
        the `finish` program's results usually will not coincide with any
        gridpoint, and may fall outside the grid's boundary. Thus, if a
        minimum only needs to be found over the provided grid points, make
        sure to pass in `finish=None`.

        *Note 2*: The grid of points is a `numpy.mgrid` object.
        For `brute` the `ranges` and `Ns` inputs have the following effect.
        Each component of the `ranges` tuple can be either a slice object or a
        two-tuple giving a range of values, such as (0, 5). If the component is a
        slice object, `brute` uses it directly. If the component is a two-tuple
        range, `brute` internally converts it to a slice object that interpolates
        `Ns` points from its low-value to its high-value, inclusive.

        Examples
        --------
        We illustrate the use of `brute` to seek the global minimum of a function
        of two variables that is given as the sum of a positive-definite
        quadratic and two deep "Gaussian-shaped" craters. Specifically, define
        the objective function `f` as the sum of three other functions,
        ``f = f1 + f2 + f3``. We suppose each of these has a signature
        ``(z, *params)``, where ``z = (x, y)``,  and ``params`` and the functions
        are as defined below.

        >>> import numpy as np
        >>> params = (2, 3, 7, 8, 9, 10, 44, -1, 2, 26, 1, -2, 0.5)
        >>> def f1(z, *params):
        ...     x, y = z
        ...     a, b, c, d, e, f, g, h, i, j, k, l, scale = params
        ...     return (a * x**2 + b * x * y + c * y**2 + d*x + e*y + f)

        >>> def f2(z, *params):
        ...     x, y = z
        ...     a, b, c, d, e, f, g, h, i, j, k, l, scale = params
        ...     return (-g*np.exp(-((x-h)**2 + (y-i)**2) / scale))

        >>> def f3(z, *params):
        ...     x, y = z
        ...     a, b, c, d, e, f, g, h, i, j, k, l, scale = params
        ...     return (-j*np.exp(-((x-k)**2 + (y-l)**2) / scale))

        >>> def f(z, *params):
        ...     return f1(z, *params) + f2(z, *params) + f3(z, *params)

        Thus, the objective function may have local minima near the minimum
        of each of the three functions of which it is composed. To
        use `fmin` to polish its gridpoint result, we may then continue as
        follows:

        >>> rranges = (slice(-4, 4, 0.25), slice(-4, 4, 0.25))
        >>> from scipy import optimize
        >>> resbrute = optimize.brute(f, rranges, args=params, full_output=True,
        ...                           finish=optimize.fmin)
        >>> resbrute[0]  # global minimum
        array([-1.05665192,  1.80834843])
        >>> resbrute[1]  # function value at global minimum
        -3.4085818767

        Note that if `finish` had been set to None, we would have gotten the
        gridpoint [-1.0 1.75] where the rounded function value is -2.892.

    check_grad(func, grad, x0, *args, epsilon=np.float64(1.4901161193847656e-08), direction='all', seed=None)
        Check the correctness of a gradient function by comparing it against a
        (forward) finite-difference approximation of the gradient.

        Parameters
        ----------
        func : callable ``func(x0, *args)``
            Function whose derivative is to be checked.
        grad : callable ``grad(x0, *args)``
            Jacobian of `func`.
        x0 : ndarray
            Points to check `grad` against forward difference approximation of grad
            using `func`.
        args : \*args, optional
            Extra arguments passed to `func` and `grad`.
        epsilon : float, optional
            Step size used for the finite difference approximation. It defaults to
            ``sqrt(np.finfo(float).eps)``, which is approximately 1.49e-08.
        direction : str, optional
            If set to ``'random'``, then gradients along a random vector
            are used to check `grad` against forward difference approximation
            using `func`. By default it is ``'all'``, in which case, all
            the one hot direction vectors are considered to check `grad`.
            If `func` is a vector valued function then only ``'all'`` can be used.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.
            Specify `seed` for reproducing the return value from this function.
            The random numbers generated with this seed affect the random vector
            along which gradients are computed to check ``grad``. Note that `seed`
            is only used when `direction` argument is set to `'random'`.

        Returns
        -------
        err : float
            The square root of the sum of squares (i.e., the 2-norm) of the
            difference between ``grad(x0, *args)`` and the finite difference
            approximation of `grad` using func at the points `x0`.

        See Also
        --------
        approx_fprime

        Examples
        --------
        >>> import numpy as np
        >>> def func(x):
        ...     return x[0]**2 - 0.5 * x[1]**3
        >>> def grad(x):
        ...     return [2 * x[0], -1.5 * x[1]**2]
        >>> from scipy.optimize import check_grad
        >>> check_grad(func, grad, [1.5, -1.5])
        2.9802322387695312e-08  # may vary
        >>> rng = np.random.default_rng()
        >>> check_grad(func, grad, [1.5, -1.5],
        ...             direction='random', seed=rng)
        2.9802322387695312e-08

    curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=None, bounds=(-inf, inf), method=None, jac=None, *, full_output=False, nan_policy=None, **kwargs)
        Use non-linear least squares to fit a function, f, to data.

        Assumes ``ydata = f(xdata, *params) + eps``.

        Parameters
        ----------
        f : callable
            The model function, f(x, ...). It must take the independent
            variable as the first argument and the parameters to fit as
            separate remaining arguments.
        xdata : array_like
            The independent variable where the data is measured.
            Should usually be an M-length sequence or an (k,M)-shaped array for
            functions with k predictors, and each element should be float
            convertible if it is an array like object.
        ydata : array_like
            The dependent data, a length M array - nominally ``f(xdata, ...)``.
        p0 : array_like, optional
            Initial guess for the parameters (length N). If None, then the
            initial values will all be 1 (if the number of parameters for the
            function can be determined using introspection, otherwise a
            ValueError is raised).
        sigma : None or scalar or M-length sequence or MxM array, optional
            Determines the uncertainty in `ydata`. If we define residuals as
            ``r = ydata - f(xdata, *popt)``, then the interpretation of `sigma`
            depends on its number of dimensions:

                - A scalar or 1-D `sigma` should contain values of standard deviations of
                  errors in `ydata`. In this case, the optimized function is
                  ``chisq = sum((r / sigma) ** 2)``.

                - A 2-D `sigma` should contain the covariance matrix of
                  errors in `ydata`. In this case, the optimized function is
                  ``chisq = r.T @ inv(sigma) @ r``.

                  .. versionadded:: 0.19

            None (default) is equivalent of 1-D `sigma` filled with ones.
        absolute_sigma : bool, optional
            If True, `sigma` is used in an absolute sense and the estimated parameter
            covariance `pcov` reflects these absolute values.

            If False (default), only the relative magnitudes of the `sigma` values matter.
            The returned parameter covariance matrix `pcov` is based on scaling
            `sigma` by a constant factor. This constant is set by demanding that the
            reduced `chisq` for the optimal parameters `popt` when using the
            *scaled* `sigma` equals unity. In other words, `sigma` is scaled to
            match the sample variance of the residuals after the fit. Default is False.
            Mathematically,
            ``pcov(absolute_sigma=False) = pcov(absolute_sigma=True) * chisq(popt)/(M-N)``
        check_finite : bool, optional
            If True, check that the input arrays do not contain nans of infs,
            and raise a ValueError if they do. Setting this parameter to
            False may silently produce nonsensical results if the input arrays
            do contain nans. Default is True if `nan_policy` is not specified
            explicitly and False otherwise.
        bounds : 2-tuple of array_like or `Bounds`, optional
            Lower and upper bounds on parameters. Defaults to no bounds.
            There are two ways to specify the bounds:

                - Instance of `Bounds` class.

                - 2-tuple of array_like: Each element of the tuple must be either
                  an array with the length equal to the number of parameters, or a
                  scalar (in which case the bound is taken to be the same for all
                  parameters). Use ``np.inf`` with an appropriate sign to disable
                  bounds on all or some parameters.

        method : {'lm', 'trf', 'dogbox'}, optional
            Method to use for optimization. See `least_squares` for more details.
            Default is 'lm' for unconstrained problems and 'trf' if `bounds` are
            provided. The method 'lm' won't work when the number of observations
            is less than the number of variables, use 'trf' or 'dogbox' in this
            case.

            .. versionadded:: 0.17
        jac : callable, string or None, optional
            Function with signature ``jac(x, ...)`` which computes the Jacobian
            matrix of the model function with respect to parameters as a dense
            array_like structure. It will be scaled according to provided `sigma`.
            If None (default), the Jacobian will be estimated numerically.
            String keywords for 'trf' and 'dogbox' methods can be used to select
            a finite difference scheme, see `least_squares`.

            .. versionadded:: 0.18
        full_output : boolean, optional
            If True, this function returns additioal information: `infodict`,
            `mesg`, and `ier`.

            .. versionadded:: 1.9
        nan_policy : {'raise', 'omit', None}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is None):

              * 'raise': throws an error
              * 'omit': performs the calculations ignoring nan values
              * None: no special handling of NaNs is performed
                (except what is done by check_finite); the behavior when NaNs
                are present is implementation-dependent and may change.

            Note that if this value is specified explicitly (not None),
            `check_finite` will be set as False.

            .. versionadded:: 1.11
        **kwargs
            Keyword arguments passed to `leastsq` for ``method='lm'`` or
            `least_squares` otherwise.

        Returns
        -------
        popt : array
            Optimal values for the parameters so that the sum of the squared
            residuals of ``f(xdata, *popt) - ydata`` is minimized.
        pcov : 2-D array
            The estimated approximate covariance of popt. The diagonals provide
            the variance of the parameter estimate. To compute one standard
            deviation errors on the parameters, use
            ``perr = np.sqrt(np.diag(pcov))``. Note that the relationship between
            `cov` and parameter error estimates is derived based on a linear
            approximation to the model function around the optimum [1].
            When this approximation becomes inaccurate, `cov` may not provide an
            accurate measure of uncertainty.

            How the `sigma` parameter affects the estimated covariance
            depends on `absolute_sigma` argument, as described above.

            If the Jacobian matrix at the solution doesn't have a full rank, then
            'lm' method returns a matrix filled with ``np.inf``, on the other hand
            'trf'  and 'dogbox' methods use Moore-Penrose pseudoinverse to compute
            the covariance matrix. Covariance matrices with large condition numbers
            (e.g. computed with `numpy.linalg.cond`) may indicate that results are
            unreliable.
        infodict : dict (returned only if `full_output` is True)
            a dictionary of optional outputs with the keys:

            ``nfev``
                The number of function calls. Methods 'trf' and 'dogbox' do not
                count function calls for numerical Jacobian approximation,
                as opposed to 'lm' method.
            ``fvec``
                The residual values evaluated at the solution, for a 1-D `sigma`
                this is ``(f(x, *popt) - ydata)/sigma``.
            ``fjac``
                A permutation of the R matrix of a QR
                factorization of the final approximate
                Jacobian matrix, stored column wise.
                Together with ipvt, the covariance of the
                estimate can be approximated.
                Method 'lm' only provides this information.
            ``ipvt``
                An integer array of length N which defines
                a permutation matrix, p, such that
                fjac*p = q*r, where r is upper triangular
                with diagonal elements of nonincreasing
                magnitude. Column j of p is column ipvt(j)
                of the identity matrix.
                Method 'lm' only provides this information.
            ``qtf``
                The vector (transpose(q) * fvec).
                Method 'lm' only provides this information.

            .. versionadded:: 1.9
        mesg : str (returned only if `full_output` is True)
            A string message giving information about the solution.

            .. versionadded:: 1.9
        ier : int (returned only if `full_output` is True)
            An integer flag. If it is equal to 1, 2, 3 or 4, the solution was
            found. Otherwise, the solution was not found. In either case, the
            optional output variable `mesg` gives more information.

            .. versionadded:: 1.9

        Raises
        ------
        ValueError
            if either `ydata` or `xdata` contain NaNs, or if incompatible options
            are used.

        RuntimeError
            if the least-squares minimization fails.

        OptimizeWarning
            if covariance of the parameters can not be estimated.

        See Also
        --------
        least_squares : Minimize the sum of squares of nonlinear functions.
        scipy.stats.linregress : Calculate a linear least squares regression for
                                 two sets of measurements.

        Notes
        -----
        Users should ensure that inputs `xdata`, `ydata`, and the output of `f`
        are ``float64``, or else the optimization may return incorrect results.

        With ``method='lm'``, the algorithm uses the Levenberg-Marquardt algorithm
        through `leastsq`. Note that this algorithm can only deal with
        unconstrained problems.

        Box constraints can be handled by methods 'trf' and 'dogbox'. Refer to
        the docstring of `least_squares` for more information.

        Parameters to be fitted must have similar scale. Differences of multiple
        orders of magnitude can lead to incorrect results. For the 'trf' and
        'dogbox' methods, the `x_scale` keyword argument can be used to scale
        the parameters.

        References
        ----------
        [1] K. Vugrin et al. Confidence region estimation techniques for nonlinear
            regression in groundwater flow: Three case studies. Water Resources
            Research, Vol. 43, W03423, :doi:`10.1029/2005WR004804`

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.optimize import curve_fit

        >>> def func(x, a, b, c):
        ...     return a * np.exp(-b * x) + c

        Define the data to be fit with some noise:

        >>> xdata = np.linspace(0, 4, 50)
        >>> y = func(xdata, 2.5, 1.3, 0.5)
        >>> rng = np.random.default_rng()
        >>> y_noise = 0.2 * rng.normal(size=xdata.size)
        >>> ydata = y + y_noise
        >>> plt.plot(xdata, ydata, 'b-', label='data')

        Fit for the parameters a, b, c of the function `func`:

        >>> popt, pcov = curve_fit(func, xdata, ydata)
        >>> popt
        array([2.56274217, 1.37268521, 0.47427475])
        >>> plt.plot(xdata, func(xdata, *popt), 'r-',
        ...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

        Constrain the optimization to the region of ``0 <= a <= 3``,
        ``0 <= b <= 1`` and ``0 <= c <= 0.5``:

        >>> popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 1., 0.5]))
        >>> popt
        array([2.43736712, 1.        , 0.34463856])
        >>> plt.plot(xdata, func(xdata, *popt), 'g--',
        ...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

        >>> plt.xlabel('x')
        >>> plt.ylabel('y')
        >>> plt.legend()
        >>> plt.show()

        For reliable results, the model `func` should not be overparametrized;
        redundant parameters can cause unreliable covariance matrices and, in some
        cases, poorer quality fits. As a quick check of whether the model may be
        overparameterized, calculate the condition number of the covariance matrix:

        >>> np.linalg.cond(pcov)
        34.571092161547405  # may vary

        The value is small, so it does not raise much concern. If, however, we were
        to add a fourth parameter ``d`` to `func` with the same effect as ``a``:

        >>> def func2(x, a, b, c, d):
        ...     return a * d * np.exp(-b * x) + c  # a and d are redundant
        >>> popt, pcov = curve_fit(func2, xdata, ydata)
        >>> np.linalg.cond(pcov)
        1.13250718925596e+32  # may vary

        Such a large value is cause for concern. The diagonal elements of the
        covariance matrix, which is related to uncertainty of the fit, gives more
        information:

        >>> np.diag(pcov)
        array([1.48814742e+29, 3.78596560e-02, 5.39253738e-03, 2.76417220e+28])  # may vary

        Note that the first and last terms are much larger than the other elements,
        suggesting that the optimal values of these parameters are ambiguous and
        that only one of these parameters is needed in the model.

        If the optimal parameters of `f` differ by multiple orders of magnitude, the
        resulting fit can be inaccurate. Sometimes, `curve_fit` can fail to find any
        results:

        >>> ydata = func(xdata, 500000, 0.01, 15)
        >>> try:
        ...     popt, pcov = curve_fit(func, xdata, ydata, method = 'trf')
        ... except RuntimeError as e:
        ...     print(e)
        Optimal parameters not found: The maximum number of function evaluations is
        exceeded.

        If parameter scale is roughly known beforehand, it can be defined in
        `x_scale` argument:

        >>> popt, pcov = curve_fit(func, xdata, ydata, method = 'trf',
        ...                        x_scale = [1000, 1, 1])
        >>> popt
        array([5.00000000e+05, 1.00000000e-02, 1.49999999e+01])

    diagbroyden(F, xin, iter=None, alpha=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using diagonal Broyden Jacobian approximation.

        The Jacobian approximation is derived from previous iterations, by
        retaining only the diagonal of Broyden matrices.

        .. warning::

           This algorithm may be useful for specific problems, but whether
           it will work may depend strongly on the problem.

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            Initial guess for the Jacobian is (-1/alpha).
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='diagbroyden'`` in particular.

        Examples
        --------
        The following functions define a system of nonlinear equations

        >>> def fun(x):
        ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
        ...             0.5 * (x[1] - x[0])**3 + x[1]]

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.diagbroyden(fun, [0, 0])
        >>> sol
        array([0.84116403, 0.15883384])

    differential_evolution(func, bounds, args=(), strategy='best1bin', maxiter=1000, popsize=15, tol=0.01, mutation=(0.5, 1), recombination=0.7, seed=None, callback=None, disp=False, polish=True, init='latinhypercube', atol=0, updating='immediate', workers=1, constraints=(), x0=None, *, integrality=None, vectorized=False)
        Finds the global minimum of a multivariate function.

        The differential evolution method [1]_ is stochastic in nature. It does
        not use gradient methods to find the minimum, and can search large areas
        of candidate space, but often requires larger numbers of function
        evaluations than conventional gradient-based techniques.

        The algorithm is due to Storn and Price [2]_.

        Parameters
        ----------
        func : callable
            The objective function to be minimized. Must be in the form
            ``f(x, *args)``, where ``x`` is the argument in the form of a 1-D array
            and ``args`` is a tuple of any additional fixed parameters needed to
            completely specify the function. The number of parameters, N, is equal
            to ``len(x)``.
        bounds : sequence or `Bounds`
            Bounds for variables. There are two ways to specify the bounds:

                1. Instance of `Bounds` class.
                2. ``(min, max)`` pairs for each element in ``x``, defining the
                   finite lower and upper bounds for the optimizing argument of
                   `func`.

            The total number of bounds is used to determine the number of
            parameters, N. If there are parameters whose bounds are equal the total
            number of free parameters is ``N - N_equal``.

        args : tuple, optional
            Any additional fixed parameters needed to
            completely specify the objective function.
        strategy : {str, callable}, optional
            The differential evolution strategy to use. Should be one of:

                - 'best1bin'
                - 'best1exp'
                - 'rand1bin'
                - 'rand1exp'
                - 'rand2bin'
                - 'rand2exp'
                - 'randtobest1bin'
                - 'randtobest1exp'
                - 'currenttobest1bin'
                - 'currenttobest1exp'
                - 'best2exp'
                - 'best2bin'

            The default is 'best1bin'. Strategies that may be implemented are
            outlined in 'Notes'.
            Alternatively the differential evolution strategy can be customized by
            providing a callable that constructs a trial vector. The callable must
            have the form ``strategy(candidate: int, population: np.ndarray, rng=None)``,
            where ``candidate`` is an integer specifying which entry of the
            population is being evolved, ``population`` is an array of shape
            ``(S, N)`` containing all the population members (where S is the
            total population size), and ``rng`` is the random number generator
            being used within the solver.
            ``candidate`` will be in the range ``[0, S)``.
            ``strategy`` must return a trial vector with shape `(N,)`. The
            fitness of this trial vector is compared against the fitness of
            ``population[candidate]``.

            .. versionchanged:: 1.12.0
                Customization of evolution strategy via a callable.

        maxiter : int, optional
            The maximum number of generations over which the entire population is
            evolved. The maximum number of function evaluations (with no polishing)
            is: ``(maxiter + 1) * popsize * (N - N_equal)``
        popsize : int, optional
            A multiplier for setting the total population size. The population has
            ``popsize * (N - N_equal)`` individuals. This keyword is overridden if
            an initial population is supplied via the `init` keyword. When using
            ``init='sobol'`` the population size is calculated as the next power
            of 2 after ``popsize * (N - N_equal)``.
        tol : float, optional
            Relative tolerance for convergence, the solving stops when
            ``np.std(pop) <= atol + tol * np.abs(np.mean(population_energies))``,
            where and `atol` and `tol` are the absolute and relative tolerance
            respectively.
        mutation : float or tuple(float, float), optional
            The mutation constant. In the literature this is also known as
            differential weight, being denoted by F.
            If specified as a float it should be in the range [0, 2].
            If specified as a tuple ``(min, max)`` dithering is employed. Dithering
            randomly changes the mutation constant on a generation by generation
            basis. The mutation constant for that generation is taken from
            ``U[min, max)``. Dithering can help speed convergence significantly.
            Increasing the mutation constant increases the search radius, but will
            slow down convergence.
        recombination : float, optional
            The recombination constant, should be in the range [0, 1]. In the
            literature this is also known as the crossover probability, being
            denoted by CR. Increasing this value allows a larger number of mutants
            to progress into the next generation, but at the risk of population
            stability.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.
            Specify `seed` for repeatable minimizations.
        disp : bool, optional
            Prints the evaluated `func` at every iteration.
        callback : callable, optional
            A callable called after each iteration. Has the signature:

                ``callback(intermediate_result: OptimizeResult)``

            where ``intermediate_result`` is a keyword parameter containing an
            `OptimizeResult` with attributes ``x`` and ``fun``, the best solution
            found so far and the objective function. Note that the name
            of the parameter must be ``intermediate_result`` for the callback
            to be passed an `OptimizeResult`.

            The callback also supports a signature like:

                ``callback(x, convergence: float=val)``

            ``val`` represents the fractional value of the population convergence.
            When ``val`` is greater than ``1.0``, the function halts.

            Introspection is used to determine which of the signatures is invoked.

            Global minimization will halt if the callback raises ``StopIteration``
            or returns ``True``; any polishing is still carried out.

            .. versionchanged:: 1.12.0
                callback accepts the ``intermediate_result`` keyword.

        polish : bool, optional
            If True (default), then `scipy.optimize.minimize` with the `L-BFGS-B`
            method is used to polish the best population member at the end, which
            can improve the minimization slightly. If a constrained problem is
            being studied then the `trust-constr` method is used instead. For large
            problems with many constraints, polishing can take a long time due to
            the Jacobian computations.
        init : str or array-like, optional
            Specify which type of population initialization is performed. Should be
            one of:

                - 'latinhypercube'
                - 'sobol'
                - 'halton'
                - 'random'
                - array specifying the initial population. The array should have
                  shape ``(S, N)``, where S is the total population size and N is
                  the number of parameters.
                  `init` is clipped to `bounds` before use.

            The default is 'latinhypercube'. Latin Hypercube sampling tries to
            maximize coverage of the available parameter space.

            'sobol' and 'halton' are superior alternatives and maximize even more
            the parameter space. 'sobol' will enforce an initial population
            size which is calculated as the next power of 2 after
            ``popsize * (N - N_equal)``. 'halton' has no requirements but is a bit
            less efficient. See `scipy.stats.qmc` for more details.

            'random' initializes the population randomly - this has the drawback
            that clustering can occur, preventing the whole of parameter space
            being covered. Use of an array to specify a population could be used,
            for example, to create a tight bunch of initial guesses in an location
            where the solution is known to exist, thereby reducing time for
            convergence.
        atol : float, optional
            Absolute tolerance for convergence, the solving stops when
            ``np.std(pop) <= atol + tol * np.abs(np.mean(population_energies))``,
            where and `atol` and `tol` are the absolute and relative tolerance
            respectively.
        updating : {'immediate', 'deferred'}, optional
            If ``'immediate'``, the best solution vector is continuously updated
            within a single generation [4]_. This can lead to faster convergence as
            trial vectors can take advantage of continuous improvements in the best
            solution.
            With ``'deferred'``, the best solution vector is updated once per
            generation. Only ``'deferred'`` is compatible with parallelization or
            vectorization, and the `workers` and `vectorized` keywords can
            over-ride this option.

            .. versionadded:: 1.2.0

        workers : int or map-like callable, optional
            If `workers` is an int the population is subdivided into `workers`
            sections and evaluated in parallel
            (uses `multiprocessing.Pool <multiprocessing>`).
            Supply -1 to use all available CPU cores.
            Alternatively supply a map-like callable, such as
            `multiprocessing.Pool.map` for evaluating the population in parallel.
            This evaluation is carried out as ``workers(func, iterable)``.
            This option will override the `updating` keyword to
            ``updating='deferred'`` if ``workers != 1``.
            This option overrides the `vectorized` keyword if ``workers != 1``.
            Requires that `func` be pickleable.

            .. versionadded:: 1.2.0

        constraints : {NonLinearConstraint, LinearConstraint, Bounds}
            Constraints on the solver, over and above those applied by the `bounds`
            kwd. Uses the approach by Lampinen [5]_.

            .. versionadded:: 1.4.0

        x0 : None or array-like, optional
            Provides an initial guess to the minimization. Once the population has
            been initialized this vector replaces the first (best) member. This
            replacement is done even if `init` is given an initial population.
            ``x0.shape == (N,)``.

            .. versionadded:: 1.7.0

        integrality : 1-D array, optional
            For each decision variable, a boolean value indicating whether the
            decision variable is constrained to integer values. The array is
            broadcast to ``(N,)``.
            If any decision variables are constrained to be integral, they will not
            be changed during polishing.
            Only integer values lying between the lower and upper bounds are used.
            If there are no integer values lying between the bounds then a
            `ValueError` is raised.

            .. versionadded:: 1.9.0

        vectorized : bool, optional
            If ``vectorized is True``, `func` is sent an `x` array with
            ``x.shape == (N, S)``, and is expected to return an array of shape
            ``(S,)``, where `S` is the number of solution vectors to be calculated.
            If constraints are applied, each of the functions used to construct
            a `Constraint` object should accept an `x` array with
            ``x.shape == (N, S)``, and return an array of shape ``(M, S)``, where
            `M` is the number of constraint components.
            This option is an alternative to the parallelization offered by
            `workers`, and may help in optimization speed by reducing interpreter
            overhead from multiple function calls. This keyword is ignored if
            ``workers != 1``.
            This option will override the `updating` keyword to
            ``updating='deferred'``.
            See the notes section for further discussion on when to use
            ``'vectorized'``, and when to use ``'workers'``.

            .. versionadded:: 1.9.0

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a `OptimizeResult` object.
            Important attributes are: ``x`` the solution array, ``success`` a
            Boolean flag indicating if the optimizer exited successfully,
            ``message`` which describes the cause of the termination,
            ``population`` the solution vectors present in the population, and
            ``population_energies`` the value of the objective function for each
            entry in ``population``.
            See `OptimizeResult` for a description of other attributes. If `polish`
            was employed, and a lower minimum was obtained by the polishing, then
            OptimizeResult also contains the ``jac`` attribute.
            If the eventual solution does not satisfy the applied constraints
            ``success`` will be `False`.

        Notes
        -----
        Differential evolution is a stochastic population based method that is
        useful for global optimization problems. At each pass through the
        population the algorithm mutates each candidate solution by mixing with
        other candidate solutions to create a trial candidate. There are several
        strategies [3]_ for creating trial candidates, which suit some problems
        more than others. The 'best1bin' strategy is a good starting point for
        many systems. In this strategy two members of the population are randomly
        chosen. Their difference is used to mutate the best member (the 'best' in
        'best1bin'), :math:`x_0`, so far:

        .. math::

            b' = x_0 + mutation * (x_{r_0} - x_{r_1})

        A trial vector is then constructed. Starting with a randomly chosen ith
        parameter the trial is sequentially filled (in modulo) with parameters
        from ``b'`` or the original candidate. The choice of whether to use ``b'``
        or the original candidate is made with a binomial distribution (the 'bin'
        in 'best1bin') - a random number in [0, 1) is generated. If this number is
        less than the `recombination` constant then the parameter is loaded from
        ``b'``, otherwise it is loaded from the original candidate. The final
        parameter is always loaded from ``b'``. Once the trial candidate is built
        its fitness is assessed. If the trial is better than the original candidate
        then it takes its place. If it is also better than the best overall
        candidate it also replaces that.

        The other strategies available are outlined in Qiang and
        Mitchell (2014) [3]_.

        .. math::
                rand1* : b' = x_{r_0} + mutation*(x_{r_1} - x_{r_2})

                rand2* : b' = x_{r_0} + mutation*(x_{r_1} + x_{r_2}
                                                    - x_{r_3} - x_{r_4})

                best1* : b' = x_0 + mutation*(x_{r_0} - x_{r_1})

                best2* : b' = x_0 + mutation*(x_{r_0} + x_{r_1}
                                                - x_{r_2} - x_{r_3})

                currenttobest1* : b' = x_i + mutation*(x_0 - x_i
                                                         + x_{r_0} - x_{r_1})

                randtobest1* : b' = x_{r_0} + mutation*(x_0 - x_{r_0}
                                                          + x_{r_1} - x_{r_2})

        where the integers :math:`r_0, r_1, r_2, r_3, r_4` are chosen randomly
        from the interval [0, NP) with `NP` being the total population size and
        the original candidate having index `i`. The user can fully customize the
        generation of the trial candidates by supplying a callable to ``strategy``.

        To improve your chances of finding a global minimum use higher `popsize`
        values, with higher `mutation` and (dithering), but lower `recombination`
        values. This has the effect of widening the search radius, but slowing
        convergence.

        By default the best solution vector is updated continuously within a single
        iteration (``updating='immediate'``). This is a modification [4]_ of the
        original differential evolution algorithm which can lead to faster
        convergence as trial vectors can immediately benefit from improved
        solutions. To use the original Storn and Price behaviour, updating the best
        solution once per iteration, set ``updating='deferred'``.
        The ``'deferred'`` approach is compatible with both parallelization and
        vectorization (``'workers'`` and ``'vectorized'`` keywords). These may
        improve minimization speed by using computer resources more efficiently.
        The ``'workers'`` distribute calculations over multiple processors. By
        default the Python `multiprocessing` module is used, but other approaches
        are also possible, such as the Message Passing Interface (MPI) used on
        clusters [6]_ [7]_. The overhead from these approaches (creating new
        Processes, etc) may be significant, meaning that computational speed
        doesn't necessarily scale with the number of processors used.
        Parallelization is best suited to computationally expensive objective
        functions. If the objective function is less expensive, then
        ``'vectorized'`` may aid by only calling the objective function once per
        iteration, rather than multiple times for all the population members; the
        interpreter overhead is reduced.

        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Differential evolution, Wikipedia,
               http://en.wikipedia.org/wiki/Differential_evolution
        .. [2] Storn, R and Price, K, Differential Evolution - a Simple and
               Efficient Heuristic for Global Optimization over Continuous Spaces,
               Journal of Global Optimization, 1997, 11, 341 - 359.
        .. [3] Qiang, J., Mitchell, C., A Unified Differential Evolution Algorithm
                for Global Optimization, 2014, https://www.osti.gov/servlets/purl/1163659
        .. [4] Wormington, M., Panaccione, C., Matney, K. M., Bowen, D. K., -
               Characterization of structures from X-ray scattering data using
               genetic algorithms, Phil. Trans. R. Soc. Lond. A, 1999, 357,
               2827-2848
        .. [5] Lampinen, J., A constraint handling approach for the differential
               evolution algorithm. Proceedings of the 2002 Congress on
               Evolutionary Computation. CEC'02 (Cat. No. 02TH8600). Vol. 2. IEEE,
               2002.
        .. [6] https://mpi4py.readthedocs.io/en/stable/
        .. [7] https://schwimmbad.readthedocs.io/en/latest/


        Examples
        --------
        Let us consider the problem of minimizing the Rosenbrock function. This
        function is implemented in `rosen` in `scipy.optimize`.

        >>> import numpy as np
        >>> from scipy.optimize import rosen, differential_evolution
        >>> bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)]
        >>> result = differential_evolution(rosen, bounds)
        >>> result.x, result.fun
        (array([1., 1., 1., 1., 1.]), 1.9216496320061384e-19)

        Now repeat, but with parallelization.

        >>> result = differential_evolution(rosen, bounds, updating='deferred',
        ...                                 workers=2)
        >>> result.x, result.fun
        (array([1., 1., 1., 1., 1.]), 1.9216496320061384e-19)

        Let's do a constrained minimization.

        >>> from scipy.optimize import LinearConstraint, Bounds

        We add the constraint that the sum of ``x[0]`` and ``x[1]`` must be less
        than or equal to 1.9.  This is a linear constraint, which may be written
        ``A @ x <= 1.9``, where ``A = array([[1, 1]])``.  This can be encoded as
        a `LinearConstraint` instance:

        >>> lc = LinearConstraint([[1, 1]], -np.inf, 1.9)

        Specify limits using a `Bounds` object.

        >>> bounds = Bounds([0., 0.], [2., 2.])
        >>> result = differential_evolution(rosen, bounds, constraints=lc,
        ...                                 seed=1)
        >>> result.x, result.fun
        (array([0.96632622, 0.93367155]), 0.0011352416852625719)

        Next find the minimum of the Ackley function
        (https://en.wikipedia.org/wiki/Test_functions_for_optimization).

        >>> def ackley(x):
        ...     arg1 = -0.2 * np.sqrt(0.5 * (x[0] ** 2 + x[1] ** 2))
        ...     arg2 = 0.5 * (np.cos(2. * np.pi * x[0]) + np.cos(2. * np.pi * x[1]))
        ...     return -20. * np.exp(arg1) - np.exp(arg2) + 20. + np.e
        >>> bounds = [(-5, 5), (-5, 5)]
        >>> result = differential_evolution(ackley, bounds, seed=1)
        >>> result.x, result.fun
        (array([0., 0.]), 4.440892098500626e-16)

        The Ackley function is written in a vectorized manner, so the
        ``'vectorized'`` keyword can be employed. Note the reduced number of
        function evaluations.

        >>> result = differential_evolution(
        ...     ackley, bounds, vectorized=True, updating='deferred', seed=1
        ... )
        >>> result.x, result.fun
        (array([0., 0.]), 4.440892098500626e-16)

        The following custom strategy function mimics 'best1bin':

        >>> def custom_strategy_fn(candidate, population, rng=None):
        ...     parameter_count = population.shape(-1)
        ...     mutation, recombination = 0.7, 0.9
        ...     trial = np.copy(population[candidate])
        ...     fill_point = rng.choice(parameter_count)
        ...
        ...     pool = np.arange(len(population))
        ...     rng.shuffle(pool)
        ...
        ...     # two unique random numbers that aren't the same, and
        ...     # aren't equal to candidate.
        ...     idxs = []
        ...     while len(idxs) < 2 and len(pool) > 0:
        ...         idx = pool[0]
        ...         pool = pool[1:]
        ...         if idx != candidate:
        ...             idxs.append(idx)
        ...
        ...     r0, r1 = idxs[:2]
        ...
        ...     bprime = (population[0] + mutation *
        ...               (population[r0] - population[r1]))
        ...
        ...     crossovers = rng.uniform(size=parameter_count)
        ...     crossovers = crossovers < recombination
        ...     crossovers[fill_point] = True
        ...     trial = np.where(crossovers, bprime, trial)
        ...     return trial

    direct(func: 'Callable[[npt.ArrayLike, tuple[Any]], float]', bounds: 'Iterable | Bounds', *, args: 'tuple' = (), eps: 'float' = 0.0001, maxfun: 'int | None' = None, maxiter: 'int' = 1000, locally_biased: 'bool' = True, f_min: 'float' = -inf, f_min_rtol: 'float' = 0.0001, vol_tol: 'float' = 1e-16, len_tol: 'float' = 1e-06, callback: 'Callable[[npt.ArrayLike], None] | None' = None) -> 'OptimizeResult'
        Finds the global minimum of a function using the
        DIRECT algorithm.

        Parameters
        ----------
        func : callable
            The objective function to be minimized.
            ``func(x, *args) -> float``
            where ``x`` is an 1-D array with shape (n,) and ``args`` is a tuple of
            the fixed parameters needed to completely specify the function.
        bounds : sequence or `Bounds`
            Bounds for variables. There are two ways to specify the bounds:

            1. Instance of `Bounds` class.
            2. ``(min, max)`` pairs for each element in ``x``.

        args : tuple, optional
            Any additional fixed parameters needed to
            completely specify the objective function.
        eps : float, optional
            Minimal required difference of the objective function values
            between the current best hyperrectangle and the next potentially
            optimal hyperrectangle to be divided. In consequence, `eps` serves as a
            tradeoff between local and global search: the smaller, the more local
            the search becomes. Default is 1e-4.
        maxfun : int or None, optional
            Approximate upper bound on objective function evaluations.
            If `None`, will be automatically set to ``1000 * N`` where ``N``
            represents the number of dimensions. Will be capped if necessary to
            limit DIRECT's RAM usage to app. 1GiB. This will only occur for very
            high dimensional problems and excessive `max_fun`. Default is `None`.
        maxiter : int, optional
            Maximum number of iterations. Default is 1000.
        locally_biased : bool, optional
            If `True` (default), use the locally biased variant of the
            algorithm known as DIRECT_L. If `False`, use the original unbiased
            DIRECT algorithm. For hard problems with many local minima,
            `False` is recommended.
        f_min : float, optional
            Function value of the global optimum. Set this value only if the
            global optimum is known. Default is ``-np.inf``, so that this
            termination criterion is deactivated.
        f_min_rtol : float, optional
            Terminate the optimization once the relative error between the
            current best minimum `f` and the supplied global minimum `f_min`
            is smaller than `f_min_rtol`. This parameter is only used if
            `f_min` is also set. Must lie between 0 and 1. Default is 1e-4.
        vol_tol : float, optional
            Terminate the optimization once the volume of the hyperrectangle
            containing the lowest function value is smaller than `vol_tol`
            of the complete search space. Must lie between 0 and 1.
            Default is 1e-16.
        len_tol : float, optional
            If `locally_biased=True`, terminate the optimization once half of
            the normalized maximal side length of the hyperrectangle containing
            the lowest function value is smaller than `len_tol`.
            If `locally_biased=False`, terminate the optimization once half of
            the normalized diagonal of the hyperrectangle containing the lowest
            function value is smaller than `len_tol`. Must lie between 0 and 1.
            Default is 1e-6.
        callback : callable, optional
            A callback function with signature ``callback(xk)`` where ``xk``
            represents the best function value found so far.

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a ``OptimizeResult`` object.
            Important attributes are: ``x`` the solution array, ``success`` a
            Boolean flag indicating if the optimizer exited successfully and
            ``message`` which describes the cause of the termination. See
            `OptimizeResult` for a description of other attributes.

        Notes
        -----
        DIviding RECTangles (DIRECT) is a deterministic global
        optimization algorithm capable of minimizing a black box function with
        its variables subject to lower and upper bound constraints by sampling
        potential solutions in the search space [1]_. The algorithm starts by
        normalising the search space to an n-dimensional unit hypercube.
        It samples the function at the center of this hypercube and at 2n
        (n is the number of variables) more points, 2 in each coordinate
        direction. Using these function values, DIRECT then divides the
        domain into hyperrectangles, each having exactly one of the sampling
        points as its center. In each iteration, DIRECT chooses, using the `eps`
        parameter which defaults to 1e-4, some of the existing hyperrectangles
        to be further divided. This division process continues until either the
        maximum number of iterations or maximum function evaluations allowed
        are exceeded, or the hyperrectangle containing the minimal value found
        so far becomes small enough. If `f_min` is specified, the optimization
        will stop once this function value is reached within a relative tolerance.
        The locally biased variant of DIRECT (originally called DIRECT_L) [2]_ is
        used by default. It makes the search more locally biased and more
        efficient for cases with only a few local minima.

        A note about termination criteria: `vol_tol` refers to the volume of the
        hyperrectangle containing the lowest function value found so far. This
        volume decreases exponentially with increasing dimensionality of the
        problem. Therefore `vol_tol` should be decreased to avoid premature
        termination of the algorithm for higher dimensions. This does not hold
        for `len_tol`: it refers either to half of the maximal side length
        (for ``locally_biased=True``) or half of the diagonal of the
        hyperrectangle (for ``locally_biased=False``).

        This code is based on the DIRECT 2.0.4 Fortran code by Gablonsky et al. at
        https://ctk.math.ncsu.edu/SOFTWARE/DIRECTv204.tar.gz .
        This original version was initially converted via f2c and then cleaned up
        and reorganized by Steven G. Johnson, August 2007, for the NLopt project.
        The `direct` function wraps the C implementation.

        .. versionadded:: 1.9.0

        References
        ----------
        .. [1] Jones, D.R., Perttunen, C.D. & Stuckman, B.E. Lipschitzian
            optimization without the Lipschitz constant. J Optim Theory Appl
            79, 157-181 (1993).
        .. [2] Gablonsky, J., Kelley, C. A Locally-Biased form of the DIRECT
            Algorithm. Journal of Global Optimization 21, 27-37 (2001).

        Examples
        --------
        The following example is a 2-D problem with four local minima: minimizing
        the Styblinski-Tang function
        (https://en.wikipedia.org/wiki/Test_functions_for_optimization).

        >>> from scipy.optimize import direct, Bounds
        >>> def styblinski_tang(pos):
        ...     x, y = pos
        ...     return 0.5 * (x**4 - 16*x**2 + 5*x + y**4 - 16*y**2 + 5*y)
        >>> bounds = Bounds([-4., -4.], [4., 4.])
        >>> result = direct(styblinski_tang, bounds)
        >>> result.x, result.fun, result.nfev
        array([-2.90321597, -2.90321597]), -78.3323279095383, 2011

        The correct global minimum was found but with a huge number of function
        evaluations (2011). Loosening the termination tolerances `vol_tol` and
        `len_tol` can be used to stop DIRECT earlier.

        >>> result = direct(styblinski_tang, bounds, len_tol=1e-3)
        >>> result.x, result.fun, result.nfev
        array([-2.9044353, -2.9044353]), -78.33230330754142, 207

    dual_annealing(func, bounds, args=(), maxiter=1000, minimizer_kwargs=None, initial_temp=5230.0, restart_temp_ratio=2e-05, visit=2.62, accept=-5.0, maxfun=10000000.0, seed=None, no_local_search=False, callback=None, x0=None)
        Find the global minimum of a function using Dual Annealing.

        Parameters
        ----------
        func : callable
            The objective function to be minimized. Must be in the form
            ``f(x, *args)``, where ``x`` is the argument in the form of a 1-D array
            and ``args`` is a  tuple of any additional fixed parameters needed to
            completely specify the function.
        bounds : sequence or `Bounds`
            Bounds for variables. There are two ways to specify the bounds:

            1. Instance of `Bounds` class.
            2. Sequence of ``(min, max)`` pairs for each element in `x`.

        args : tuple, optional
            Any additional fixed parameters needed to completely specify the
            objective function.
        maxiter : int, optional
            The maximum number of global search iterations. Default value is 1000.
        minimizer_kwargs : dict, optional
            Keyword arguments to be passed to the local minimizer
            (`minimize`). An important option could be ``method`` for the minimizer
            method to use.
            If no keyword arguments are provided, the local minimizer defaults to
            'L-BFGS-B' and uses the already supplied bounds. If `minimizer_kwargs`
            is specified, then the dict must contain all parameters required to
            control the local minimization. `args` is ignored in this dict, as it is
            passed automatically. `bounds` is not automatically passed on to the
            local minimizer as the method may not support them.
        initial_temp : float, optional
            The initial temperature, use higher values to facilitates a wider
            search of the energy landscape, allowing dual_annealing to escape
            local minima that it is trapped in. Default value is 5230. Range is
            (0.01, 5.e4].
        restart_temp_ratio : float, optional
            During the annealing process, temperature is decreasing, when it
            reaches ``initial_temp * restart_temp_ratio``, the reannealing process
            is triggered. Default value of the ratio is 2e-5. Range is (0, 1).
        visit : float, optional
            Parameter for visiting distribution. Default value is 2.62. Higher
            values give the visiting distribution a heavier tail, this makes
            the algorithm jump to a more distant region. The value range is (1, 3].
        accept : float, optional
            Parameter for acceptance distribution. It is used to control the
            probability of acceptance. The lower the acceptance parameter, the
            smaller the probability of acceptance. Default value is -5.0 with
            a range (-1e4, -5].
        maxfun : int, optional
            Soft limit for the number of objective function calls. If the
            algorithm is in the middle of a local search, this number will be
            exceeded, the algorithm will stop just after the local search is
            done. Default value is 1e7.
        seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.
            Specify `seed` for repeatable minimizations. The random numbers
            generated with this seed only affect the visiting distribution function
            and new coordinates generation.
        no_local_search : bool, optional
            If `no_local_search` is set to True, a traditional Generalized
            Simulated Annealing will be performed with no local search
            strategy applied.
        callback : callable, optional
            A callback function with signature ``callback(x, f, context)``,
            which will be called for all minima found.
            ``x`` and ``f`` are the coordinates and function value of the
            latest minimum found, and ``context`` has value in [0, 1, 2], with the
            following meaning:

                - 0: minimum detected in the annealing process.
                - 1: detection occurred in the local search process.
                - 2: detection done in the dual annealing process.

            If the callback implementation returns True, the algorithm will stop.
        x0 : ndarray, shape(n,), optional
            Coordinates of a single N-D starting point.

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a `OptimizeResult` object.
            Important attributes are: ``x`` the solution array, ``fun`` the value
            of the function at the solution, and ``message`` which describes the
            cause of the termination.
            See `OptimizeResult` for a description of other attributes.

        Notes
        -----
        This function implements the Dual Annealing optimization. This stochastic
        approach derived from [3]_ combines the generalization of CSA (Classical
        Simulated Annealing) and FSA (Fast Simulated Annealing) [1]_ [2]_ coupled
        to a strategy for applying a local search on accepted locations [4]_.
        An alternative implementation of this same algorithm is described in [5]_
        and benchmarks are presented in [6]_. This approach introduces an advanced
        method to refine the solution found by the generalized annealing
        process. This algorithm uses a distorted Cauchy-Lorentz visiting
        distribution, with its shape controlled by the parameter :math:`q_{v}`

        .. math::

            g_{q_{v}}(\Delta x(t)) \propto \frac{ \
            \left[T_{q_{v}}(t) \right]^{-\frac{D}{3-q_{v}}}}{ \
            \left[{1+(q_{v}-1)\frac{(\Delta x(t))^{2}} { \
            \left[T_{q_{v}}(t)\right]^{\frac{2}{3-q_{v}}}}}\right]^{ \
            \frac{1}{q_{v}-1}+\frac{D-1}{2}}}

        Where :math:`t` is the artificial time. This visiting distribution is used
        to generate a trial jump distance :math:`\Delta x(t)` of variable
        :math:`x(t)` under artificial temperature :math:`T_{q_{v}}(t)`.

        From the starting point, after calling the visiting distribution
        function, the acceptance probability is computed as follows:

        .. math::

            p_{q_{a}} = \min{\{1,\left[1-(1-q_{a}) \beta \Delta E \right]^{ \
            \frac{1}{1-q_{a}}}\}}

        Where :math:`q_{a}` is a acceptance parameter. For :math:`q_{a}<1`, zero
        acceptance probability is assigned to the cases where

        .. math::

            [1-(1-q_{a}) \beta \Delta E] < 0

        The artificial temperature :math:`T_{q_{v}}(t)` is decreased according to

        .. math::

            T_{q_{v}}(t) = T_{q_{v}}(1) \frac{2^{q_{v}-1}-1}{\left( \
            1 + t\right)^{q_{v}-1}-1}

        Where :math:`q_{v}` is the visiting parameter.

        .. versionadded:: 1.2.0

        References
        ----------
        .. [1] Tsallis C. Possible generalization of Boltzmann-Gibbs
            statistics. Journal of Statistical Physics, 52, 479-487 (1998).
        .. [2] Tsallis C, Stariolo DA. Generalized Simulated Annealing.
            Physica A, 233, 395-406 (1996).
        .. [3] Xiang Y, Sun DY, Fan W, Gong XG. Generalized Simulated
            Annealing Algorithm and Its Application to the Thomson Model.
            Physics Letters A, 233, 216-220 (1997).
        .. [4] Xiang Y, Gong XG. Efficiency of Generalized Simulated
            Annealing. Physical Review E, 62, 4473 (2000).
        .. [5] Xiang Y, Gubian S, Suomela B, Hoeng J. Generalized
            Simulated Annealing for Efficient Global Optimization: the GenSA
            Package for R. The R Journal, Volume 5/1 (2013).
        .. [6] Mullen, K. Continuous Global Optimization in R. Journal of
            Statistical Software, 60(6), 1 - 45, (2014).
            :doi:`10.18637/jss.v060.i06`

        Examples
        --------
        The following example is a 10-D problem, with many local minima.
        The function involved is called Rastrigin
        (https://en.wikipedia.org/wiki/Rastrigin_function)

        >>> import numpy as np
        >>> from scipy.optimize import dual_annealing
        >>> func = lambda x: np.sum(x*x - 10*np.cos(2*np.pi*x)) + 10*np.size(x)
        >>> lw = [-5.12] * 10
        >>> up = [5.12] * 10
        >>> ret = dual_annealing(func, bounds=list(zip(lw, up)))
        >>> ret.x
        array([-4.26437714e-09, -3.91699361e-09, -1.86149218e-09, -3.97165720e-09,
               -6.29151648e-09, -6.53145322e-09, -3.93616815e-09, -6.55623025e-09,
               -6.05775280e-09, -5.00668935e-09]) # random
        >>> ret.fun
        0.000000

    excitingmixing(F, xin, iter=None, alpha=None, alphamax=1.0, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using a tuned diagonal Jacobian approximation.

        The Jacobian matrix is diagonal and is tuned on each iteration.

        .. warning::

           This algorithm may be useful for specific problems, but whether
           it will work may depend strongly on the problem.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='excitingmixing'`` in particular.

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            Initial Jacobian approximation is (-1/alpha).
        alphamax : float, optional
            The entries of the diagonal Jacobian are kept in the range
            ``[alpha, alphamax]``.
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

    fixed_point(func, x0, args=(), xtol=1e-08, maxiter=500, method='del2')
        Find a fixed point of the function.

        Given a function of one or more variables and a starting point, find a
        fixed point of the function: i.e., where ``func(x0) == x0``.

        Parameters
        ----------
        func : function
            Function to evaluate.
        x0 : array_like
            Fixed point of function.
        args : tuple, optional
            Extra arguments to `func`.
        xtol : float, optional
            Convergence tolerance, defaults to 1e-08.
        maxiter : int, optional
            Maximum number of iterations, defaults to 500.
        method : {"del2", "iteration"}, optional
            Method of finding the fixed-point, defaults to "del2",
            which uses Steffensen's Method with Aitken's ``Del^2``
            convergence acceleration [1]_. The "iteration" method simply iterates
            the function until convergence is detected, without attempting to
            accelerate the convergence.

        References
        ----------
        .. [1] Burden, Faires, "Numerical Analysis", 5th edition, pg. 80

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import optimize
        >>> def func(x, c1, c2):
        ...    return np.sqrt(c1/(x+c2))
        >>> c1 = np.array([10,12.])
        >>> c2 = np.array([3, 5.])
        >>> optimize.fixed_point(func, [1.2, 1.3], args=(c1,c2))
        array([ 1.4920333 ,  1.37228132])

    fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, initial_simplex=None)
        Minimize a function using the downhill simplex algorithm.

        This algorithm only uses function values, not derivatives or second
        derivatives.

        Parameters
        ----------
        func : callable func(x,*args)
            The objective function to be minimized.
        x0 : ndarray
            Initial guess.
        args : tuple, optional
            Extra arguments passed to func, i.e., ``f(x,*args)``.
        xtol : float, optional
            Absolute error in xopt between iterations that is acceptable for
            convergence.
        ftol : number, optional
            Absolute error in func(xopt) between iterations that is acceptable for
            convergence.
        maxiter : int, optional
            Maximum number of iterations to perform.
        maxfun : number, optional
            Maximum number of function evaluations to make.
        full_output : bool, optional
            Set to True if fopt and warnflag outputs are desired.
        disp : bool, optional
            Set to True to print convergence messages.
        retall : bool, optional
            Set to True to return list of solutions at each iteration.
        callback : callable, optional
            Called after each iteration, as callback(xk), where xk is the
            current parameter vector.
        initial_simplex : array_like of shape (N + 1, N), optional
            Initial simplex. If given, overrides `x0`.
            ``initial_simplex[j,:]`` should contain the coordinates of
            the jth vertex of the ``N+1`` vertices in the simplex, where
            ``N`` is the dimension.

        Returns
        -------
        xopt : ndarray
            Parameter that minimizes function.
        fopt : float
            Value of function at minimum: ``fopt = func(xopt)``.
        iter : int
            Number of iterations performed.
        funcalls : int
            Number of function calls made.
        warnflag : int
            1 : Maximum number of function evaluations made.
            2 : Maximum number of iterations reached.
        allvecs : list
            Solution at each iteration.

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'Nelder-Mead' `method` in particular.

        Notes
        -----
        Uses a Nelder-Mead simplex algorithm to find the minimum of function of
        one or more variables.

        This algorithm has a long history of successful use in applications.
        But it will usually be slower than an algorithm that uses first or
        second derivative information. In practice, it can have poor
        performance in high-dimensional problems and is not robust to
        minimizing complicated functions. Additionally, there currently is no
        complete theory describing when the algorithm will successfully
        converge to the minimum, or how fast it will if it does. Both the ftol and
        xtol criteria must be met for convergence.

        Examples
        --------
        >>> def f(x):
        ...     return x**2

        >>> from scipy import optimize

        >>> minimum = optimize.fmin(f, 1)
        Optimization terminated successfully.
                 Current function value: 0.000000
                 Iterations: 17
                 Function evaluations: 34
        >>> minimum[0]
        -8.8817841970012523e-16

        References
        ----------
        .. [1] Nelder, J.A. and Mead, R. (1965), "A simplex method for function
               minimization", The Computer Journal, 7, pp. 308-313

        .. [2] Wright, M.H. (1996), "Direct Search Methods: Once Scorned, Now
               Respectable", in Numerical Analysis 1995, Proceedings of the
               1995 Dundee Biennial Conference in Numerical Analysis, D.F.
               Griffiths and G.A. Watson (Eds.), Addison Wesley Longman,
               Harlow, UK, pp. 191-208.

    fmin_bfgs(f, x0, fprime=None, args=(), gtol=1e-05, norm=inf, epsilon=np.float64(1.4901161193847656e-08), maxiter=None, full_output=0, disp=1, retall=0, callback=None, xrtol=0, c1=0.0001, c2=0.9, hess_inv0=None)
        Minimize a function using the BFGS algorithm.

        Parameters
        ----------
        f : callable ``f(x,*args)``
            Objective function to be minimized.
        x0 : ndarray
            Initial guess, shape (n,)
        fprime : callable ``f'(x,*args)``, optional
            Gradient of f.
        args : tuple, optional
            Extra arguments passed to f and fprime.
        gtol : float, optional
            Terminate successfully if gradient norm is less than `gtol`
        norm : float, optional
            Order of norm (Inf is max, -Inf is min)
        epsilon : int or ndarray, optional
            If `fprime` is approximated, use this value for the step size.
        callback : callable, optional
            An optional user-supplied function to call after each
            iteration. Called as ``callback(xk)``, where ``xk`` is the
            current parameter vector.
        maxiter : int, optional
            Maximum number of iterations to perform.
        full_output : bool, optional
            If True, return ``fopt``, ``func_calls``, ``grad_calls``, and
            ``warnflag`` in addition to ``xopt``.
        disp : bool, optional
            Print convergence message if True.
        retall : bool, optional
            Return a list of results at each iteration if True.
        xrtol : float, default: 0
            Relative tolerance for `x`. Terminate successfully if step
            size is less than ``xk * xrtol`` where ``xk`` is the current
            parameter vector.
        c1 : float, default: 1e-4
            Parameter for Armijo condition rule.
        c2 : float, default: 0.9
            Parameter for curvature condition rule.
        hess_inv0 : None or ndarray, optional``
            Initial inverse hessian estimate, shape (n, n). If None (default) then
            the identity matrix is used.

        Returns
        -------
        xopt : ndarray
            Parameters which minimize f, i.e., ``f(xopt) == fopt``.
        fopt : float
            Minimum value.
        gopt : ndarray
            Value of gradient at minimum, f'(xopt), which should be near 0.
        Bopt : ndarray
            Value of 1/f''(xopt), i.e., the inverse Hessian matrix.
        func_calls : int
            Number of function_calls made.
        grad_calls : int
            Number of gradient calls made.
        warnflag : integer
            1 : Maximum number of iterations exceeded.
            2 : Gradient and/or function calls not changing.
            3 : NaN result encountered.
        allvecs : list
            The value of `xopt` at each iteration. Only returned if `retall` is
            True.

        Notes
        -----
        Optimize the function, `f`, whose gradient is given by `fprime`
        using the quasi-Newton method of Broyden, Fletcher, Goldfarb,
        and Shanno (BFGS).

        Parameters `c1` and `c2` must satisfy ``0 < c1 < c2 < 1``.

        See Also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See ``method='BFGS'`` in particular.

        References
        ----------
        Wright, and Nocedal 'Numerical Optimization', 1999, p. 198.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import fmin_bfgs
        >>> def quadratic_cost(x, Q):
        ...     return x @ Q @ x
        ...
        >>> x0 = np.array([-3, -4])
        >>> cost_weight =  np.diag([1., 10.])
        >>> # Note that a trailing comma is necessary for a tuple with single element
        >>> fmin_bfgs(quadratic_cost, x0, args=(cost_weight,))
        Optimization terminated successfully.
                Current function value: 0.000000
                Iterations: 7                   # may vary
                Function evaluations: 24        # may vary
                Gradient evaluations: 8         # may vary
        array([ 2.85169950e-06, -4.61820139e-07])

        >>> def quadratic_cost_grad(x, Q):
        ...     return 2 * Q @ x
        ...
        >>> fmin_bfgs(quadratic_cost, x0, quadratic_cost_grad, args=(cost_weight,))
        Optimization terminated successfully.
                Current function value: 0.000000
                Iterations: 7
                Function evaluations: 8
                Gradient evaluations: 8
        array([ 2.85916637e-06, -4.54371951e-07])

    fmin_cg(f, x0, fprime=None, args=(), gtol=1e-05, norm=inf, epsilon=np.float64(1.4901161193847656e-08), maxiter=None, full_output=0, disp=1, retall=0, callback=None, c1=0.0001, c2=0.4)
        Minimize a function using a nonlinear conjugate gradient algorithm.

        Parameters
        ----------
        f : callable, ``f(x, *args)``
            Objective function to be minimized. Here `x` must be a 1-D array of
            the variables that are to be changed in the search for a minimum, and
            `args` are the other (fixed) parameters of `f`.
        x0 : ndarray
            A user-supplied initial estimate of `xopt`, the optimal value of `x`.
            It must be a 1-D array of values.
        fprime : callable, ``fprime(x, *args)``, optional
            A function that returns the gradient of `f` at `x`. Here `x` and `args`
            are as described above for `f`. The returned value must be a 1-D array.
            Defaults to None, in which case the gradient is approximated
            numerically (see `epsilon`, below).
        args : tuple, optional
            Parameter values passed to `f` and `fprime`. Must be supplied whenever
            additional fixed parameters are needed to completely specify the
            functions `f` and `fprime`.
        gtol : float, optional
            Stop when the norm of the gradient is less than `gtol`.
        norm : float, optional
            Order to use for the norm of the gradient
            (``-np.inf`` is min, ``np.inf`` is max).
        epsilon : float or ndarray, optional
            Step size(s) to use when `fprime` is approximated numerically. Can be a
            scalar or a 1-D array. Defaults to ``sqrt(eps)``, with eps the
            floating point machine precision.  Usually ``sqrt(eps)`` is about
            1.5e-8.
        maxiter : int, optional
            Maximum number of iterations to perform. Default is ``200 * len(x0)``.
        full_output : bool, optional
            If True, return `fopt`, `func_calls`, `grad_calls`, and `warnflag` in
            addition to `xopt`.  See the Returns section below for additional
            information on optional return values.
        disp : bool, optional
            If True, return a convergence message, followed by `xopt`.
        retall : bool, optional
            If True, add to the returned values the results of each iteration.
        callback : callable, optional
            An optional user-supplied function, called after each iteration.
            Called as ``callback(xk)``, where ``xk`` is the current value of `x0`.
        c1 : float, default: 1e-4
            Parameter for Armijo condition rule.
        c2 : float, default: 0.4
            Parameter for curvature condition rule.

        Returns
        -------
        xopt : ndarray
            Parameters which minimize f, i.e., ``f(xopt) == fopt``.
        fopt : float, optional
            Minimum value found, f(xopt). Only returned if `full_output` is True.
        func_calls : int, optional
            The number of function_calls made. Only returned if `full_output`
            is True.
        grad_calls : int, optional
            The number of gradient calls made. Only returned if `full_output` is
            True.
        warnflag : int, optional
            Integer value with warning status, only returned if `full_output` is
            True.

            0 : Success.

            1 : The maximum number of iterations was exceeded.

            2 : Gradient and/or function calls were not changing. May indicate
                that precision was lost, i.e., the routine did not converge.

            3 : NaN result encountered.

        allvecs : list of ndarray, optional
            List of arrays, containing the results at each iteration.
            Only returned if `retall` is True.

        See Also
        --------
        minimize : common interface to all `scipy.optimize` algorithms for
                   unconstrained and constrained minimization of multivariate
                   functions. It provides an alternative way to call
                   ``fmin_cg``, by specifying ``method='CG'``.

        Notes
        -----
        This conjugate gradient algorithm is based on that of Polak and Ribiere
        [1]_.

        Conjugate gradient methods tend to work better when:

        1. `f` has a unique global minimizing point, and no local minima or
           other stationary points,
        2. `f` is, at least locally, reasonably well approximated by a
           quadratic function of the variables,
        3. `f` is continuous and has a continuous gradient,
        4. `fprime` is not too large, e.g., has a norm less than 1000,
        5. The initial guess, `x0`, is reasonably close to `f` 's global
           minimizing point, `xopt`.

        Parameters `c1` and `c2` must satisfy ``0 < c1 < c2 < 1``.

        References
        ----------
        .. [1] Wright & Nocedal, "Numerical Optimization", 1999, pp. 120-122.

        Examples
        --------
        Example 1: seek the minimum value of the expression
        ``a*u**2 + b*u*v + c*v**2 + d*u + e*v + f`` for given values
        of the parameters and an initial guess ``(u, v) = (0, 0)``.

        >>> import numpy as np
        >>> args = (2, 3, 7, 8, 9, 10)  # parameter values
        >>> def f(x, *args):
        ...     u, v = x
        ...     a, b, c, d, e, f = args
        ...     return a*u**2 + b*u*v + c*v**2 + d*u + e*v + f
        >>> def gradf(x, *args):
        ...     u, v = x
        ...     a, b, c, d, e, f = args
        ...     gu = 2*a*u + b*v + d     # u-component of the gradient
        ...     gv = b*u + 2*c*v + e     # v-component of the gradient
        ...     return np.asarray((gu, gv))
        >>> x0 = np.asarray((0, 0))  # Initial guess.
        >>> from scipy import optimize
        >>> res1 = optimize.fmin_cg(f, x0, fprime=gradf, args=args)
        Optimization terminated successfully.
                 Current function value: 1.617021
                 Iterations: 4
                 Function evaluations: 8
                 Gradient evaluations: 8
        >>> res1
        array([-1.80851064, -0.25531915])

        Example 2: solve the same problem using the `minimize` function.
        (This `myopts` dictionary shows all of the available options,
        although in practice only non-default values would be needed.
        The returned value will be a dictionary.)

        >>> opts = {'maxiter' : None,    # default value.
        ...         'disp' : True,    # non-default value.
        ...         'gtol' : 1e-5,    # default value.
        ...         'norm' : np.inf,  # default value.
        ...         'eps' : 1.4901161193847656e-08}  # default value.
        >>> res2 = optimize.minimize(f, x0, jac=gradf, args=args,
        ...                          method='CG', options=opts)
        Optimization terminated successfully.
                Current function value: 1.617021
                Iterations: 4
                Function evaluations: 8
                Gradient evaluations: 8
        >>> res2.x  # minimum found
        array([-1.80851064, -0.25531915])

    fmin_cobyla(func, x0, cons, args=(), consargs=None, rhobeg=1.0, rhoend=0.0001, maxfun=1000, disp=None, catol=0.0002, *, callback=None)
        Minimize a function using the Constrained Optimization By Linear
        Approximation (COBYLA) method. This method wraps a FORTRAN
        implementation of the algorithm.

        Parameters
        ----------
        func : callable
            Function to minimize. In the form func(x, \*args).
        x0 : ndarray
            Initial guess.
        cons : sequence
            Constraint functions; must all be ``>=0`` (a single function
            if only 1 constraint). Each function takes the parameters `x`
            as its first argument, and it can return either a single number or
            an array or list of numbers.
        args : tuple, optional
            Extra arguments to pass to function.
        consargs : tuple, optional
            Extra arguments to pass to constraint functions (default of None means
            use same extra arguments as those passed to func).
            Use ``()`` for no extra arguments.
        rhobeg : float, optional
            Reasonable initial changes to the variables.
        rhoend : float, optional
            Final accuracy in the optimization (not precisely guaranteed). This
            is a lower bound on the size of the trust region.
        disp : {0, 1, 2, 3}, optional
            Controls the frequency of output; 0 implies no output.
        maxfun : int, optional
            Maximum number of function evaluations.
        catol : float, optional
            Absolute tolerance for constraint violations.
        callback : callable, optional
            Called after each iteration, as ``callback(x)``, where ``x`` is the
            current parameter vector.

        Returns
        -------
        x : ndarray
            The argument that minimises `f`.

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'COBYLA' `method` in particular.

        Notes
        -----
        This algorithm is based on linear approximations to the objective
        function and each constraint. We briefly describe the algorithm.

        Suppose the function is being minimized over k variables. At the
        jth iteration the algorithm has k+1 points v_1, ..., v_(k+1),
        an approximate solution x_j, and a radius RHO_j.
        (i.e., linear plus a constant) approximations to the objective
        function and constraint functions such that their function values
        agree with the linear approximation on the k+1 points v_1,.., v_(k+1).
        This gives a linear program to solve (where the linear approximations
        of the constraint functions are constrained to be non-negative).

        However, the linear approximations are likely only good
        approximations near the current simplex, so the linear program is
        given the further requirement that the solution, which
        will become x_(j+1), must be within RHO_j from x_j. RHO_j only
        decreases, never increases. The initial RHO_j is rhobeg and the
        final RHO_j is rhoend. In this way COBYLA's iterations behave
        like a trust region algorithm.

        Additionally, the linear program may be inconsistent, or the
        approximation may give poor improvement. For details about
        how these issues are resolved, as well as how the points v_i are
        updated, refer to the source code or the references below.


        References
        ----------
        Powell M.J.D. (1994), "A direct search optimization method that models
        the objective and constraint functions by linear interpolation.", in
        Advances in Optimization and Numerical Analysis, eds. S. Gomez and
        J-P Hennart, Kluwer Academic (Dordrecht), pp. 51-67

        Powell M.J.D. (1998), "Direct search algorithms for optimization
        calculations", Acta Numerica 7, 287-336

        Powell M.J.D. (2007), "A view of algorithms for optimization without
        derivatives", Cambridge University Technical Report DAMTP 2007/NA03


        Examples
        --------
        Minimize the objective function f(x,y) = x*y subject
        to the constraints x**2 + y**2 < 1 and y > 0::

            >>> def objective(x):
            ...     return x[0]*x[1]
            ...
            >>> def constr1(x):
            ...     return 1 - (x[0]**2 + x[1]**2)
            ...
            >>> def constr2(x):
            ...     return x[1]
            ...
            >>> from scipy.optimize import fmin_cobyla
            >>> fmin_cobyla(objective, [0.0, 0.1], [constr1, constr2], rhoend=1e-7)
            array([-0.70710685,  0.70710671])

        The exact solution is (-sqrt(2)/2, sqrt(2)/2).

    fmin_l_bfgs_b(func, x0, fprime=None, args=(), approx_grad=0, bounds=None, m=10, factr=10000000.0, pgtol=1e-05, epsilon=1e-08, iprint=-1, maxfun=15000, maxiter=15000, disp=None, callback=None, maxls=20)
        Minimize a function func using the L-BFGS-B algorithm.

        Parameters
        ----------
        func : callable f(x,*args)
            Function to minimize.
        x0 : ndarray
            Initial guess.
        fprime : callable fprime(x,*args), optional
            The gradient of `func`. If None, then `func` returns the function
            value and the gradient (``f, g = func(x, *args)``), unless
            `approx_grad` is True in which case `func` returns only ``f``.
        args : sequence, optional
            Arguments to pass to `func` and `fprime`.
        approx_grad : bool, optional
            Whether to approximate the gradient numerically (in which case
            `func` returns only the function value).
        bounds : list, optional
            ``(min, max)`` pairs for each element in ``x``, defining
            the bounds on that parameter. Use None or +-inf for one of ``min`` or
            ``max`` when there is no bound in that direction.
        m : int, optional
            The maximum number of variable metric corrections
            used to define the limited memory matrix. (The limited memory BFGS
            method does not store the full hessian but uses this many terms in an
            approximation to it.)
        factr : float, optional
            The iteration stops when
            ``(f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr * eps``,
            where ``eps`` is the machine precision, which is automatically
            generated by the code. Typical values for `factr` are: 1e12 for
            low accuracy; 1e7 for moderate accuracy; 10.0 for extremely
            high accuracy. See Notes for relationship to `ftol`, which is exposed
            (instead of `factr`) by the `scipy.optimize.minimize` interface to
            L-BFGS-B.
        pgtol : float, optional
            The iteration will stop when
            ``max{|proj g_i | i = 1, ..., n} <= pgtol``
            where ``proj g_i`` is the i-th component of the projected gradient.
        epsilon : float, optional
            Step size used when `approx_grad` is True, for numerically
            calculating the gradient
        iprint : int, optional
            Controls the frequency of output. ``iprint < 0`` means no output;
            ``iprint = 0``    print only one line at the last iteration;
            ``0 < iprint < 99`` print also f and ``|proj g|`` every iprint iterations;
            ``iprint = 99``   print details of every iteration except n-vectors;
            ``iprint = 100``  print also the changes of active set and final x;
            ``iprint > 100``  print details of every iteration including x and g.
        disp : int, optional
            If zero, then no output. If a positive number, then this over-rides
            `iprint` (i.e., `iprint` gets the value of `disp`).
        maxfun : int, optional
            Maximum number of function evaluations. Note that this function
            may violate the limit because of evaluating gradients by numerical
            differentiation.
        maxiter : int, optional
            Maximum number of iterations.
        callback : callable, optional
            Called after each iteration, as ``callback(xk)``, where ``xk`` is the
            current parameter vector.
        maxls : int, optional
            Maximum number of line search steps (per iteration). Default is 20.

        Returns
        -------
        x : array_like
            Estimated position of the minimum.
        f : float
            Value of `func` at the minimum.
        d : dict
            Information dictionary.

            * d['warnflag'] is

              - 0 if converged,
              - 1 if too many function evaluations or too many iterations,
              - 2 if stopped for another reason, given in d['task']

            * d['grad'] is the gradient at the minimum (should be 0 ish)
            * d['funcalls'] is the number of function calls made.
            * d['nit'] is the number of iterations.

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'L-BFGS-B' `method` in particular. Note that the
            `ftol` option is made available via that interface, while `factr` is
            provided via this interface, where `factr` is the factor multiplying
            the default machine floating-point precision to arrive at `ftol`:
            ``ftol = factr * numpy.finfo(float).eps``.

        Notes
        -----
        License of L-BFGS-B (FORTRAN code):

        The version included here (in fortran code) is 3.0
        (released April 25, 2011). It was written by Ciyou Zhu, Richard Byrd,
        and Jorge Nocedal <nocedal@ece.nwu.edu>. It carries the following
        condition for use:

        This software is freely available, but we expect that all publications
        describing work using this software, or all commercial products using it,
        quote at least one of the references given below. This software is released
        under the BSD License.

        References
        ----------
        * R. H. Byrd, P. Lu and J. Nocedal. A Limited Memory Algorithm for Bound
          Constrained Optimization, (1995), SIAM Journal on Scientific and
          Statistical Computing, 16, 5, pp. 1190-1208.
        * C. Zhu, R. H. Byrd and J. Nocedal. L-BFGS-B: Algorithm 778: L-BFGS-B,
          FORTRAN routines for large scale bound constrained optimization (1997),
          ACM Transactions on Mathematical Software, 23, 4, pp. 550 - 560.
        * J.L. Morales and J. Nocedal. L-BFGS-B: Remark on Algorithm 778: L-BFGS-B,
          FORTRAN routines for large scale bound constrained optimization (2011),
          ACM Transactions on Mathematical Software, 38, 1.

        Examples
        --------
        Solve a linear regression problem via `fmin_l_bfgs_b`. To do this, first we define
        an objective function ``f(m, b) = (y - y_model)**2``, where `y` describes the
        observations and `y_model` the prediction of the linear model as
        ``y_model = m*x + b``. The bounds for the parameters, ``m`` and ``b``, are arbitrarily
        chosen as ``(0,5)`` and ``(5,10)`` for this example.

        >>> import numpy as np
        >>> from scipy.optimize import fmin_l_bfgs_b
        >>> X = np.arange(0, 10, 1)
        >>> M = 2
        >>> B = 3
        >>> Y = M * X + B
        >>> def func(parameters, *args):
        ...     x = args[0]
        ...     y = args[1]
        ...     m, b = parameters
        ...     y_model = m*x + b
        ...     error = sum(np.power((y - y_model), 2))
        ...     return error

        >>> initial_values = np.array([0.0, 1.0])

        >>> x_opt, f_opt, info = fmin_l_bfgs_b(func, x0=initial_values, args=(X, Y),
        ...                                    approx_grad=True)
        >>> x_opt, f_opt
        array([1.99999999, 3.00000006]), 1.7746231151323805e-14  # may vary

        The optimized parameters in ``x_opt`` agree with the ground truth parameters
        ``m`` and ``b``. Next, let us perform a bound contrained optimization using the `bounds`
        parameter.

        >>> bounds = [(0, 5), (5, 10)]
        >>> x_opt, f_op, info = fmin_l_bfgs_b(func, x0=initial_values, args=(X, Y),
        ...                                   approx_grad=True, bounds=bounds)
        >>> x_opt, f_opt
        array([1.65990508, 5.31649385]), 15.721334516453945  # may vary

    fmin_ncg(f, x0, fprime, fhess_p=None, fhess=None, args=(), avextol=1e-05, epsilon=np.float64(1.4901161193847656e-08), maxiter=None, full_output=0, disp=1, retall=0, callback=None, c1=0.0001, c2=0.9)
        Unconstrained minimization of a function using the Newton-CG method.

        Parameters
        ----------
        f : callable ``f(x, *args)``
            Objective function to be minimized.
        x0 : ndarray
            Initial guess.
        fprime : callable ``f'(x, *args)``
            Gradient of f.
        fhess_p : callable ``fhess_p(x, p, *args)``, optional
            Function which computes the Hessian of f times an
            arbitrary vector, p.
        fhess : callable ``fhess(x, *args)``, optional
            Function to compute the Hessian matrix of f.
        args : tuple, optional
            Extra arguments passed to f, fprime, fhess_p, and fhess
            (the same set of extra arguments is supplied to all of
            these functions).
        epsilon : float or ndarray, optional
            If fhess is approximated, use this value for the step size.
        callback : callable, optional
            An optional user-supplied function which is called after
            each iteration. Called as callback(xk), where xk is the
            current parameter vector.
        avextol : float, optional
            Convergence is assumed when the average relative error in
            the minimizer falls below this amount.
        maxiter : int, optional
            Maximum number of iterations to perform.
        full_output : bool, optional
            If True, return the optional outputs.
        disp : bool, optional
            If True, print convergence message.
        retall : bool, optional
            If True, return a list of results at each iteration.
        c1 : float, default: 1e-4
            Parameter for Armijo condition rule.
        c2 : float, default: 0.9
            Parameter for curvature condition rule

        Returns
        -------
        xopt : ndarray
            Parameters which minimize f, i.e., ``f(xopt) == fopt``.
        fopt : float
            Value of the function at xopt, i.e., ``fopt = f(xopt)``.
        fcalls : int
            Number of function calls made.
        gcalls : int
            Number of gradient calls made.
        hcalls : int
            Number of Hessian calls made.
        warnflag : int
            Warnings generated by the algorithm.
            1 : Maximum number of iterations exceeded.
            2 : Line search failure (precision loss).
            3 : NaN result encountered.
        allvecs : list
            The result at each iteration, if retall is True (see below).

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'Newton-CG' `method` in particular.

        Notes
        -----
        Only one of `fhess_p` or `fhess` need to be given.  If `fhess`
        is provided, then `fhess_p` will be ignored. If neither `fhess`
        nor `fhess_p` is provided, then the hessian product will be
        approximated using finite differences on `fprime`. `fhess_p`
        must compute the hessian times an arbitrary vector. If it is not
        given, finite-differences on `fprime` are used to compute
        it.

        Newton-CG methods are also called truncated Newton methods. This
        function differs from scipy.optimize.fmin_tnc because

        1. scipy.optimize.fmin_ncg is written purely in Python using NumPy
            and scipy while scipy.optimize.fmin_tnc calls a C function.
        2. scipy.optimize.fmin_ncg is only for unconstrained minimization
            while scipy.optimize.fmin_tnc is for unconstrained minimization
            or box constrained minimization. (Box constraints give
            lower and upper bounds for each variable separately.)

        Parameters `c1` and `c2` must satisfy ``0 < c1 < c2 < 1``.

        References
        ----------
        Wright & Nocedal, 'Numerical Optimization', 1999, p. 140.

    fmin_powell(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, direc=None)
        Minimize a function using modified Powell's method.

        This method only uses function values, not derivatives.

        Parameters
        ----------
        func : callable f(x,*args)
            Objective function to be minimized.
        x0 : ndarray
            Initial guess.
        args : tuple, optional
            Extra arguments passed to func.
        xtol : float, optional
            Line-search error tolerance.
        ftol : float, optional
            Relative error in ``func(xopt)`` acceptable for convergence.
        maxiter : int, optional
            Maximum number of iterations to perform.
        maxfun : int, optional
            Maximum number of function evaluations to make.
        full_output : bool, optional
            If True, ``fopt``, ``xi``, ``direc``, ``iter``, ``funcalls``, and
            ``warnflag`` are returned.
        disp : bool, optional
            If True, print convergence messages.
        retall : bool, optional
            If True, return a list of the solution at each iteration.
        callback : callable, optional
            An optional user-supplied function, called after each
            iteration.  Called as ``callback(xk)``, where ``xk`` is the
            current parameter vector.
        direc : ndarray, optional
            Initial fitting step and parameter order set as an (N, N) array, where N
            is the number of fitting parameters in `x0`. Defaults to step size 1.0
            fitting all parameters simultaneously (``np.eye((N, N))``). To
            prevent initial consideration of values in a step or to change initial
            step size, set to 0 or desired step size in the Jth position in the Mth
            block, where J is the position in `x0` and M is the desired evaluation
            step, with steps being evaluated in index order. Step size and ordering
            will change freely as minimization proceeds.

        Returns
        -------
        xopt : ndarray
            Parameter which minimizes `func`.
        fopt : number
            Value of function at minimum: ``fopt = func(xopt)``.
        direc : ndarray
            Current direction set.
        iter : int
            Number of iterations.
        funcalls : int
            Number of function calls made.
        warnflag : int
            Integer warning flag:
                1 : Maximum number of function evaluations.
                2 : Maximum number of iterations.
                3 : NaN result encountered.
                4 : The result is out of the provided bounds.
        allvecs : list
            List of solutions at each iteration.

        See also
        --------
        minimize: Interface to unconstrained minimization algorithms for
            multivariate functions. See the 'Powell' method in particular.

        Notes
        -----
        Uses a modification of Powell's method to find the minimum of
        a function of N variables. Powell's method is a conjugate
        direction method.

        The algorithm has two loops. The outer loop merely iterates over the inner
        loop. The inner loop minimizes over each current direction in the direction
        set. At the end of the inner loop, if certain conditions are met, the
        direction that gave the largest decrease is dropped and replaced with the
        difference between the current estimated x and the estimated x from the
        beginning of the inner-loop.

        The technical conditions for replacing the direction of greatest
        increase amount to checking that

        1. No further gain can be made along the direction of greatest increase
           from that iteration.
        2. The direction of greatest increase accounted for a large sufficient
           fraction of the decrease in the function value from that iteration of
           the inner loop.

        References
        ----------
        Powell M.J.D. (1964) An efficient method for finding the minimum of a
        function of several variables without calculating derivatives,
        Computer Journal, 7 (2):155-162.

        Press W., Teukolsky S.A., Vetterling W.T., and Flannery B.P.:
        Numerical Recipes (any edition), Cambridge University Press

        Examples
        --------
        >>> def f(x):
        ...     return x**2

        >>> from scipy import optimize

        >>> minimum = optimize.fmin_powell(f, -1)
        Optimization terminated successfully.
                 Current function value: 0.000000
                 Iterations: 2
                 Function evaluations: 16
        >>> minimum
        array(0.0)

    fmin_slsqp(func, x0, eqcons=(), f_eqcons=None, ieqcons=(), f_ieqcons=None, bounds=(), fprime=None, fprime_eqcons=None, fprime_ieqcons=None, args=(), iter=100, acc=1e-06, iprint=1, disp=None, full_output=0, epsilon=np.float64(1.4901161193847656e-08), callback=None)
        Minimize a function using Sequential Least Squares Programming

        Python interface function for the SLSQP Optimization subroutine
        originally implemented by Dieter Kraft.

        Parameters
        ----------
        func : callable f(x,*args)
            Objective function.  Must return a scalar.
        x0 : 1-D ndarray of float
            Initial guess for the independent variable(s).
        eqcons : list, optional
            A list of functions of length n such that
            eqcons[j](x,*args) == 0.0 in a successfully optimized
            problem.
        f_eqcons : callable f(x,*args), optional
            Returns a 1-D array in which each element must equal 0.0 in a
            successfully optimized problem. If f_eqcons is specified,
            eqcons is ignored.
        ieqcons : list, optional
            A list of functions of length n such that
            ieqcons[j](x,*args) >= 0.0 in a successfully optimized
            problem.
        f_ieqcons : callable f(x,*args), optional
            Returns a 1-D ndarray in which each element must be greater or
            equal to 0.0 in a successfully optimized problem. If
            f_ieqcons is specified, ieqcons is ignored.
        bounds : list, optional
            A list of tuples specifying the lower and upper bound
            for each independent variable [(xl0, xu0),(xl1, xu1),...]
            Infinite values will be interpreted as large floating values.
        fprime : callable `f(x,*args)`, optional
            A function that evaluates the partial derivatives of func.
        fprime_eqcons : callable `f(x,*args)`, optional
            A function of the form `f(x, *args)` that returns the m by n
            array of equality constraint normals. If not provided,
            the normals will be approximated. The array returned by
            fprime_eqcons should be sized as ( len(eqcons), len(x0) ).
        fprime_ieqcons : callable `f(x,*args)`, optional
            A function of the form `f(x, *args)` that returns the m by n
            array of inequality constraint normals. If not provided,
            the normals will be approximated. The array returned by
            fprime_ieqcons should be sized as ( len(ieqcons), len(x0) ).
        args : sequence, optional
            Additional arguments passed to func and fprime.
        iter : int, optional
            The maximum number of iterations.
        acc : float, optional
            Requested accuracy.
        iprint : int, optional
            The verbosity of fmin_slsqp :

            * iprint <= 0 : Silent operation
            * iprint == 1 : Print summary upon completion (default)
            * iprint >= 2 : Print status of each iterate and summary
        disp : int, optional
            Overrides the iprint interface (preferred).
        full_output : bool, optional
            If False, return only the minimizer of func (default).
            Otherwise, output final objective function and summary
            information.
        epsilon : float, optional
            The step size for finite-difference derivative estimates.
        callback : callable, optional
            Called after each iteration, as ``callback(x)``, where ``x`` is the
            current parameter vector.

        Returns
        -------
        out : ndarray of float
            The final minimizer of func.
        fx : ndarray of float, if full_output is true
            The final value of the objective function.
        its : int, if full_output is true
            The number of iterations.
        imode : int, if full_output is true
            The exit mode from the optimizer (see below).
        smode : string, if full_output is true
            Message describing the exit mode from the optimizer.

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'SLSQP' `method` in particular.

        Notes
        -----
        Exit modes are defined as follows ::

            -1 : Gradient evaluation required (g & a)
             0 : Optimization terminated successfully
             1 : Function evaluation required (f & c)
             2 : More equality constraints than independent variables
             3 : More than 3*n iterations in LSQ subproblem
             4 : Inequality constraints incompatible
             5 : Singular matrix E in LSQ subproblem
             6 : Singular matrix C in LSQ subproblem
             7 : Rank-deficient equality constraint subproblem HFTI
             8 : Positive directional derivative for linesearch
             9 : Iteration limit reached

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-sqlsp>`.

    fmin_tnc(func, x0, fprime=None, args=(), approx_grad=0, bounds=None, epsilon=1e-08, scale=None, offset=None, messages=15, maxCGit=-1, maxfun=None, eta=-1, stepmx=0, accuracy=0, fmin=0, ftol=-1, xtol=-1, pgtol=-1, rescale=-1, disp=None, callback=None)
        Minimize a function with variables subject to bounds, using
        gradient information in a truncated Newton algorithm. This
        method wraps a C implementation of the algorithm.

        Parameters
        ----------
        func : callable ``func(x, *args)``
            Function to minimize.  Must do one of:

            1. Return f and g, where f is the value of the function and g its
               gradient (a list of floats).

            2. Return the function value but supply gradient function
               separately as `fprime`.

            3. Return the function value and set ``approx_grad=True``.

            If the function returns None, the minimization
            is aborted.
        x0 : array_like
            Initial estimate of minimum.
        fprime : callable ``fprime(x, *args)``, optional
            Gradient of `func`. If None, then either `func` must return the
            function value and the gradient (``f,g = func(x, *args)``)
            or `approx_grad` must be True.
        args : tuple, optional
            Arguments to pass to function.
        approx_grad : bool, optional
            If true, approximate the gradient numerically.
        bounds : list, optional
            (min, max) pairs for each element in x0, defining the
            bounds on that parameter. Use None or +/-inf for one of
            min or max when there is no bound in that direction.
        epsilon : float, optional
            Used if approx_grad is True. The stepsize in a finite
            difference approximation for fprime.
        scale : array_like, optional
            Scaling factors to apply to each variable. If None, the
            factors are up-low for interval bounded variables and
            1+|x| for the others. Defaults to None.
        offset : array_like, optional
            Value to subtract from each variable. If None, the
            offsets are (up+low)/2 for interval bounded variables
            and x for the others.
        messages : int, optional
            Bit mask used to select messages display during
            minimization values defined in the MSGS dict. Defaults to
            MGS_ALL.
        disp : int, optional
            Integer interface to messages. 0 = no message, 5 = all messages
        maxCGit : int, optional
            Maximum number of hessian*vector evaluations per main
            iteration. If maxCGit == 0, the direction chosen is
            -gradient if maxCGit < 0, maxCGit is set to
            max(1,min(50,n/2)). Defaults to -1.
        maxfun : int, optional
            Maximum number of function evaluation. If None, maxfun is
            set to max(100, 10*len(x0)). Defaults to None. Note that this function
            may violate the limit because of evaluating gradients by numerical
            differentiation.
        eta : float, optional
            Severity of the line search. If < 0 or > 1, set to 0.25.
            Defaults to -1.
        stepmx : float, optional
            Maximum step for the line search. May be increased during
            call. If too small, it will be set to 10.0. Defaults to 0.
        accuracy : float, optional
            Relative precision for finite difference calculations. If
            <= machine_precision, set to sqrt(machine_precision).
            Defaults to 0.
        fmin : float, optional
            Minimum function value estimate. Defaults to 0.
        ftol : float, optional
            Precision goal for the value of f in the stopping criterion.
            If ftol < 0.0, ftol is set to 0.0 defaults to -1.
        xtol : float, optional
            Precision goal for the value of x in the stopping
            criterion (after applying x scaling factors). If xtol <
            0.0, xtol is set to sqrt(machine_precision). Defaults to
            -1.
        pgtol : float, optional
            Precision goal for the value of the projected gradient in
            the stopping criterion (after applying x scaling factors).
            If pgtol < 0.0, pgtol is set to 1e-2 * sqrt(accuracy).
            Setting it to 0.0 is not recommended. Defaults to -1.
        rescale : float, optional
            Scaling factor (in log10) used to trigger f value
            rescaling. If 0, rescale at each iteration. If a large
            value, never rescale. If < 0, rescale is set to 1.3.
        callback : callable, optional
            Called after each iteration, as callback(xk), where xk is the
            current parameter vector.

        Returns
        -------
        x : ndarray
            The solution.
        nfeval : int
            The number of function evaluations.
        rc : int
            Return code, see below

        See also
        --------
        minimize: Interface to minimization algorithms for multivariate
            functions. See the 'TNC' `method` in particular.

        Notes
        -----
        The underlying algorithm is truncated Newton, also called
        Newton Conjugate-Gradient. This method differs from
        scipy.optimize.fmin_ncg in that

        1. it wraps a C implementation of the algorithm
        2. it allows each variable to be given an upper and lower bound.

        The algorithm incorporates the bound constraints by determining
        the descent direction as in an unconstrained truncated Newton,
        but never taking a step-size large enough to leave the space
        of feasible x's. The algorithm keeps track of a set of
        currently active constraints, and ignores them when computing
        the minimum allowable step size. (The x's associated with the
        active constraint are kept fixed.) If the maximum allowable
        step size is zero then a new constraint is added. At the end
        of each iteration one of the constraints may be deemed no
        longer active and removed. A constraint is considered
        no longer active is if it is currently active
        but the gradient for that variable points inward from the
        constraint. The specific constraint removed is the one
        associated with the variable of largest index whose
        constraint is no longer active.

        Return codes are defined as follows::

            -1 : Infeasible (lower bound > upper bound)
             0 : Local minimum reached (|pg| ~= 0)
             1 : Converged (|f_n-f_(n-1)| ~= 0)
             2 : Converged (|x_n-x_(n-1)| ~= 0)
             3 : Max. number of function evaluations reached
             4 : Linear search failed
             5 : All lower bounds are equal to the upper bounds
             6 : Unable to progress
             7 : User requested end of minimization

        References
        ----------
        Wright S., Nocedal J. (2006), 'Numerical Optimization'

        Nash S.G. (1984), "Newton-Type Minimization Via the Lanczos Method",
        SIAM Journal of Numerical Analysis 21, pp. 770-778

    fminbound(func, x1, x2, args=(), xtol=1e-05, maxfun=500, full_output=0, disp=1)
        Bounded minimization for scalar functions.

        Parameters
        ----------
        func : callable f(x,*args)
            Objective function to be minimized (must accept and return scalars).
        x1, x2 : float or array scalar
            Finite optimization bounds.
        args : tuple, optional
            Extra arguments passed to function.
        xtol : float, optional
            The convergence tolerance.
        maxfun : int, optional
            Maximum number of function evaluations allowed.
        full_output : bool, optional
            If True, return optional outputs.
        disp : int, optional
            If non-zero, print messages.
                0 : no message printing.
                1 : non-convergence notification messages only.
                2 : print a message on convergence too.
                3 : print iteration results.


        Returns
        -------
        xopt : ndarray
            Parameters (over given interval) which minimize the
            objective function.
        fval : number
            (Optional output) The function value evaluated at the minimizer.
        ierr : int
            (Optional output) An error flag (0 if converged, 1 if maximum number of
            function calls reached).
        numfunc : int
            (Optional output) The number of function calls made.

        See also
        --------
        minimize_scalar: Interface to minimization algorithms for scalar
            univariate functions. See the 'Bounded' `method` in particular.

        Notes
        -----
        Finds a local minimizer of the scalar function `func` in the
        interval x1 < xopt < x2 using Brent's method. (See `brent`
        for auto-bracketing.)

        References
        ----------
        .. [1] Forsythe, G.E., M. A. Malcolm, and C. B. Moler. "Computer Methods
               for Mathematical Computations." Prentice-Hall Series in Automatic
               Computation 259 (1977).
        .. [2] Brent, Richard P. Algorithms for Minimization Without Derivatives.
               Courier Corporation, 2013.

        Examples
        --------
        `fminbound` finds the minimizer of the function in the given range.
        The following examples illustrate this.

        >>> from scipy import optimize
        >>> def f(x):
        ...     return (x-1)**2
        >>> minimizer = optimize.fminbound(f, -4, 4)
        >>> minimizer
        1.0
        >>> minimum = f(minimizer)
        >>> minimum
        0.0
        >>> res = optimize.fminbound(f, 3, 4, full_output=True)
        >>> minimizer, fval, ierr, numfunc = res
        >>> minimizer
        3.000005960860986
        >>> minimum = f(minimizer)
        >>> minimum, fval
        (4.000023843479476, 4.000023843479476)

    fsolve(func, x0, args=(), fprime=None, full_output=0, col_deriv=0, xtol=1.49012e-08, maxfev=0, band=None, epsfcn=None, factor=100, diag=None)
        Find the roots of a function.

        Return the roots of the (non-linear) equations defined by
        ``func(x) = 0`` given a starting estimate.

        Parameters
        ----------
        func : callable ``f(x, *args)``
            A function that takes at least one (possibly vector) argument,
            and returns a value of the same length.
        x0 : ndarray
            The starting estimate for the roots of ``func(x) = 0``.
        args : tuple, optional
            Any extra arguments to `func`.
        fprime : callable ``f(x, *args)``, optional
            A function to compute the Jacobian of `func` with derivatives
            across the rows. By default, the Jacobian will be estimated.
        full_output : bool, optional
            If True, return optional outputs.
        col_deriv : bool, optional
            Specify whether the Jacobian function computes derivatives down
            the columns (faster, because there is no transpose operation).
        xtol : float, optional
            The calculation will terminate if the relative error between two
            consecutive iterates is at most `xtol`.
        maxfev : int, optional
            The maximum number of calls to the function. If zero, then
            ``100*(N+1)`` is the maximum where N is the number of elements
            in `x0`.
        band : tuple, optional
            If set to a two-sequence containing the number of sub- and
            super-diagonals within the band of the Jacobi matrix, the
            Jacobi matrix is considered banded (only for ``fprime=None``).
        epsfcn : float, optional
            A suitable step length for the forward-difference
            approximation of the Jacobian (for ``fprime=None``). If
            `epsfcn` is less than the machine precision, it is assumed
            that the relative errors in the functions are of the order of
            the machine precision.
        factor : float, optional
            A parameter determining the initial step bound
            (``factor * || diag * x||``). Should be in the interval
            ``(0.1, 100)``.
        diag : sequence, optional
            N positive entries that serve as a scale factors for the
            variables.

        Returns
        -------
        x : ndarray
            The solution (or the result of the last iteration for
            an unsuccessful call).
        infodict : dict
            A dictionary of optional outputs with the keys:

            ``nfev``
                number of function calls
            ``njev``
                number of Jacobian calls
            ``fvec``
                function evaluated at the output
            ``fjac``
                the orthogonal matrix, q, produced by the QR
                factorization of the final approximate Jacobian
                matrix, stored column wise
            ``r``
                upper triangular matrix produced by QR factorization
                of the same matrix
            ``qtf``
                the vector ``(transpose(q) * fvec)``

        ier : int
            An integer flag.  Set to 1 if a solution was found, otherwise refer
            to `mesg` for more information.
        mesg : str
            If no solution is found, `mesg` details the cause of failure.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See the ``method='hybr'`` in particular.

        Notes
        -----
        ``fsolve`` is a wrapper around MINPACK's hybrd and hybrj algorithms.

        Examples
        --------
        Find a solution to the system of equations:
        ``x0*cos(x1) = 4,  x1*x0 - x1 = 5``.

        >>> import numpy as np
        >>> from scipy.optimize import fsolve
        >>> def func(x):
        ...     return [x[0] * np.cos(x[1]) - 4,
        ...             x[1] * x[0] - x[1] - 5]
        >>> root = fsolve(func, [1, 1])
        >>> root
        array([6.50409711, 0.90841421])
        >>> np.isclose(func(root), [0.0, 0.0])  # func(root) should be almost 0.0.
        array([ True,  True])

    golden(func, args=(), brack=None, tol=np.float64(1.4901161193847656e-08), full_output=0, maxiter=5000)
        Return the minimizer of a function of one variable using the golden section
        method.

        Given a function of one variable and a possible bracketing interval,
        return a minimizer of the function isolated to a fractional precision of
        tol.

        Parameters
        ----------
        func : callable func(x,*args)
            Objective function to minimize.
        args : tuple, optional
            Additional arguments (if present), passed to func.
        brack : tuple, optional
            Either a triple ``(xa, xb, xc)`` where ``xa < xb < xc`` and
            ``func(xb) < func(xa) and  func(xb) < func(xc)``, or a pair (xa, xb)
            to be used as initial points for a downhill bracket search (see
            `scipy.optimize.bracket`).
            The minimizer ``x`` will not necessarily satisfy ``xa <= x <= xb``.
        tol : float, optional
            x tolerance stop criterion
        full_output : bool, optional
            If True, return optional outputs.
        maxiter : int
            Maximum number of iterations to perform.

        Returns
        -------
        xmin : ndarray
            Optimum point.
        fval : float
            (Optional output) Optimum function value.
        funcalls : int
            (Optional output) Number of objective function evaluations made.

        See also
        --------
        minimize_scalar: Interface to minimization algorithms for scalar
            univariate functions. See the 'Golden' `method` in particular.

        Notes
        -----
        Uses analog of bisection method to decrease the bracketed
        interval.

        Examples
        --------
        We illustrate the behaviour of the function when `brack` is of
        size 2 and 3, respectively. In the case where `brack` is of the
        form (xa,xb), we can see for the given values, the output need
        not necessarily lie in the range ``(xa, xb)``.

        >>> def f(x):
        ...     return (x-1)**2

        >>> from scipy import optimize

        >>> minimizer = optimize.golden(f, brack=(1, 2))
        >>> minimizer
        1
        >>> res = optimize.golden(f, brack=(-1, 0.5, 2), full_output=True)
        >>> xmin, fval, funcalls = res
        >>> f(xmin), fval
        (9.925165290385052e-18, 9.925165290385052e-18)

    isotonic_regression(y: 'npt.ArrayLike', *, weights: 'npt.ArrayLike | None' = None, increasing: 'bool' = True) -> 'OptimizeResult'
        Nonparametric isotonic regression.

        A (not strictly) monotonically increasing array `x` with the same length
        as `y` is calculated by the pool adjacent violators algorithm (PAVA), see
        [1]_. See the Notes section for more details.

        Parameters
        ----------
        y : (N,) array_like
            Response variable.
        weights : (N,) array_like or None
            Case weights.
        increasing : bool
            If True, fit monotonic increasing, i.e. isotonic, regression.
            If False, fit a monotonic decreasing, i.e. antitonic, regression.
            Default is True.

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a ``OptimizeResult`` object.
            Important attributes are:

            - ``x``: The isotonic regression solution, i.e. an increasing (or
              decreasing) array of the same length than y, with elements in the
              range from min(y) to max(y).
            - ``weights`` : Array with the sum of case weights for each block
              (or pool) B.
            - ``blocks``: Array of length B+1 with the indices of the start
              positions of each block (or pool) B. The j-th block is given by
              ``x[blocks[j]:blocks[j+1]]`` for which all values are the same.

        Notes
        -----
        Given data :math:`y` and case weights :math:`w`, the isotonic regression
        solves the following optimization problem:

        .. math::

            \operatorname{argmin}_{x_i} \sum_i w_i (y_i - x_i)^2 \quad
            \text{subject to } x_i \leq x_j \text{ whenever } i \leq j \,.

        For every input value :math:`y_i`, it generates a value :math:`x_i` such
        that :math:`x` is increasing (but not strictly), i.e.
        :math:`x_i \leq x_{i+1}`. This is accomplished by the PAVA.
        The solution consists of pools or blocks, i.e. neighboring elements of
        :math:`x`, e.g. :math:`x_i` and :math:`x_{i+1}`, that all have the same
        value.

        Most interestingly, the solution stays the same if the squared loss is
        replaced by the wide class of Bregman functions which are the unique
        class of strictly consistent scoring functions for the mean, see [2]_
        and references therein.

        The implemented version of PAVA according to [1]_ has a computational
        complexity of O(N) with input size N.

        References
        ----------
        .. [1] Busing, F. M. T. A. (2022).
               Monotone Regression: A Simple and Fast O(n) PAVA Implementation.
               Journal of Statistical Software, Code Snippets, 102(1), 1-25.
               :doi:`10.18637/jss.v102.c01`
        .. [2] Jordan, A.I., Mühlemann, A. & Ziegel, J.F.
               Characterizing the optimal solutions to the isotonic regression
               problem for identifiable functionals.
               Ann Inst Stat Math 74, 489-514 (2022).
               :doi:`10.1007/s10463-021-00808-0`

        Examples
        --------
        This example demonstrates that ``isotonic_regression`` really solves a
        constrained optimization problem.

        >>> import numpy as np
        >>> from scipy.optimize import isotonic_regression, minimize
        >>> y = [1.5, 1.0, 4.0, 6.0, 5.7, 5.0, 7.8, 9.0, 7.5, 9.5, 9.0]
        >>> def objective(yhat, y):
        ...     return np.sum((yhat - y)**2)
        >>> def constraint(yhat, y):
        ...     # This is for a monotonically increasing regression.
        ...     return np.diff(yhat)
        >>> result = minimize(objective, x0=y, args=(y,),
        ...                   constraints=[{'type': 'ineq',
        ...                                 'fun': lambda x: constraint(x, y)}])
        >>> result.x
        array([1.25      , 1.25      , 4.        , 5.56666667, 5.56666667,
               5.56666667, 7.8       , 8.25      , 8.25      , 9.25      ,
               9.25      ])
        >>> result = isotonic_regression(y)
        >>> result.x
        array([1.25      , 1.25      , 4.        , 5.56666667, 5.56666667,
               5.56666667, 7.8       , 8.25      , 8.25      , 9.25      ,
               9.25      ])

        The big advantage of ``isotonic_regression`` compared to calling
        ``minimize`` is that it is more user friendly, i.e. one does not need to
        define objective and constraint functions, and that it is orders of
        magnitudes faster. On commodity hardware (in 2023), for normal distributed
        input y of length 1000, the minimizer takes about 4 seconds, while
        ``isotonic_regression`` takes about 200 microseconds.

    least_squares(fun, x0, jac='2-point', bounds=(-inf, inf), method='trf', ftol=1e-08, xtol=1e-08, gtol=1e-08, x_scale=1.0, loss='linear', f_scale=1.0, diff_step=None, tr_solver=None, tr_options={}, jac_sparsity=None, max_nfev=None, verbose=0, args=(), kwargs={})
        Solve a nonlinear least-squares problem with bounds on the variables.

        Given the residuals f(x) (an m-D real function of n real
        variables) and the loss function rho(s) (a scalar function), `least_squares`
        finds a local minimum of the cost function F(x)::

            minimize F(x) = 0.5 * sum(rho(f_i(x)**2), i = 0, ..., m - 1)
            subject to lb <= x <= ub

        The purpose of the loss function rho(s) is to reduce the influence of
        outliers on the solution.

        Parameters
        ----------
        fun : callable
            Function which computes the vector of residuals, with the signature
            ``fun(x, *args, **kwargs)``, i.e., the minimization proceeds with
            respect to its first argument. The argument ``x`` passed to this
            function is an ndarray of shape (n,) (never a scalar, even for n=1).
            It must allocate and return a 1-D array_like of shape (m,) or a scalar.
            If the argument ``x`` is complex or the function ``fun`` returns
            complex residuals, it must be wrapped in a real function of real
            arguments, as shown at the end of the Examples section.
        x0 : array_like with shape (n,) or float
            Initial guess on independent variables. If float, it will be treated
            as a 1-D array with one element. When `method` is 'trf', the initial
            guess might be slightly adjusted to lie sufficiently within the given
            `bounds`.
        jac : {'2-point', '3-point', 'cs', callable}, optional
            Method of computing the Jacobian matrix (an m-by-n matrix, where
            element (i, j) is the partial derivative of f[i] with respect to
            x[j]). The keywords select a finite difference scheme for numerical
            estimation. The scheme '3-point' is more accurate, but requires
            twice as many operations as '2-point' (default). The scheme 'cs'
            uses complex steps, and while potentially the most accurate, it is
            applicable only when `fun` correctly handles complex inputs and
            can be analytically continued to the complex plane. Method 'lm'
            always uses the '2-point' scheme. If callable, it is used as
            ``jac(x, *args, **kwargs)`` and should return a good approximation
            (or the exact value) for the Jacobian as an array_like (np.atleast_2d
            is applied), a sparse matrix (csr_matrix preferred for performance) or
            a `scipy.sparse.linalg.LinearOperator`.
        bounds : 2-tuple of array_like or `Bounds`, optional
            There are two ways to specify bounds:

                1. Instance of `Bounds` class
                2. Lower and upper bounds on independent variables. Defaults to no
                   bounds. Each array must match the size of `x0` or be a scalar,
                   in the latter case a bound will be the same for all variables.
                   Use ``np.inf`` with an appropriate sign to disable bounds on all
                   or some variables.
        method : {'trf', 'dogbox', 'lm'}, optional
            Algorithm to perform minimization.

                * 'trf' : Trust Region Reflective algorithm, particularly suitable
                  for large sparse problems with bounds. Generally robust method.
                * 'dogbox' : dogleg algorithm with rectangular trust regions,
                  typical use case is small problems with bounds. Not recommended
                  for problems with rank-deficient Jacobian.
                * 'lm' : Levenberg-Marquardt algorithm as implemented in MINPACK.
                  Doesn't handle bounds and sparse Jacobians. Usually the most
                  efficient method for small unconstrained problems.

            Default is 'trf'. See Notes for more information.
        ftol : float or None, optional
            Tolerance for termination by the change of the cost function. Default
            is 1e-8. The optimization process is stopped when ``dF < ftol * F``,
            and there was an adequate agreement between a local quadratic model and
            the true model in the last step.

            If None and 'method' is not 'lm', the termination by this condition is
            disabled. If 'method' is 'lm', this tolerance must be higher than
            machine epsilon.
        xtol : float or None, optional
            Tolerance for termination by the change of the independent variables.
            Default is 1e-8. The exact condition depends on the `method` used:

                * For 'trf' and 'dogbox' : ``norm(dx) < xtol * (xtol + norm(x))``.
                * For 'lm' : ``Delta < xtol * norm(xs)``, where ``Delta`` is
                  a trust-region radius and ``xs`` is the value of ``x``
                  scaled according to `x_scale` parameter (see below).

            If None and 'method' is not 'lm', the termination by this condition is
            disabled. If 'method' is 'lm', this tolerance must be higher than
            machine epsilon.
        gtol : float or None, optional
            Tolerance for termination by the norm of the gradient. Default is 1e-8.
            The exact condition depends on a `method` used:

                * For 'trf' : ``norm(g_scaled, ord=np.inf) < gtol``, where
                  ``g_scaled`` is the value of the gradient scaled to account for
                  the presence of the bounds [STIR]_.
                * For 'dogbox' : ``norm(g_free, ord=np.inf) < gtol``, where
                  ``g_free`` is the gradient with respect to the variables which
                  are not in the optimal state on the boundary.
                * For 'lm' : the maximum absolute value of the cosine of angles
                  between columns of the Jacobian and the residual vector is less
                  than `gtol`, or the residual vector is zero.

            If None and 'method' is not 'lm', the termination by this condition is
            disabled. If 'method' is 'lm', this tolerance must be higher than
            machine epsilon.
        x_scale : array_like or 'jac', optional
            Characteristic scale of each variable. Setting `x_scale` is equivalent
            to reformulating the problem in scaled variables ``xs = x / x_scale``.
            An alternative view is that the size of a trust region along jth
            dimension is proportional to ``x_scale[j]``. Improved convergence may
            be achieved by setting `x_scale` such that a step of a given size
            along any of the scaled variables has a similar effect on the cost
            function. If set to 'jac', the scale is iteratively updated using the
            inverse norms of the columns of the Jacobian matrix (as described in
            [JJMore]_).
        loss : str or callable, optional
            Determines the loss function. The following keyword values are allowed:

                * 'linear' (default) : ``rho(z) = z``. Gives a standard
                  least-squares problem.
                * 'soft_l1' : ``rho(z) = 2 * ((1 + z)**0.5 - 1)``. The smooth
                  approximation of l1 (absolute value) loss. Usually a good
                  choice for robust least squares.
                * 'huber' : ``rho(z) = z if z <= 1 else 2*z**0.5 - 1``. Works
                  similarly to 'soft_l1'.
                * 'cauchy' : ``rho(z) = ln(1 + z)``. Severely weakens outliers
                  influence, but may cause difficulties in optimization process.
                * 'arctan' : ``rho(z) = arctan(z)``. Limits a maximum loss on
                  a single residual, has properties similar to 'cauchy'.

            If callable, it must take a 1-D ndarray ``z=f**2`` and return an
            array_like with shape (3, m) where row 0 contains function values,
            row 1 contains first derivatives and row 2 contains second
            derivatives. Method 'lm' supports only 'linear' loss.
        f_scale : float, optional
            Value of soft margin between inlier and outlier residuals, default
            is 1.0. The loss function is evaluated as follows
            ``rho_(f**2) = C**2 * rho(f**2 / C**2)``, where ``C`` is `f_scale`,
            and ``rho`` is determined by `loss` parameter. This parameter has
            no effect with ``loss='linear'``, but for other `loss` values it is
            of crucial importance.
        max_nfev : None or int, optional
            Maximum number of function evaluations before the termination.
            If None (default), the value is chosen automatically:

                * For 'trf' and 'dogbox' : 100 * n.
                * For 'lm' :  100 * n if `jac` is callable and 100 * n * (n + 1)
                  otherwise (because 'lm' counts function calls in Jacobian
                  estimation).

        diff_step : None or array_like, optional
            Determines the relative step size for the finite difference
            approximation of the Jacobian. The actual step is computed as
            ``x * diff_step``. If None (default), then `diff_step` is taken to be
            a conventional "optimal" power of machine epsilon for the finite
            difference scheme used [NR]_.
        tr_solver : {None, 'exact', 'lsmr'}, optional
            Method for solving trust-region subproblems, relevant only for 'trf'
            and 'dogbox' methods.

                * 'exact' is suitable for not very large problems with dense
                  Jacobian matrices. The computational complexity per iteration is
                  comparable to a singular value decomposition of the Jacobian
                  matrix.
                * 'lsmr' is suitable for problems with sparse and large Jacobian
                  matrices. It uses the iterative procedure
                  `scipy.sparse.linalg.lsmr` for finding a solution of a linear
                  least-squares problem and only requires matrix-vector product
                  evaluations.

            If None (default), the solver is chosen based on the type of Jacobian
            returned on the first iteration.
        tr_options : dict, optional
            Keyword options passed to trust-region solver.

                * ``tr_solver='exact'``: `tr_options` are ignored.
                * ``tr_solver='lsmr'``: options for `scipy.sparse.linalg.lsmr`.
                  Additionally,  ``method='trf'`` supports  'regularize' option
                  (bool, default is True), which adds a regularization term to the
                  normal equation, which improves convergence if the Jacobian is
                  rank-deficient [Byrd]_ (eq. 3.4).

        jac_sparsity : {None, array_like, sparse matrix}, optional
            Defines the sparsity structure of the Jacobian matrix for finite
            difference estimation, its shape must be (m, n). If the Jacobian has
            only few non-zero elements in *each* row, providing the sparsity
            structure will greatly speed up the computations [Curtis]_. A zero
            entry means that a corresponding element in the Jacobian is identically
            zero. If provided, forces the use of 'lsmr' trust-region solver.
            If None (default), then dense differencing will be used. Has no effect
            for 'lm' method.
        verbose : {0, 1, 2}, optional
            Level of algorithm's verbosity:

                * 0 (default) : work silently.
                * 1 : display a termination report.
                * 2 : display progress during iterations (not supported by 'lm'
                  method).

        args, kwargs : tuple and dict, optional
            Additional arguments passed to `fun` and `jac`. Both empty by default.
            The calling signature is ``fun(x, *args, **kwargs)`` and the same for
            `jac`.

        Returns
        -------
        result : OptimizeResult
            `OptimizeResult` with the following fields defined:

                x : ndarray, shape (n,)
                    Solution found.
                cost : float
                    Value of the cost function at the solution.
                fun : ndarray, shape (m,)
                    Vector of residuals at the solution.
                jac : ndarray, sparse matrix or LinearOperator, shape (m, n)
                    Modified Jacobian matrix at the solution, in the sense that J^T J
                    is a Gauss-Newton approximation of the Hessian of the cost function.
                    The type is the same as the one used by the algorithm.
                grad : ndarray, shape (m,)
                    Gradient of the cost function at the solution.
                optimality : float
                    First-order optimality measure. In unconstrained problems, it is
                    always the uniform norm of the gradient. In constrained problems,
                    it is the quantity which was compared with `gtol` during iterations.
                active_mask : ndarray of int, shape (n,)
                    Each component shows whether a corresponding constraint is active
                    (that is, whether a variable is at the bound):

                        *  0 : a constraint is not active.
                        * -1 : a lower bound is active.
                        *  1 : an upper bound is active.

                    Might be somewhat arbitrary for 'trf' method as it generates a
                    sequence of strictly feasible iterates and `active_mask` is
                    determined within a tolerance threshold.
                nfev : int
                    Number of function evaluations done. Methods 'trf' and 'dogbox' do
                    not count function calls for numerical Jacobian approximation, as
                    opposed to 'lm' method.
                njev : int or None
                    Number of Jacobian evaluations done. If numerical Jacobian
                    approximation is used in 'lm' method, it is set to None.
                status : int
                    The reason for algorithm termination:

                        * -1 : improper input parameters status returned from MINPACK.
                        *  0 : the maximum number of function evaluations is exceeded.
                        *  1 : `gtol` termination condition is satisfied.
                        *  2 : `ftol` termination condition is satisfied.
                        *  3 : `xtol` termination condition is satisfied.
                        *  4 : Both `ftol` and `xtol` termination conditions are satisfied.

                message : str
                    Verbal description of the termination reason.
                success : bool
                    True if one of the convergence criteria is satisfied (`status` > 0).

        See Also
        --------
        leastsq : A legacy wrapper for the MINPACK implementation of the
                  Levenberg-Marquadt algorithm.
        curve_fit : Least-squares minimization applied to a curve-fitting problem.

        Notes
        -----
        Method 'lm' (Levenberg-Marquardt) calls a wrapper over least-squares
        algorithms implemented in MINPACK (lmder, lmdif). It runs the
        Levenberg-Marquardt algorithm formulated as a trust-region type algorithm.
        The implementation is based on paper [JJMore]_, it is very robust and
        efficient with a lot of smart tricks. It should be your first choice
        for unconstrained problems. Note that it doesn't support bounds. Also,
        it doesn't work when m < n.

        Method 'trf' (Trust Region Reflective) is motivated by the process of
        solving a system of equations, which constitute the first-order optimality
        condition for a bound-constrained minimization problem as formulated in
        [STIR]_. The algorithm iteratively solves trust-region subproblems
        augmented by a special diagonal quadratic term and with trust-region shape
        determined by the distance from the bounds and the direction of the
        gradient. This enhancements help to avoid making steps directly into bounds
        and efficiently explore the whole space of variables. To further improve
        convergence, the algorithm considers search directions reflected from the
        bounds. To obey theoretical requirements, the algorithm keeps iterates
        strictly feasible. With dense Jacobians trust-region subproblems are
        solved by an exact method very similar to the one described in [JJMore]_
        (and implemented in MINPACK). The difference from the MINPACK
        implementation is that a singular value decomposition of a Jacobian
        matrix is done once per iteration, instead of a QR decomposition and series
        of Givens rotation eliminations. For large sparse Jacobians a 2-D subspace
        approach of solving trust-region subproblems is used [STIR]_, [Byrd]_.
        The subspace is spanned by a scaled gradient and an approximate
        Gauss-Newton solution delivered by `scipy.sparse.linalg.lsmr`. When no
        constraints are imposed the algorithm is very similar to MINPACK and has
        generally comparable performance. The algorithm works quite robust in
        unbounded and bounded problems, thus it is chosen as a default algorithm.

        Method 'dogbox' operates in a trust-region framework, but considers
        rectangular trust regions as opposed to conventional ellipsoids [Voglis]_.
        The intersection of a current trust region and initial bounds is again
        rectangular, so on each iteration a quadratic minimization problem subject
        to bound constraints is solved approximately by Powell's dogleg method
        [NumOpt]_. The required Gauss-Newton step can be computed exactly for
        dense Jacobians or approximately by `scipy.sparse.linalg.lsmr` for large
        sparse Jacobians. The algorithm is likely to exhibit slow convergence when
        the rank of Jacobian is less than the number of variables. The algorithm
        often outperforms 'trf' in bounded problems with a small number of
        variables.

        Robust loss functions are implemented as described in [BA]_. The idea
        is to modify a residual vector and a Jacobian matrix on each iteration
        such that computed gradient and Gauss-Newton Hessian approximation match
        the true gradient and Hessian approximation of the cost function. Then
        the algorithm proceeds in a normal way, i.e., robust loss functions are
        implemented as a simple wrapper over standard least-squares algorithms.

        .. versionadded:: 0.17.0

        References
        ----------
        .. [STIR] M. A. Branch, T. F. Coleman, and Y. Li, "A Subspace, Interior,
                  and Conjugate Gradient Method for Large-Scale Bound-Constrained
                  Minimization Problems," SIAM Journal on Scientific Computing,
                  Vol. 21, Number 1, pp 1-23, 1999.
        .. [NR] William H. Press et. al., "Numerical Recipes. The Art of Scientific
                Computing. 3rd edition", Sec. 5.7.
        .. [Byrd] R. H. Byrd, R. B. Schnabel and G. A. Shultz, "Approximate
                  solution of the trust region problem by minimization over
                  two-dimensional subspaces", Math. Programming, 40, pp. 247-263,
                  1988.
        .. [Curtis] A. Curtis, M. J. D. Powell, and J. Reid, "On the estimation of
                    sparse Jacobian matrices", Journal of the Institute of
                    Mathematics and its Applications, 13, pp. 117-120, 1974.
        .. [JJMore] J. J. More, "The Levenberg-Marquardt Algorithm: Implementation
                    and Theory," Numerical Analysis, ed. G. A. Watson, Lecture
                    Notes in Mathematics 630, Springer Verlag, pp. 105-116, 1977.
        .. [Voglis] C. Voglis and I. E. Lagaris, "A Rectangular Trust Region
                    Dogleg Approach for Unconstrained and Bound Constrained
                    Nonlinear Optimization", WSEAS International Conference on
                    Applied Mathematics, Corfu, Greece, 2004.
        .. [NumOpt] J. Nocedal and S. J. Wright, "Numerical optimization,
                    2nd edition", Chapter 4.
        .. [BA] B. Triggs et. al., "Bundle Adjustment - A Modern Synthesis",
                Proceedings of the International Workshop on Vision Algorithms:
                Theory and Practice, pp. 298-372, 1999.

        Examples
        --------
        In this example we find a minimum of the Rosenbrock function without bounds
        on independent variables.

        >>> import numpy as np
        >>> def fun_rosenbrock(x):
        ...     return np.array([10 * (x[1] - x[0]**2), (1 - x[0])])

        Notice that we only provide the vector of the residuals. The algorithm
        constructs the cost function as a sum of squares of the residuals, which
        gives the Rosenbrock function. The exact minimum is at ``x = [1.0, 1.0]``.

        >>> from scipy.optimize import least_squares
        >>> x0_rosenbrock = np.array([2, 2])
        >>> res_1 = least_squares(fun_rosenbrock, x0_rosenbrock)
        >>> res_1.x
        array([ 1.,  1.])
        >>> res_1.cost
        9.8669242910846867e-30
        >>> res_1.optimality
        8.8928864934219529e-14

        We now constrain the variables, in such a way that the previous solution
        becomes infeasible. Specifically, we require that ``x[1] >= 1.5``, and
        ``x[0]`` left unconstrained. To this end, we specify the `bounds` parameter
        to `least_squares` in the form ``bounds=([-np.inf, 1.5], np.inf)``.

        We also provide the analytic Jacobian:

        >>> def jac_rosenbrock(x):
        ...     return np.array([
        ...         [-20 * x[0], 10],
        ...         [-1, 0]])

        Putting this all together, we see that the new solution lies on the bound:

        >>> res_2 = least_squares(fun_rosenbrock, x0_rosenbrock, jac_rosenbrock,
        ...                       bounds=([-np.inf, 1.5], np.inf))
        >>> res_2.x
        array([ 1.22437075,  1.5       ])
        >>> res_2.cost
        0.025213093946805685
        >>> res_2.optimality
        1.5885401433157753e-07

        Now we solve a system of equations (i.e., the cost function should be zero
        at a minimum) for a Broyden tridiagonal vector-valued function of 100000
        variables:

        >>> def fun_broyden(x):
        ...     f = (3 - x) * x + 1
        ...     f[1:] -= x[:-1]
        ...     f[:-1] -= 2 * x[1:]
        ...     return f

        The corresponding Jacobian matrix is sparse. We tell the algorithm to
        estimate it by finite differences and provide the sparsity structure of
        Jacobian to significantly speed up this process.

        >>> from scipy.sparse import lil_matrix
        >>> def sparsity_broyden(n):
        ...     sparsity = lil_matrix((n, n), dtype=int)
        ...     i = np.arange(n)
        ...     sparsity[i, i] = 1
        ...     i = np.arange(1, n)
        ...     sparsity[i, i - 1] = 1
        ...     i = np.arange(n - 1)
        ...     sparsity[i, i + 1] = 1
        ...     return sparsity
        ...
        >>> n = 100000
        >>> x0_broyden = -np.ones(n)
        ...
        >>> res_3 = least_squares(fun_broyden, x0_broyden,
        ...                       jac_sparsity=sparsity_broyden(n))
        >>> res_3.cost
        4.5687069299604613e-23
        >>> res_3.optimality
        1.1650454296851518e-11

        Let's also solve a curve fitting problem using robust loss function to
        take care of outliers in the data. Define the model function as
        ``y = a + b * exp(c * t)``, where t is a predictor variable, y is an
        observation and a, b, c are parameters to estimate.

        First, define the function which generates the data with noise and
        outliers, define the model parameters, and generate data:

        >>> from numpy.random import default_rng
        >>> rng = default_rng()
        >>> def gen_data(t, a, b, c, noise=0., n_outliers=0, seed=None):
        ...     rng = default_rng(seed)
        ...
        ...     y = a + b * np.exp(t * c)
        ...
        ...     error = noise * rng.standard_normal(t.size)
        ...     outliers = rng.integers(0, t.size, n_outliers)
        ...     error[outliers] *= 10
        ...
        ...     return y + error
        ...
        >>> a = 0.5
        >>> b = 2.0
        >>> c = -1
        >>> t_min = 0
        >>> t_max = 10
        >>> n_points = 15
        ...
        >>> t_train = np.linspace(t_min, t_max, n_points)
        >>> y_train = gen_data(t_train, a, b, c, noise=0.1, n_outliers=3)

        Define function for computing residuals and initial estimate of
        parameters.

        >>> def fun(x, t, y):
        ...     return x[0] + x[1] * np.exp(x[2] * t) - y
        ...
        >>> x0 = np.array([1.0, 1.0, 0.0])

        Compute a standard least-squares solution:

        >>> res_lsq = least_squares(fun, x0, args=(t_train, y_train))

        Now compute two solutions with two different robust loss functions. The
        parameter `f_scale` is set to 0.1, meaning that inlier residuals should
        not significantly exceed 0.1 (the noise level used).

        >>> res_soft_l1 = least_squares(fun, x0, loss='soft_l1', f_scale=0.1,
        ...                             args=(t_train, y_train))
        >>> res_log = least_squares(fun, x0, loss='cauchy', f_scale=0.1,
        ...                         args=(t_train, y_train))

        And, finally, plot all the curves. We see that by selecting an appropriate
        `loss`  we can get estimates close to optimal even in the presence of
        strong outliers. But keep in mind that generally it is recommended to try
        'soft_l1' or 'huber' losses first (if at all necessary) as the other two
        options may cause difficulties in optimization process.

        >>> t_test = np.linspace(t_min, t_max, n_points * 10)
        >>> y_true = gen_data(t_test, a, b, c)
        >>> y_lsq = gen_data(t_test, *res_lsq.x)
        >>> y_soft_l1 = gen_data(t_test, *res_soft_l1.x)
        >>> y_log = gen_data(t_test, *res_log.x)
        ...
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(t_train, y_train, 'o')
        >>> plt.plot(t_test, y_true, 'k', linewidth=2, label='true')
        >>> plt.plot(t_test, y_lsq, label='linear loss')
        >>> plt.plot(t_test, y_soft_l1, label='soft_l1 loss')
        >>> plt.plot(t_test, y_log, label='cauchy loss')
        >>> plt.xlabel("t")
        >>> plt.ylabel("y")
        >>> plt.legend()
        >>> plt.show()

        In the next example, we show how complex-valued residual functions of
        complex variables can be optimized with ``least_squares()``. Consider the
        following function:

        >>> def f(z):
        ...     return z - (0.5 + 0.5j)

        We wrap it into a function of real variables that returns real residuals
        by simply handling the real and imaginary parts as independent variables:

        >>> def f_wrap(x):
        ...     fx = f(x[0] + 1j*x[1])
        ...     return np.array([fx.real, fx.imag])

        Thus, instead of the original m-D complex function of n complex
        variables we optimize a 2m-D real function of 2n real variables:

        >>> from scipy.optimize import least_squares
        >>> res_wrapped = least_squares(f_wrap, (0.1, 0.1), bounds=([0, 0], [1, 1]))
        >>> z = res_wrapped.x[0] + res_wrapped.x[1]*1j
        >>> z
        (0.49999999999925893+0.49999999999925893j)

    leastsq(func, x0, args=(), Dfun=None, full_output=False, col_deriv=False, ftol=1.49012e-08, xtol=1.49012e-08, gtol=0.0, maxfev=0, epsfcn=None, factor=100, diag=None)
        Minimize the sum of squares of a set of equations.

        ::

            x = arg min(sum(func(y)**2,axis=0))
                     y

        Parameters
        ----------
        func : callable
            Should take at least one (possibly length ``N`` vector) argument and
            returns ``M`` floating point numbers. It must not return NaNs or
            fitting might fail. ``M`` must be greater than or equal to ``N``.
        x0 : ndarray
            The starting estimate for the minimization.
        args : tuple, optional
            Any extra arguments to func are placed in this tuple.
        Dfun : callable, optional
            A function or method to compute the Jacobian of func with derivatives
            across the rows. If this is None, the Jacobian will be estimated.
        full_output : bool, optional
            If ``True``, return all optional outputs (not just `x` and `ier`).
        col_deriv : bool, optional
            If ``True``, specify that the Jacobian function computes derivatives
            down the columns (faster, because there is no transpose operation).
        ftol : float, optional
            Relative error desired in the sum of squares.
        xtol : float, optional
            Relative error desired in the approximate solution.
        gtol : float, optional
            Orthogonality desired between the function vector and the columns of
            the Jacobian.
        maxfev : int, optional
            The maximum number of calls to the function. If `Dfun` is provided,
            then the default `maxfev` is 100*(N+1) where N is the number of elements
            in x0, otherwise the default `maxfev` is 200*(N+1).
        epsfcn : float, optional
            A variable used in determining a suitable step length for the forward-
            difference approximation of the Jacobian (for Dfun=None).
            Normally the actual step length will be sqrt(epsfcn)*x
            If epsfcn is less than the machine precision, it is assumed that the
            relative errors are of the order of the machine precision.
        factor : float, optional
            A parameter determining the initial step bound
            (``factor * || diag * x||``). Should be in interval ``(0.1, 100)``.
        diag : sequence, optional
            N positive entries that serve as a scale factors for the variables.

        Returns
        -------
        x : ndarray
            The solution (or the result of the last iteration for an unsuccessful
            call).
        cov_x : ndarray
            The inverse of the Hessian. `fjac` and `ipvt` are used to construct an
            estimate of the Hessian. A value of None indicates a singular matrix,
            which means the curvature in parameters `x` is numerically flat. To
            obtain the covariance matrix of the parameters `x`, `cov_x` must be
            multiplied by the variance of the residuals -- see curve_fit. Only
            returned if `full_output` is ``True``.
        infodict : dict
            a dictionary of optional outputs with the keys:

            ``nfev``
                The number of function calls
            ``fvec``
                The function evaluated at the output
            ``fjac``
                A permutation of the R matrix of a QR
                factorization of the final approximate
                Jacobian matrix, stored column wise.
                Together with ipvt, the covariance of the
                estimate can be approximated.
            ``ipvt``
                An integer array of length N which defines
                a permutation matrix, p, such that
                fjac*p = q*r, where r is upper triangular
                with diagonal elements of nonincreasing
                magnitude. Column j of p is column ipvt(j)
                of the identity matrix.
            ``qtf``
                The vector (transpose(q) * fvec).

            Only returned if `full_output` is ``True``.
        mesg : str
            A string message giving information about the cause of failure.
            Only returned if `full_output` is ``True``.
        ier : int
            An integer flag. If it is equal to 1, 2, 3 or 4, the solution was
            found. Otherwise, the solution was not found. In either case, the
            optional output variable 'mesg' gives more information.

        See Also
        --------
        least_squares : Newer interface to solve nonlinear least-squares problems
            with bounds on the variables. See ``method='lm'`` in particular.

        Notes
        -----
        "leastsq" is a wrapper around MINPACK's lmdif and lmder algorithms.

        cov_x is a Jacobian approximation to the Hessian of the least squares
        objective function.
        This approximation assumes that the objective function is based on the
        difference between some observed target data (ydata) and a (non-linear)
        function of the parameters `f(xdata, params)` ::

               func(params) = ydata - f(xdata, params)

        so that the objective function is ::

               min   sum((ydata - f(xdata, params))**2, axis=0)
             params

        The solution, `x`, is always a 1-D array, regardless of the shape of `x0`,
        or whether `x0` is a scalar.

        Examples
        --------
        >>> from scipy.optimize import leastsq
        >>> def func(x):
        ...     return 2*(x-3)**2+1
        >>> leastsq(func, 0)
        (array([2.99999999]), 1)

    line_search = line_search_wolfe2(f, myfprime, xk, pk, gfk=None, old_fval=None, old_old_fval=None, args=(), c1=0.0001, c2=0.9, amax=None, extra_condition=None, maxiter=10)
        Find alpha that satisfies strong Wolfe conditions.

        Parameters
        ----------
        f : callable f(x,*args)
            Objective function.
        myfprime : callable f'(x,*args)
            Objective function gradient.
        xk : ndarray
            Starting point.
        pk : ndarray
            Search direction. The search direction must be a descent direction
            for the algorithm to converge.
        gfk : ndarray, optional
            Gradient value for x=xk (xk being the current parameter
            estimate). Will be recomputed if omitted.
        old_fval : float, optional
            Function value for x=xk. Will be recomputed if omitted.
        old_old_fval : float, optional
            Function value for the point preceding x=xk.
        args : tuple, optional
            Additional arguments passed to objective function.
        c1 : float, optional
            Parameter for Armijo condition rule.
        c2 : float, optional
            Parameter for curvature condition rule.
        amax : float, optional
            Maximum step size
        extra_condition : callable, optional
            A callable of the form ``extra_condition(alpha, x, f, g)``
            returning a boolean. Arguments are the proposed step ``alpha``
            and the corresponding ``x``, ``f`` and ``g`` values. The line search
            accepts the value of ``alpha`` only if this
            callable returns ``True``. If the callable returns ``False``
            for the step length, the algorithm will continue with
            new iterates. The callable is only called for iterates
            satisfying the strong Wolfe conditions.
        maxiter : int, optional
            Maximum number of iterations to perform.

        Returns
        -------
        alpha : float or None
            Alpha for which ``x_new = x0 + alpha * pk``,
            or None if the line search algorithm did not converge.
        fc : int
            Number of function evaluations made.
        gc : int
            Number of gradient evaluations made.
        new_fval : float or None
            New function value ``f(x_new)=f(x0+alpha*pk)``,
            or None if the line search algorithm did not converge.
        old_fval : float
            Old function value ``f(x0)``.
        new_slope : float or None
            The local slope along the search direction at the
            new value ``<myfprime(x_new), pk>``,
            or None if the line search algorithm did not converge.


        Notes
        -----
        Uses the line search algorithm to enforce strong Wolfe
        conditions. See Wright and Nocedal, 'Numerical Optimization',
        1999, pp. 59-61.

        The search direction `pk` must be a descent direction (e.g.
        ``-myfprime(xk)``) to find a step length that satisfies the strong Wolfe
        conditions. If the search direction is not a descent direction (e.g.
        ``myfprime(xk)``), then `alpha`, `new_fval`, and `new_slope` will be None.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import line_search

        A objective function and its gradient are defined.

        >>> def obj_func(x):
        ...     return (x[0])**2+(x[1])**2
        >>> def obj_grad(x):
        ...     return [2*x[0], 2*x[1]]

        We can find alpha that satisfies strong Wolfe conditions.

        >>> start_point = np.array([1.8, 1.7])
        >>> search_gradient = np.array([-1.0, -1.0])
        >>> line_search(obj_func, obj_grad, start_point, search_gradient)
        (1.0, 2, 1, 1.1300000000000001, 6.13, [1.6, 1.4])

    linear_sum_assignment(...)
        Solve the linear sum assignment problem.

        Parameters
        ----------
        cost_matrix : array
            The cost matrix of the bipartite graph.

        maximize : bool (default: False)
            Calculates a maximum weight matching if true.

        Returns
        -------
        row_ind, col_ind : array
            An array of row indices and one of corresponding column indices giving
            the optimal assignment. The cost of the assignment can be computed
            as ``cost_matrix[row_ind, col_ind].sum()``. The row indices will be
            sorted; in the case of a square cost matrix they will be equal to
            ``numpy.arange(cost_matrix.shape[0])``.

        See Also
        --------
        scipy.sparse.csgraph.min_weight_full_bipartite_matching : for sparse inputs

        Notes
        -----

        The linear sum assignment problem [1]_ is also known as minimum weight
        matching in bipartite graphs. A problem instance is described by a matrix
        C, where each C[i,j] is the cost of matching vertex i of the first partite
        set (a 'worker') and vertex j of the second set (a 'job'). The goal is to
        find a complete assignment of workers to jobs of minimal cost.

        Formally, let X be a boolean matrix where :math:`X[i,j] = 1` iff row i is
        assigned to column j. Then the optimal assignment has cost

        .. math::
            \min \sum_i \sum_j C_{i,j} X_{i,j}

        where, in the case where the matrix X is square, each row is assigned to
        exactly one column, and each column to exactly one row.

        This function can also solve a generalization of the classic assignment
        problem where the cost matrix is rectangular. If it has more rows than
        columns, then not every row needs to be assigned to a column, and vice
        versa.

        This implementation is a modified Jonker-Volgenant algorithm with no
        initialization, described in ref. [2]_.

        .. versionadded:: 0.17.0

        References
        ----------

        .. [1] https://en.wikipedia.org/wiki/Assignment_problem

        .. [2] DF Crouse. On implementing 2D rectangular assignment algorithms.
               *IEEE Transactions on Aerospace and Electronic Systems*,
               52(4):1679-1696, August 2016, :doi:`10.1109/TAES.2016.140952`

        Examples
        --------
        >>> import numpy as np
        >>> cost = np.array([[4, 1, 3], [2, 0, 5], [3, 2, 2]])
        >>> from scipy.optimize import linear_sum_assignment
        >>> row_ind, col_ind = linear_sum_assignment(cost)
        >>> col_ind
        array([1, 0, 2])
        >>> cost[row_ind, col_ind].sum()
        5

    linearmixing(F, xin, iter=None, alpha=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using a scalar Jacobian approximation.

        .. warning::

           This algorithm may be useful for specific problems, but whether
           it will work may depend strongly on the problem.

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        alpha : float, optional
            The Jacobian approximation is (-1/alpha).
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='linearmixing'`` in particular.

    linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bounds=(0, None), method='highs', callback=None, options=None, x0=None, integrality=None)
        Linear programming: minimize a linear objective function subject to linear
        equality and inequality constraints.

        Linear programming solves problems of the following form:

        .. math::

            \min_x \ & c^T x \\
            \mbox{such that} \ & A_{ub} x \leq b_{ub},\\
            & A_{eq} x = b_{eq},\\
            & l \leq x \leq u ,

        where :math:`x` is a vector of decision variables; :math:`c`,
        :math:`b_{ub}`, :math:`b_{eq}`, :math:`l`, and :math:`u` are vectors; and
        :math:`A_{ub}` and :math:`A_{eq}` are matrices.

        Alternatively, that's:

            - minimize ::

                c @ x

            - such that ::

                A_ub @ x <= b_ub
                A_eq @ x == b_eq
                lb <= x <= ub

        Note that by default ``lb = 0`` and ``ub = None``. Other bounds can be
        specified with ``bounds``.

        Parameters
        ----------
        c : 1-D array
            The coefficients of the linear objective function to be minimized.
        A_ub : 2-D array, optional
            The inequality constraint matrix. Each row of ``A_ub`` specifies the
            coefficients of a linear inequality constraint on ``x``.
        b_ub : 1-D array, optional
            The inequality constraint vector. Each element represents an
            upper bound on the corresponding value of ``A_ub @ x``.
        A_eq : 2-D array, optional
            The equality constraint matrix. Each row of ``A_eq`` specifies the
            coefficients of a linear equality constraint on ``x``.
        b_eq : 1-D array, optional
            The equality constraint vector. Each element of ``A_eq @ x`` must equal
            the corresponding element of ``b_eq``.
        bounds : sequence, optional
            A sequence of ``(min, max)`` pairs for each element in ``x``, defining
            the minimum and maximum values of that decision variable.
            If a single tuple ``(min, max)`` is provided, then ``min`` and ``max``
            will serve as bounds for all decision variables.
            Use ``None`` to indicate that there is no bound. For instance, the
            default bound ``(0, None)`` means that all decision variables are
            non-negative, and the pair ``(None, None)`` means no bounds at all,
            i.e. all variables are allowed to be any real.
        method : str, optional
            The algorithm used to solve the standard form problem.
            :ref:`'highs' <optimize.linprog-highs>` (default),
            :ref:`'highs-ds' <optimize.linprog-highs-ds>`,
            :ref:`'highs-ipm' <optimize.linprog-highs-ipm>`,
            :ref:`'interior-point' <optimize.linprog-interior-point>` (legacy),
            :ref:`'revised simplex' <optimize.linprog-revised_simplex>` (legacy),
            and
            :ref:`'simplex' <optimize.linprog-simplex>` (legacy) are supported.
            The legacy methods are deprecated and will be removed in SciPy 1.11.0.
        callback : callable, optional
            If a callback function is provided, it will be called at least once per
            iteration of the algorithm. The callback function must accept a single
            `scipy.optimize.OptimizeResult` consisting of the following fields:

            x : 1-D array
                The current solution vector.
            fun : float
                The current value of the objective function ``c @ x``.
            success : bool
                ``True`` when the algorithm has completed successfully.
            slack : 1-D array
                The (nominally positive) values of the slack,
                ``b_ub - A_ub @ x``.
            con : 1-D array
                The (nominally zero) residuals of the equality constraints,
                ``b_eq - A_eq @ x``.
            phase : int
                The phase of the algorithm being executed.
            status : int
                An integer representing the status of the algorithm.

                ``0`` : Optimization proceeding nominally.

                ``1`` : Iteration limit reached.

                ``2`` : Problem appears to be infeasible.

                ``3`` : Problem appears to be unbounded.

                ``4`` : Numerical difficulties encountered.

                nit : int
                    The current iteration number.
                message : str
                    A string descriptor of the algorithm status.

            Callback functions are not currently supported by the HiGHS methods.

        options : dict, optional
            A dictionary of solver options. All methods accept the following
            options:

            maxiter : int
                Maximum number of iterations to perform.
                Default: see method-specific documentation.
            disp : bool
                Set to ``True`` to print convergence messages.
                Default: ``False``.
            presolve : bool
                Set to ``False`` to disable automatic presolve.
                Default: ``True``.

            All methods except the HiGHS solvers also accept:

            tol : float
                A tolerance which determines when a residual is "close enough" to
                zero to be considered exactly zero.
            autoscale : bool
                Set to ``True`` to automatically perform equilibration.
                Consider using this option if the numerical values in the
                constraints are separated by several orders of magnitude.
                Default: ``False``.
            rr : bool
                Set to ``False`` to disable automatic redundancy removal.
                Default: ``True``.
            rr_method : string
                Method used to identify and remove redundant rows from the
                equality constraint matrix after presolve. For problems with
                dense input, the available methods for redundancy removal are:

                "SVD":
                    Repeatedly performs singular value decomposition on
                    the matrix, detecting redundant rows based on nonzeros
                    in the left singular vectors that correspond with
                    zero singular values. May be fast when the matrix is
                    nearly full rank.
                "pivot":
                    Uses the algorithm presented in [5]_ to identify
                    redundant rows.
                "ID":
                    Uses a randomized interpolative decomposition.
                    Identifies columns of the matrix transpose not used in
                    a full-rank interpolative decomposition of the matrix.
                None:
                    Uses "svd" if the matrix is nearly full rank, that is,
                    the difference between the matrix rank and the number
                    of rows is less than five. If not, uses "pivot". The
                    behavior of this default is subject to change without
                    prior notice.

                Default: None.
                For problems with sparse input, this option is ignored, and the
                pivot-based algorithm presented in [5]_ is used.

            For method-specific options, see
            :func:`show_options('linprog') <show_options>`.

        x0 : 1-D array, optional
            Guess values of the decision variables, which will be refined by
            the optimization algorithm. This argument is currently used only by the
            'revised simplex' method, and can only be used if `x0` represents a
            basic feasible solution.

        integrality : 1-D array or int, optional
            Indicates the type of integrality constraint on each decision variable.

            ``0`` : Continuous variable; no integrality constraint.

            ``1`` : Integer variable; decision variable must be an integer
            within `bounds`.

            ``2`` : Semi-continuous variable; decision variable must be within
            `bounds` or take value ``0``.

            ``3`` : Semi-integer variable; decision variable must be an integer
            within `bounds` or take value ``0``.

            By default, all variables are continuous.

            For mixed integrality constraints, supply an array of shape `c.shape`.
            To infer a constraint on each decision variable from shorter inputs,
            the argument will be broadcasted to `c.shape` using `np.broadcast_to`.

            This argument is currently used only by the ``'highs'`` method and
            ignored otherwise.

        Returns
        -------
        res : OptimizeResult
            A :class:`scipy.optimize.OptimizeResult` consisting of the fields
            below. Note that the return types of the fields may depend on whether
            the optimization was successful, therefore it is recommended to check
            `OptimizeResult.status` before relying on the other fields:

            x : 1-D array
                The values of the decision variables that minimizes the
                objective function while satisfying the constraints.
            fun : float
                The optimal value of the objective function ``c @ x``.
            slack : 1-D array
                The (nominally positive) values of the slack variables,
                ``b_ub - A_ub @ x``.
            con : 1-D array
                The (nominally zero) residuals of the equality constraints,
                ``b_eq - A_eq @ x``.
            success : bool
                ``True`` when the algorithm succeeds in finding an optimal
                solution.
            status : int
                An integer representing the exit status of the algorithm.

                ``0`` : Optimization terminated successfully.

                ``1`` : Iteration limit reached.

                ``2`` : Problem appears to be infeasible.

                ``3`` : Problem appears to be unbounded.

                ``4`` : Numerical difficulties encountered.

            nit : int
                The total number of iterations performed in all phases.
            message : str
                A string descriptor of the exit status of the algorithm.

        See Also
        --------
        show_options : Additional options accepted by the solvers.

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter.

        `'highs-ds'` and
        `'highs-ipm'` are interfaces to the
        HiGHS simplex and interior-point method solvers [13]_, respectively.
        `'highs'` (default) chooses between
        the two automatically. These are the fastest linear
        programming solvers in SciPy, especially for large, sparse problems;
        which of these two is faster is problem-dependent.
        The other solvers (`'interior-point'`, `'revised simplex'`, and
        `'simplex'`) are legacy methods and will be removed in SciPy 1.11.0.

        Method *highs-ds* is a wrapper of the C++ high performance dual
        revised simplex implementation (HSOL) [13]_, [14]_. Method *highs-ipm*
        is a wrapper of a C++ implementation of an **i**\ nterior-\ **p**\ oint
        **m**\ ethod [13]_; it features a crossover routine, so it is as accurate
        as a simplex solver. Method *highs* chooses between the two automatically.
        For new code involving `linprog`, we recommend explicitly choosing one of
        these three method values.

        .. versionadded:: 1.6.0

        Method *interior-point* uses the primal-dual path following algorithm
        as outlined in [4]_. This algorithm supports sparse constraint matrices and
        is typically faster than the simplex methods, especially for large, sparse
        problems. Note, however, that the solution returned may be slightly less
        accurate than those of the simplex methods and will not, in general,
        correspond with a vertex of the polytope defined by the constraints.

        .. versionadded:: 1.0.0

        Method *revised simplex* uses the revised simplex method as described in
        [9]_, except that a factorization [11]_ of the basis matrix, rather than
        its inverse, is efficiently maintained and used to solve the linear systems
        at each iteration of the algorithm.

        .. versionadded:: 1.3.0

        Method *simplex* uses a traditional, full-tableau implementation of
        Dantzig's simplex algorithm [1]_, [2]_ (*not* the
        Nelder-Mead simplex). This algorithm is included for backwards
        compatibility and educational purposes.

        .. versionadded:: 0.15.0

        Before applying *interior-point*, *revised simplex*, or *simplex*,
        a presolve procedure based on [8]_ attempts
        to identify trivial infeasibilities, trivial unboundedness, and potential
        problem simplifications. Specifically, it checks for:

        - rows of zeros in ``A_eq`` or ``A_ub``, representing trivial constraints;
        - columns of zeros in ``A_eq`` `and` ``A_ub``, representing unconstrained
          variables;
        - column singletons in ``A_eq``, representing fixed variables; and
        - column singletons in ``A_ub``, representing simple bounds.

        If presolve reveals that the problem is unbounded (e.g. an unconstrained
        and unbounded variable has negative cost) or infeasible (e.g., a row of
        zeros in ``A_eq`` corresponds with a nonzero in ``b_eq``), the solver
        terminates with the appropriate status code. Note that presolve terminates
        as soon as any sign of unboundedness is detected; consequently, a problem
        may be reported as unbounded when in reality the problem is infeasible
        (but infeasibility has not been detected yet). Therefore, if it is
        important to know whether the problem is actually infeasible, solve the
        problem again with option ``presolve=False``.

        If neither infeasibility nor unboundedness are detected in a single pass
        of the presolve, bounds are tightened where possible and fixed
        variables are removed from the problem. Then, linearly dependent rows
        of the ``A_eq`` matrix are removed, (unless they represent an
        infeasibility) to avoid numerical difficulties in the primary solve
        routine. Note that rows that are nearly linearly dependent (within a
        prescribed tolerance) may also be removed, which can change the optimal
        solution in rare cases. If this is a concern, eliminate redundancy from
        your problem formulation and run with option ``rr=False`` or
        ``presolve=False``.

        Several potential improvements can be made here: additional presolve
        checks outlined in [8]_ should be implemented, the presolve routine should
        be run multiple times (until no further simplifications can be made), and
        more of the efficiency improvements from [5]_ should be implemented in the
        redundancy removal routines.

        After presolve, the problem is transformed to standard form by converting
        the (tightened) simple bounds to upper bound constraints, introducing
        non-negative slack variables for inequality constraints, and expressing
        unbounded variables as the difference between two non-negative variables.
        Optionally, the problem is automatically scaled via equilibration [12]_.
        The selected algorithm solves the standard form problem, and a
        postprocessing routine converts the result to a solution to the original
        problem.

        References
        ----------
        .. [1] Dantzig, George B., Linear programming and extensions. Rand
               Corporation Research Study Princeton Univ. Press, Princeton, NJ,
               1963
        .. [2] Hillier, S.H. and Lieberman, G.J. (1995), "Introduction to
               Mathematical Programming", McGraw-Hill, Chapter 4.
        .. [3] Bland, Robert G. New finite pivoting rules for the simplex method.
               Mathematics of Operations Research (2), 1977: pp. 103-107.
        .. [4] Andersen, Erling D., and Knud D. Andersen. "The MOSEK interior point
               optimizer for linear programming: an implementation of the
               homogeneous algorithm." High performance optimization. Springer US,
               2000. 197-232.
        .. [5] Andersen, Erling D. "Finding all linearly dependent rows in
               large-scale linear programming." Optimization Methods and Software
               6.3 (1995): 219-227.
        .. [6] Freund, Robert M. "Primal-Dual Interior-Point Methods for Linear
               Programming based on Newton's Method." Unpublished Course Notes,
               March 2004. Available 2/25/2017 at
               https://ocw.mit.edu/courses/sloan-school-of-management/15-084j-nonlinear-programming-spring-2004/lecture-notes/lec14_int_pt_mthd.pdf
        .. [7] Fourer, Robert. "Solving Linear Programs by Interior-Point Methods."
               Unpublished Course Notes, August 26, 2005. Available 2/25/2017 at
               http://www.4er.org/CourseNotes/Book%20B/B-III.pdf
        .. [8] Andersen, Erling D., and Knud D. Andersen. "Presolving in linear
               programming." Mathematical Programming 71.2 (1995): 221-245.
        .. [9] Bertsimas, Dimitris, and J. Tsitsiklis. "Introduction to linear
               programming." Athena Scientific 1 (1997): 997.
        .. [10] Andersen, Erling D., et al. Implementation of interior point
                methods for large scale linear programming. HEC/Universite de
                Geneve, 1996.
        .. [11] Bartels, Richard H. "A stabilization of the simplex method."
                Journal in  Numerische Mathematik 16.5 (1971): 414-434.
        .. [12] Tomlin, J. A. "On scaling linear programming problems."
                Mathematical Programming Study 4 (1975): 146-166.
        .. [13] Huangfu, Q., Galabova, I., Feldmeier, M., and Hall, J. A. J.
                "HiGHS - high performance software for linear optimization."
                https://highs.dev/
        .. [14] Huangfu, Q. and Hall, J. A. J. "Parallelizing the dual revised
                simplex method." Mathematical Programming Computation, 10 (1),
                119-142, 2018. DOI: 10.1007/s12532-017-0130-5

        Examples
        --------
        Consider the following problem:

        .. math::

            \min_{x_0, x_1} \ -x_0 + 4x_1 & \\
            \mbox{such that} \ -3x_0 + x_1 & \leq 6,\\
            -x_0 - 2x_1 & \geq -4,\\
            x_1 & \geq -3.

        The problem is not presented in the form accepted by `linprog`. This is
        easily remedied by converting the "greater than" inequality
        constraint to a "less than" inequality constraint by
        multiplying both sides by a factor of :math:`-1`. Note also that the last
        constraint is really the simple bound :math:`-3 \leq x_1 \leq \infty`.
        Finally, since there are no bounds on :math:`x_0`, we must explicitly
        specify the bounds :math:`-\infty \leq x_0 \leq \infty`, as the
        default is for variables to be non-negative. After collecting coeffecients
        into arrays and tuples, the input for this problem is:

        >>> from scipy.optimize import linprog
        >>> c = [-1, 4]
        >>> A = [[-3, 1], [1, 2]]
        >>> b = [6, 4]
        >>> x0_bounds = (None, None)
        >>> x1_bounds = (-3, None)
        >>> res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])
        >>> res.fun
        -22.0
        >>> res.x
        array([10., -3.])
        >>> res.message
        'Optimization terminated successfully. (HiGHS Status 7: Optimal)'

        The marginals (AKA dual values / shadow prices / Lagrange multipliers)
        and residuals (slacks) are also available.

        >>> res.ineqlin
          residual: [ 3.900e+01  0.000e+00]
         marginals: [-0.000e+00 -1.000e+00]

        For example, because the marginal associated with the second inequality
        constraint is -1, we expect the optimal value of the objective function
        to decrease by ``eps`` if we add a small amount ``eps`` to the right hand
        side of the second inequality constraint:

        >>> eps = 0.05
        >>> b[1] += eps
        >>> linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun
        -22.05

        Also, because the residual on the first inequality constraint is 39, we
        can decrease the right hand side of the first constraint by 39 without
        affecting the optimal solution.

        >>> b = [6, 4]  # reset to original values
        >>> b[0] -= 39
        >>> linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun
        -22.0

    linprog_verbose_callback(res)
        A sample callback function demonstrating the linprog callback interface.
        This callback produces detailed output to sys.stdout before each iteration
        and after the final iteration of the simplex algorithm.

        Parameters
        ----------
        res : A `scipy.optimize.OptimizeResult` consisting of the following fields:

            x : 1-D array
                The independent variable vector which optimizes the linear
                programming problem.
            fun : float
                Value of the objective function.
            success : bool
                True if the algorithm succeeded in finding an optimal solution.
            slack : 1-D array
                The values of the slack variables. Each slack variable corresponds
                to an inequality constraint. If the slack is zero, then the
                corresponding constraint is active.
            con : 1-D array
                The (nominally zero) residuals of the equality constraints, that is,
                ``b - A_eq @ x``
            phase : int
                The phase of the optimization being executed. In phase 1 a basic
                feasible solution is sought and the T has an additional row
                representing an alternate objective function.
            status : int
                An integer representing the exit status of the optimization::

                     0 : Optimization terminated successfully
                     1 : Iteration limit reached
                     2 : Problem appears to be infeasible
                     3 : Problem appears to be unbounded
                     4 : Serious numerical difficulties encountered

            nit : int
                The number of iterations performed.
            message : str
                A string descriptor of the exit status of the optimization.

    lsq_linear(A, b, bounds=(-inf, inf), method='trf', tol=1e-10, lsq_solver=None, lsmr_tol=None, max_iter=None, verbose=0, *, lsmr_maxiter=None)
        Solve a linear least-squares problem with bounds on the variables.

        Given a m-by-n design matrix A and a target vector b with m elements,
        `lsq_linear` solves the following optimization problem::

            minimize 0.5 * ||A x - b||**2
            subject to lb <= x <= ub

        This optimization problem is convex, hence a found minimum (if iterations
        have converged) is guaranteed to be global.

        Parameters
        ----------
        A : array_like, sparse matrix of LinearOperator, shape (m, n)
            Design matrix. Can be `scipy.sparse.linalg.LinearOperator`.
        b : array_like, shape (m,)
            Target vector.
        bounds : 2-tuple of array_like or `Bounds`, optional
            Lower and upper bounds on parameters. Defaults to no bounds.
            There are two ways to specify the bounds:

                - Instance of `Bounds` class.

                - 2-tuple of array_like: Each element of the tuple must be either
                  an array with the length equal to the number of parameters, or a
                  scalar (in which case the bound is taken to be the same for all
                  parameters). Use ``np.inf`` with an appropriate sign to disable
                  bounds on all or some parameters.

        method : 'trf' or 'bvls', optional
            Method to perform minimization.

                * 'trf' : Trust Region Reflective algorithm adapted for a linear
                  least-squares problem. This is an interior-point-like method
                  and the required number of iterations is weakly correlated with
                  the number of variables.
                * 'bvls' : Bounded-variable least-squares algorithm. This is
                  an active set method, which requires the number of iterations
                  comparable to the number of variables. Can't be used when `A` is
                  sparse or LinearOperator.

            Default is 'trf'.
        tol : float, optional
            Tolerance parameter. The algorithm terminates if a relative change
            of the cost function is less than `tol` on the last iteration.
            Additionally, the first-order optimality measure is considered:

                * ``method='trf'`` terminates if the uniform norm of the gradient,
                  scaled to account for the presence of the bounds, is less than
                  `tol`.
                * ``method='bvls'`` terminates if Karush-Kuhn-Tucker conditions
                  are satisfied within `tol` tolerance.

        lsq_solver : {None, 'exact', 'lsmr'}, optional
            Method of solving unbounded least-squares problems throughout
            iterations:

                * 'exact' : Use dense QR or SVD decomposition approach. Can't be
                  used when `A` is sparse or LinearOperator.
                * 'lsmr' : Use `scipy.sparse.linalg.lsmr` iterative procedure
                  which requires only matrix-vector product evaluations. Can't
                  be used with ``method='bvls'``.

            If None (default), the solver is chosen based on type of `A`.
        lsmr_tol : None, float or 'auto', optional
            Tolerance parameters 'atol' and 'btol' for `scipy.sparse.linalg.lsmr`
            If None (default), it is set to ``1e-2 * tol``. If 'auto', the
            tolerance will be adjusted based on the optimality of the current
            iterate, which can speed up the optimization process, but is not always
            reliable.
        max_iter : None or int, optional
            Maximum number of iterations before termination. If None (default), it
            is set to 100 for ``method='trf'`` or to the number of variables for
            ``method='bvls'`` (not counting iterations for 'bvls' initialization).
        verbose : {0, 1, 2}, optional
            Level of algorithm's verbosity:

                * 0 : work silently (default).
                * 1 : display a termination report.
                * 2 : display progress during iterations.
        lsmr_maxiter : None or int, optional
            Maximum number of iterations for the lsmr least squares solver,
            if it is used (by setting ``lsq_solver='lsmr'``). If None (default), it
            uses lsmr's default of ``min(m, n)`` where ``m`` and ``n`` are the
            number of rows and columns of `A`, respectively. Has no effect if
            ``lsq_solver='exact'``.

        Returns
        -------
        OptimizeResult with the following fields defined:
        x : ndarray, shape (n,)
            Solution found.
        cost : float
            Value of the cost function at the solution.
        fun : ndarray, shape (m,)
            Vector of residuals at the solution.
        optimality : float
            First-order optimality measure. The exact meaning depends on `method`,
            refer to the description of `tol` parameter.
        active_mask : ndarray of int, shape (n,)
            Each component shows whether a corresponding constraint is active
            (that is, whether a variable is at the bound):

                *  0 : a constraint is not active.
                * -1 : a lower bound is active.
                *  1 : an upper bound is active.

            Might be somewhat arbitrary for the `trf` method as it generates a
            sequence of strictly feasible iterates and active_mask is determined
            within a tolerance threshold.
        unbounded_sol : tuple
            Unbounded least squares solution tuple returned by the least squares
            solver (set with `lsq_solver` option). If `lsq_solver` is not set or is
            set to ``'exact'``, the tuple contains an ndarray of shape (n,) with
            the unbounded solution, an ndarray with the sum of squared residuals,
            an int with the rank of `A`, and an ndarray with the singular values
            of `A` (see NumPy's ``linalg.lstsq`` for more information). If
            `lsq_solver` is set to ``'lsmr'``, the tuple contains an ndarray of
            shape (n,) with the unbounded solution, an int with the exit code,
            an int with the number of iterations, and five floats with
            various norms and the condition number of `A` (see SciPy's
            ``sparse.linalg.lsmr`` for more information). This output can be
            useful for determining the convergence of the least squares solver,
            particularly the iterative ``'lsmr'`` solver. The unbounded least
            squares problem is to minimize ``0.5 * ||A x - b||**2``.
        nit : int
            Number of iterations. Zero if the unconstrained solution is optimal.
        status : int
            Reason for algorithm termination:

                * -1 : the algorithm was not able to make progress on the last
                  iteration.
                *  0 : the maximum number of iterations is exceeded.
                *  1 : the first-order optimality measure is less than `tol`.
                *  2 : the relative change of the cost function is less than `tol`.
                *  3 : the unconstrained solution is optimal.

        message : str
            Verbal description of the termination reason.
        success : bool
            True if one of the convergence criteria is satisfied (`status` > 0).

        See Also
        --------
        nnls : Linear least squares with non-negativity constraint.
        least_squares : Nonlinear least squares with bounds on the variables.

        Notes
        -----
        The algorithm first computes the unconstrained least-squares solution by
        `numpy.linalg.lstsq` or `scipy.sparse.linalg.lsmr` depending on
        `lsq_solver`. This solution is returned as optimal if it lies within the
        bounds.

        Method 'trf' runs the adaptation of the algorithm described in [STIR]_ for
        a linear least-squares problem. The iterations are essentially the same as
        in the nonlinear least-squares algorithm, but as the quadratic function
        model is always accurate, we don't need to track or modify the radius of
        a trust region. The line search (backtracking) is used as a safety net
        when a selected step does not decrease the cost function. Read more
        detailed description of the algorithm in `scipy.optimize.least_squares`.

        Method 'bvls' runs a Python implementation of the algorithm described in
        [BVLS]_. The algorithm maintains active and free sets of variables, on
        each iteration chooses a new variable to move from the active set to the
        free set and then solves the unconstrained least-squares problem on free
        variables. This algorithm is guaranteed to give an accurate solution
        eventually, but may require up to n iterations for a problem with n
        variables. Additionally, an ad-hoc initialization procedure is
        implemented, that determines which variables to set free or active
        initially. It takes some number of iterations before actual BVLS starts,
        but can significantly reduce the number of further iterations.

        References
        ----------
        .. [STIR] M. A. Branch, T. F. Coleman, and Y. Li, "A Subspace, Interior,
                  and Conjugate Gradient Method for Large-Scale Bound-Constrained
                  Minimization Problems," SIAM Journal on Scientific Computing,
                  Vol. 21, Number 1, pp 1-23, 1999.
        .. [BVLS] P. B. Start and R. L. Parker, "Bounded-Variable Least-Squares:
                  an Algorithm and Applications", Computational Statistics, 10,
                  129-141, 1995.

        Examples
        --------
        In this example, a problem with a large sparse matrix and bounds on the
        variables is solved.

        >>> import numpy as np
        >>> from scipy.sparse import rand
        >>> from scipy.optimize import lsq_linear
        >>> rng = np.random.default_rng()
        ...
        >>> m = 20000
        >>> n = 10000
        ...
        >>> A = rand(m, n, density=1e-4, random_state=rng)
        >>> b = rng.standard_normal(m)
        ...
        >>> lb = rng.standard_normal(n)
        >>> ub = lb + 1
        ...
        >>> res = lsq_linear(A, b, bounds=(lb, ub), lsmr_tol='auto', verbose=1)
        # may vary
        The relative change of the cost function is less than `tol`.
        Number of iterations 16, initial cost 1.5039e+04, final cost 1.1112e+04,
        first-order optimality 4.66e-08.

    milp(c, *, integrality=None, bounds=None, constraints=None, options=None)
        Mixed-integer linear programming

        Solves problems of the following form:

        .. math::

            \min_x \ & c^T x \\
            \mbox{such that} \ & b_l \leq A x \leq b_u,\\
            & l \leq x \leq u, \\
            & x_i \in \mathbb{Z}, i \in X_i

        where :math:`x` is a vector of decision variables;
        :math:`c`, :math:`b_l`, :math:`b_u`, :math:`l`, and :math:`u` are vectors;
        :math:`A` is a matrix, and :math:`X_i` is the set of indices of
        decision variables that must be integral. (In this context, a
        variable that can assume only integer values is said to be "integral";
        it has an "integrality" constraint.)

        Alternatively, that's:

        minimize::

            c @ x

        such that::

            b_l <= A @ x <= b_u
            l <= x <= u
            Specified elements of x must be integers

        By default, ``l = 0`` and ``u = np.inf`` unless specified with
        ``bounds``.

        Parameters
        ----------
        c : 1D dense array_like
            The coefficients of the linear objective function to be minimized.
            `c` is converted to a double precision array before the problem is
            solved.
        integrality : 1D dense array_like, optional
            Indicates the type of integrality constraint on each decision variable.

            ``0`` : Continuous variable; no integrality constraint.

            ``1`` : Integer variable; decision variable must be an integer
            within `bounds`.

            ``2`` : Semi-continuous variable; decision variable must be within
            `bounds` or take value ``0``.

            ``3`` : Semi-integer variable; decision variable must be an integer
            within `bounds` or take value ``0``.

            By default, all variables are continuous. `integrality` is converted
            to an array of integers before the problem is solved.

        bounds : scipy.optimize.Bounds, optional
            Bounds on the decision variables. Lower and upper bounds are converted
            to double precision arrays before the problem is solved. The
            ``keep_feasible`` parameter of the `Bounds` object is ignored. If
            not specified, all decision variables are constrained to be
            non-negative.
        constraints : sequence of scipy.optimize.LinearConstraint, optional
            Linear constraints of the optimization problem. Arguments may be
            one of the following:

            1. A single `LinearConstraint` object
            2. A single tuple that can be converted to a `LinearConstraint` object
               as ``LinearConstraint(*constraints)``
            3. A sequence composed entirely of objects of type 1. and 2.

            Before the problem is solved, all values are converted to double
            precision, and the matrices of constraint coefficients are converted to
            instances of `scipy.sparse.csc_array`. The ``keep_feasible`` parameter
            of `LinearConstraint` objects is ignored.
        options : dict, optional
            A dictionary of solver options. The following keys are recognized.

            disp : bool (default: ``False``)
                Set to ``True`` if indicators of optimization status are to be
                printed to the console during optimization.
            node_limit : int, optional
                The maximum number of nodes (linear program relaxations) to solve
                before stopping. Default is no maximum number of nodes.
            presolve : bool (default: ``True``)
                Presolve attempts to identify trivial infeasibilities,
                identify trivial unboundedness, and simplify the problem before
                sending it to the main solver.
            time_limit : float, optional
                The maximum number of seconds allotted to solve the problem.
                Default is no time limit.
            mip_rel_gap : float, optional
                Termination criterion for MIP solver: solver will terminate when
                the gap between the primal objective value and the dual objective
                bound, scaled by the primal objective value, is <= mip_rel_gap.

        Returns
        -------
        res : OptimizeResult
            An instance of :class:`scipy.optimize.OptimizeResult`. The object
            is guaranteed to have the following attributes.

            status : int
                An integer representing the exit status of the algorithm.

                ``0`` : Optimal solution found.

                ``1`` : Iteration or time limit reached.

                ``2`` : Problem is infeasible.

                ``3`` : Problem is unbounded.

                ``4`` : Other; see message for details.

            success : bool
                ``True`` when an optimal solution is found and ``False`` otherwise.

            message : str
                A string descriptor of the exit status of the algorithm.

            The following attributes will also be present, but the values may be
            ``None``, depending on the solution status.

            x : ndarray
                The values of the decision variables that minimize the
                objective function while satisfying the constraints.
            fun : float
                The optimal value of the objective function ``c @ x``.
            mip_node_count : int
                The number of subproblems or "nodes" solved by the MILP solver.
            mip_dual_bound : float
                The MILP solver's final estimate of the lower bound on the optimal
                solution.
            mip_gap : float
                The difference between the primal objective value and the dual
                objective bound, scaled by the primal objective value.

        Notes
        -----
        `milp` is a wrapper of the HiGHS linear optimization software [1]_. The
        algorithm is deterministic, and it typically finds the global optimum of
        moderately challenging mixed-integer linear programs (when it exists).

        References
        ----------
        .. [1] Huangfu, Q., Galabova, I., Feldmeier, M., and Hall, J. A. J.
               "HiGHS - high performance software for linear optimization."
               https://highs.dev/
        .. [2] Huangfu, Q. and Hall, J. A. J. "Parallelizing the dual revised
               simplex method." Mathematical Programming Computation, 10 (1),
               119-142, 2018. DOI: 10.1007/s12532-017-0130-5

        Examples
        --------
        Consider the problem at
        https://en.wikipedia.org/wiki/Integer_programming#Example, which is
        expressed as a maximization problem of two variables. Since `milp` requires
        that the problem be expressed as a minimization problem, the objective
        function coefficients on the decision variables are:

        >>> import numpy as np
        >>> c = -np.array([0, 1])

        Note the negative sign: we maximize the original objective function
        by minimizing the negative of the objective function.

        We collect the coefficients of the constraints into arrays like:

        >>> A = np.array([[-1, 1], [3, 2], [2, 3]])
        >>> b_u = np.array([1, 12, 12])
        >>> b_l = np.full_like(b_u, -np.inf, dtype=float)

        Because there is no lower limit on these constraints, we have defined a
        variable ``b_l`` full of values representing negative infinity. This may
        be unfamiliar to users of `scipy.optimize.linprog`, which only accepts
        "less than" (or "upper bound") inequality constraints of the form
        ``A_ub @ x <= b_u``. By accepting both ``b_l`` and ``b_u`` of constraints
        ``b_l <= A_ub @ x <= b_u``, `milp` makes it easy to specify "greater than"
        inequality constraints, "less than" inequality constraints, and equality
        constraints concisely.

        These arrays are collected into a single `LinearConstraint` object like:

        >>> from scipy.optimize import LinearConstraint
        >>> constraints = LinearConstraint(A, b_l, b_u)

        The non-negativity bounds on the decision variables are enforced by
        default, so we do not need to provide an argument for `bounds`.

        Finally, the problem states that both decision variables must be integers:

        >>> integrality = np.ones_like(c)

        We solve the problem like:

        >>> from scipy.optimize import milp
        >>> res = milp(c=c, constraints=constraints, integrality=integrality)
        >>> res.x
        [2.0, 2.0]

        Note that had we solved the relaxed problem (without integrality
        constraints):

        >>> res = milp(c=c, constraints=constraints)  # OR:
        >>> # from scipy.optimize import linprog; res = linprog(c, A, b_u)
        >>> res.x
        [1.8, 2.8]

        we would not have obtained the correct solution by rounding to the nearest
        integers.

        Other examples are given :ref:`in the tutorial <tutorial-optimize_milp>`.

    minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
        Minimization of scalar function of one or more variables.

        Parameters
        ----------
        fun : callable
            The objective function to be minimized.

                ``fun(x, *args) -> float``

            where ``x`` is a 1-D array with shape (n,) and ``args``
            is a tuple of the fixed parameters needed to completely
            specify the function.
        x0 : ndarray, shape (n,)
            Initial guess. Array of real elements of size (n,),
            where ``n`` is the number of independent variables.
        args : tuple, optional
            Extra arguments passed to the objective function and its
            derivatives (`fun`, `jac` and `hess` functions).
        method : str or callable, optional
            Type of solver.  Should be one of

                - 'Nelder-Mead' :ref:`(see here) <optimize.minimize-neldermead>`
                - 'Powell'      :ref:`(see here) <optimize.minimize-powell>`
                - 'CG'          :ref:`(see here) <optimize.minimize-cg>`
                - 'BFGS'        :ref:`(see here) <optimize.minimize-bfgs>`
                - 'Newton-CG'   :ref:`(see here) <optimize.minimize-newtoncg>`
                - 'L-BFGS-B'    :ref:`(see here) <optimize.minimize-lbfgsb>`
                - 'TNC'         :ref:`(see here) <optimize.minimize-tnc>`
                - 'COBYLA'      :ref:`(see here) <optimize.minimize-cobyla>`
                - 'COBYQA'      :ref:`(see here) <optimize.minimize-cobyqa>`
                - 'SLSQP'       :ref:`(see here) <optimize.minimize-slsqp>`
                - 'trust-constr':ref:`(see here) <optimize.minimize-trustconstr>`
                - 'dogleg'      :ref:`(see here) <optimize.minimize-dogleg>`
                - 'trust-ncg'   :ref:`(see here) <optimize.minimize-trustncg>`
                - 'trust-exact' :ref:`(see here) <optimize.minimize-trustexact>`
                - 'trust-krylov' :ref:`(see here) <optimize.minimize-trustkrylov>`
                - custom - a callable object, see below for description.

            If not given, chosen to be one of ``BFGS``, ``L-BFGS-B``, ``SLSQP``,
            depending on whether or not the problem has constraints or bounds.
        jac : {callable,  '2-point', '3-point', 'cs', bool}, optional
            Method for computing the gradient vector. Only for CG, BFGS,
            Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov,
            trust-exact and trust-constr.
            If it is a callable, it should be a function that returns the gradient
            vector:

                ``jac(x, *args) -> array_like, shape (n,)``

            where ``x`` is an array with shape (n,) and ``args`` is a tuple with
            the fixed parameters. If `jac` is a Boolean and is True, `fun` is
            assumed to return a tuple ``(f, g)`` containing the objective
            function and the gradient.
            Methods 'Newton-CG', 'trust-ncg', 'dogleg', 'trust-exact', and
            'trust-krylov' require that either a callable be supplied, or that
            `fun` return the objective and gradient.
            If None or False, the gradient will be estimated using 2-point finite
            difference estimation with an absolute step size.
            Alternatively, the keywords  {'2-point', '3-point', 'cs'} can be used
            to select a finite difference scheme for numerical estimation of the
            gradient with a relative step size. These finite difference schemes
            obey any specified `bounds`.
        hess : {callable, '2-point', '3-point', 'cs', HessianUpdateStrategy}, optional
            Method for computing the Hessian matrix. Only for Newton-CG, dogleg,
            trust-ncg, trust-krylov, trust-exact and trust-constr.
            If it is callable, it should return the Hessian matrix:

                ``hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)``

            where ``x`` is a (n,) ndarray and ``args`` is a tuple with the fixed
            parameters.
            The keywords {'2-point', '3-point', 'cs'} can also be used to select
            a finite difference scheme for numerical estimation of the hessian.
            Alternatively, objects implementing the `HessianUpdateStrategy`
            interface can be used to approximate the Hessian. Available
            quasi-Newton methods implementing this interface are:

                - `BFGS`;
                - `SR1`.

            Not all of the options are available for each of the methods; for
            availability refer to the notes.
        hessp : callable, optional
            Hessian of objective function times an arbitrary vector p. Only for
            Newton-CG, trust-ncg, trust-krylov, trust-constr.
            Only one of `hessp` or `hess` needs to be given. If `hess` is
            provided, then `hessp` will be ignored. `hessp` must compute the
            Hessian times an arbitrary vector:

                ``hessp(x, p, *args) ->  ndarray shape (n,)``

            where ``x`` is a (n,) ndarray, ``p`` is an arbitrary vector with
            dimension (n,) and ``args`` is a tuple with the fixed
            parameters.
        bounds : sequence or `Bounds`, optional
            Bounds on variables for Nelder-Mead, L-BFGS-B, TNC, SLSQP, Powell,
            trust-constr, COBYLA, and COBYQA methods. There are two ways to specify
            the bounds:

                1. Instance of `Bounds` class.
                2. Sequence of ``(min, max)`` pairs for each element in `x`. None
                   is used to specify no bound.

        constraints : {Constraint, dict} or List of {Constraint, dict}, optional
            Constraints definition. Only for COBYLA, COBYQA, SLSQP and trust-constr.

            Constraints for 'trust-constr' and 'cobyqa' are defined as a single object
            or a list of objects specifying constraints to the optimization problem.
            Available constraints are:

                - `LinearConstraint`
                - `NonlinearConstraint`

            Constraints for COBYLA, SLSQP are defined as a list of dictionaries.
            Each dictionary with fields:

                type : str
                    Constraint type: 'eq' for equality, 'ineq' for inequality.
                fun : callable
                    The function defining the constraint.
                jac : callable, optional
                    The Jacobian of `fun` (only for SLSQP).
                args : sequence, optional
                    Extra arguments to be passed to the function and Jacobian.

            Equality constraint means that the constraint function result is to
            be zero whereas inequality means that it is to be non-negative.
            Note that COBYLA only supports inequality constraints.

        tol : float, optional
            Tolerance for termination. When `tol` is specified, the selected
            minimization algorithm sets some relevant solver-specific tolerance(s)
            equal to `tol`. For detailed control, use solver-specific
            options.
        options : dict, optional
            A dictionary of solver options. All methods except `TNC` accept the
            following generic options:

                maxiter : int
                    Maximum number of iterations to perform. Depending on the
                    method each iteration may use several function evaluations.

                    For `TNC` use `maxfun` instead of `maxiter`.
                disp : bool
                    Set to True to print convergence messages.

            For method-specific options, see :func:`show_options()`.
        callback : callable, optional
            A callable called after each iteration.

            All methods except TNC, SLSQP, and COBYLA support a callable with
            the signature:

                ``callback(intermediate_result: OptimizeResult)``

            where ``intermediate_result`` is a keyword parameter containing an
            `OptimizeResult` with attributes ``x`` and ``fun``, the present values
            of the parameter vector and objective function. Note that the name
            of the parameter must be ``intermediate_result`` for the callback
            to be passed an `OptimizeResult`. These methods will also terminate if
            the callback raises ``StopIteration``.

            All methods except trust-constr (also) support a signature like:

                ``callback(xk)``

            where ``xk`` is the current parameter vector.

            Introspection is used to determine which of the signatures above to
            invoke.

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a ``OptimizeResult`` object.
            Important attributes are: ``x`` the solution array, ``success`` a
            Boolean flag indicating if the optimizer exited successfully and
            ``message`` which describes the cause of the termination. See
            `OptimizeResult` for a description of other attributes.

        See also
        --------
        minimize_scalar : Interface to minimization algorithms for scalar
            univariate functions
        show_options : Additional options accepted by the solvers

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter. The default method is *BFGS*.

        **Unconstrained minimization**

        Method :ref:`CG <optimize.minimize-cg>` uses a nonlinear conjugate
        gradient algorithm by Polak and Ribiere, a variant of the
        Fletcher-Reeves method described in [5]_ pp.120-122. Only the
        first derivatives are used.

        Method :ref:`BFGS <optimize.minimize-bfgs>` uses the quasi-Newton
        method of Broyden, Fletcher, Goldfarb, and Shanno (BFGS) [5]_
        pp. 136. It uses the first derivatives only. BFGS has proven good
        performance even for non-smooth optimizations. This method also
        returns an approximation of the Hessian inverse, stored as
        `hess_inv` in the OptimizeResult object.

        Method :ref:`Newton-CG <optimize.minimize-newtoncg>` uses a
        Newton-CG algorithm [5]_ pp. 168 (also known as the truncated
        Newton method). It uses a CG method to the compute the search
        direction. See also *TNC* method for a box-constrained
        minimization with a similar algorithm. Suitable for large-scale
        problems.

        Method :ref:`dogleg <optimize.minimize-dogleg>` uses the dog-leg
        trust-region algorithm [5]_ for unconstrained minimization. This
        algorithm requires the gradient and Hessian; furthermore the
        Hessian is required to be positive definite.

        Method :ref:`trust-ncg <optimize.minimize-trustncg>` uses the
        Newton conjugate gradient trust-region algorithm [5]_ for
        unconstrained minimization. This algorithm requires the gradient
        and either the Hessian or a function that computes the product of
        the Hessian with a given vector. Suitable for large-scale problems.

        Method :ref:`trust-krylov <optimize.minimize-trustkrylov>` uses
        the Newton GLTR trust-region algorithm [14]_, [15]_ for unconstrained
        minimization. This algorithm requires the gradient
        and either the Hessian or a function that computes the product of
        the Hessian with a given vector. Suitable for large-scale problems.
        On indefinite problems it requires usually less iterations than the
        `trust-ncg` method and is recommended for medium and large-scale problems.

        Method :ref:`trust-exact <optimize.minimize-trustexact>`
        is a trust-region method for unconstrained minimization in which
        quadratic subproblems are solved almost exactly [13]_. This
        algorithm requires the gradient and the Hessian (which is
        *not* required to be positive definite). It is, in many
        situations, the Newton method to converge in fewer iterations
        and the most recommended for small and medium-size problems.

        **Bound-Constrained minimization**

        Method :ref:`Nelder-Mead <optimize.minimize-neldermead>` uses the
        Simplex algorithm [1]_, [2]_. This algorithm is robust in many
        applications. However, if numerical computation of derivative can be
        trusted, other algorithms using the first and/or second derivatives
        information might be preferred for their better performance in
        general.

        Method :ref:`L-BFGS-B <optimize.minimize-lbfgsb>` uses the L-BFGS-B
        algorithm [6]_, [7]_ for bound constrained minimization.

        Method :ref:`Powell <optimize.minimize-powell>` is a modification
        of Powell's method [3]_, [4]_ which is a conjugate direction
        method. It performs sequential one-dimensional minimizations along
        each vector of the directions set (`direc` field in `options` and
        `info`), which is updated at each iteration of the main
        minimization loop. The function need not be differentiable, and no
        derivatives are taken. If bounds are not provided, then an
        unbounded line search will be used. If bounds are provided and
        the initial guess is within the bounds, then every function
        evaluation throughout the minimization procedure will be within
        the bounds. If bounds are provided, the initial guess is outside
        the bounds, and `direc` is full rank (default has full rank), then
        some function evaluations during the first iteration may be
        outside the bounds, but every function evaluation after the first
        iteration will be within the bounds. If `direc` is not full rank,
        then some parameters may not be optimized and the solution is not
        guaranteed to be within the bounds.

        Method :ref:`TNC <optimize.minimize-tnc>` uses a truncated Newton
        algorithm [5]_, [8]_ to minimize a function with variables subject
        to bounds. This algorithm uses gradient information; it is also
        called Newton Conjugate-Gradient. It differs from the *Newton-CG*
        method described above as it wraps a C implementation and allows
        each variable to be given upper and lower bounds.

        **Constrained Minimization**

        Method :ref:`COBYLA <optimize.minimize-cobyla>` uses the
        Constrained Optimization BY Linear Approximation (COBYLA) method
        [9]_, [10]_, [11]_. The algorithm is based on linear
        approximations to the objective function and each constraint. The
        method wraps a FORTRAN implementation of the algorithm. The
        constraints functions 'fun' may return either a single number
        or an array or list of numbers.

        Method :ref:`COBYQA <optimize.minimize-cobyqa>` uses the Constrained
        Optimization BY Quadratic Approximations (COBYQA) method [18]_. The
        algorithm is a derivative-free trust-region SQP method based on quadratic
        approximations to the objective function and each nonlinear constraint. The
        bounds are treated as unrelaxable constraints, in the sense that the
        algorithm always respects them throughout the optimization process.

        Method :ref:`SLSQP <optimize.minimize-slsqp>` uses Sequential
        Least SQuares Programming to minimize a function of several
        variables with any combination of bounds, equality and inequality
        constraints. The method wraps the SLSQP Optimization subroutine
        originally implemented by Dieter Kraft [12]_. Note that the
        wrapper handles infinite values in bounds by converting them into
        large floating values.

        Method :ref:`trust-constr <optimize.minimize-trustconstr>` is a
        trust-region algorithm for constrained optimization. It switches
        between two implementations depending on the problem definition.
        It is the most versatile constrained minimization algorithm
        implemented in SciPy and the most appropriate for large-scale problems.
        For equality constrained problems it is an implementation of Byrd-Omojokun
        Trust-Region SQP method described in [17]_ and in [5]_, p. 549. When
        inequality constraints are imposed as well, it switches to the trust-region
        interior point method described in [16]_. This interior point algorithm,
        in turn, solves inequality constraints by introducing slack variables
        and solving a sequence of equality-constrained barrier problems
        for progressively smaller values of the barrier parameter.
        The previously described equality constrained SQP method is
        used to solve the subproblems with increasing levels of accuracy
        as the iterate gets closer to a solution.

        **Finite-Difference Options**

        For Method :ref:`trust-constr <optimize.minimize-trustconstr>`
        the gradient and the Hessian may be approximated using
        three finite-difference schemes: {'2-point', '3-point', 'cs'}.
        The scheme 'cs' is, potentially, the most accurate but it
        requires the function to correctly handle complex inputs and to
        be differentiable in the complex plane. The scheme '3-point' is more
        accurate than '2-point' but requires twice as many operations. If the
        gradient is estimated via finite-differences the Hessian must be
        estimated using one of the quasi-Newton strategies.

        **Method specific options for the** `hess` **keyword**

        +--------------+------+----------+-------------------------+-----+
        | method/Hess  | None | callable | '2-point/'3-point'/'cs' | HUS |
        +==============+======+==========+=========================+=====+
        | Newton-CG    | x    | (n, n)   | x                       | x   |
        |              |      | LO       |                         |     |
        +--------------+------+----------+-------------------------+-----+
        | dogleg       |      | (n, n)   |                         |     |
        +--------------+------+----------+-------------------------+-----+
        | trust-ncg    |      | (n, n)   | x                       | x   |
        +--------------+------+----------+-------------------------+-----+
        | trust-krylov |      | (n, n)   | x                       | x   |
        +--------------+------+----------+-------------------------+-----+
        | trust-exact  |      | (n, n)   |                         |     |
        +--------------+------+----------+-------------------------+-----+
        | trust-constr | x    | (n, n)   |  x                      | x   |
        |              |      | LO       |                         |     |
        |              |      | sp       |                         |     |
        +--------------+------+----------+-------------------------+-----+

        where LO=LinearOperator, sp=Sparse matrix, HUS=HessianUpdateStrategy

        **Custom minimizers**

        It may be useful to pass a custom minimization method, for example
        when using a frontend to this method such as `scipy.optimize.basinhopping`
        or a different library.  You can simply pass a callable as the ``method``
        parameter.

        The callable is called as ``method(fun, x0, args, **kwargs, **options)``
        where ``kwargs`` corresponds to any other parameters passed to `minimize`
        (such as `callback`, `hess`, etc.), except the `options` dict, which has
        its contents also passed as `method` parameters pair by pair.  Also, if
        `jac` has been passed as a bool type, `jac` and `fun` are mangled so that
        `fun` returns just the function values and `jac` is converted to a function
        returning the Jacobian.  The method shall return an `OptimizeResult`
        object.

        The provided `method` callable must be able to accept (and possibly ignore)
        arbitrary parameters; the set of parameters accepted by `minimize` may
        expand in future versions and then these parameters will be passed to
        the method.  You can find an example in the scipy.optimize tutorial.

        References
        ----------
        .. [1] Nelder, J A, and R Mead. 1965. A Simplex Method for Function
            Minimization. The Computer Journal 7: 308-13.
        .. [2] Wright M H. 1996. Direct search methods: Once scorned, now
            respectable, in Numerical Analysis 1995: Proceedings of the 1995
            Dundee Biennial Conference in Numerical Analysis (Eds. D F
            Griffiths and G A Watson). Addison Wesley Longman, Harlow, UK.
            191-208.
        .. [3] Powell, M J D. 1964. An efficient method for finding the minimum of
           a function of several variables without calculating derivatives. The
           Computer Journal 7: 155-162.
        .. [4] Press W, S A Teukolsky, W T Vetterling and B P Flannery.
           Numerical Recipes (any edition), Cambridge University Press.
        .. [5] Nocedal, J, and S J Wright. 2006. Numerical Optimization.
           Springer New York.
        .. [6] Byrd, R H and P Lu and J. Nocedal. 1995. A Limited Memory
           Algorithm for Bound Constrained Optimization. SIAM Journal on
           Scientific and Statistical Computing 16 (5): 1190-1208.
        .. [7] Zhu, C and R H Byrd and J Nocedal. 1997. L-BFGS-B: Algorithm
           778: L-BFGS-B, FORTRAN routines for large scale bound constrained
           optimization. ACM Transactions on Mathematical Software 23 (4):
           550-560.
        .. [8] Nash, S G. Newton-Type Minimization Via the Lanczos Method.
           1984. SIAM Journal of Numerical Analysis 21: 770-778.
        .. [9] Powell, M J D. A direct search optimization method that models
           the objective and constraint functions by linear interpolation.
           1994. Advances in Optimization and Numerical Analysis, eds. S. Gomez
           and J-P Hennart, Kluwer Academic (Dordrecht), 51-67.
        .. [10] Powell M J D. Direct search algorithms for optimization
           calculations. 1998. Acta Numerica 7: 287-336.
        .. [11] Powell M J D. A view of algorithms for optimization without
           derivatives. 2007.Cambridge University Technical Report DAMTP
           2007/NA03
        .. [12] Kraft, D. A software package for sequential quadratic
           programming. 1988. Tech. Rep. DFVLR-FB 88-28, DLR German Aerospace
           Center -- Institute for Flight Mechanics, Koln, Germany.
        .. [13] Conn, A. R., Gould, N. I., and Toint, P. L.
           Trust region methods. 2000. Siam. pp. 169-200.
        .. [14] F. Lenders, C. Kirches, A. Potschka: "trlib: A vector-free
           implementation of the GLTR method for iterative solution of
           the trust region problem", :arxiv:`1611.04718`
        .. [15] N. Gould, S. Lucidi, M. Roma, P. Toint: "Solving the
           Trust-Region Subproblem using the Lanczos Method",
           SIAM J. Optim., 9(2), 504--525, (1999).
        .. [16] Byrd, Richard H., Mary E. Hribar, and Jorge Nocedal. 1999.
            An interior point algorithm for large-scale nonlinear  programming.
            SIAM Journal on Optimization 9.4: 877-900.
        .. [17] Lalee, Marucha, Jorge Nocedal, and Todd Plantega. 1998. On the
            implementation of an algorithm for large-scale equality constrained
            optimization. SIAM Journal on Optimization 8.3: 682-706.
        .. [18] Ragonneau, T. M. *Model-Based Derivative-Free Optimization Methods
            and Software*. PhD thesis, Department of Applied Mathematics, The Hong
            Kong Polytechnic University, Hong Kong, China, 2022. URL:
            https://theses.lib.polyu.edu.hk/handle/200/12294.

        Examples
        --------
        Let us consider the problem of minimizing the Rosenbrock function. This
        function (and its respective derivatives) is implemented in `rosen`
        (resp. `rosen_der`, `rosen_hess`) in the `scipy.optimize`.

        >>> from scipy.optimize import minimize, rosen, rosen_der

        A simple application of the *Nelder-Mead* method is:

        >>> x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
        >>> res = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6)
        >>> res.x
        array([ 1.,  1.,  1.,  1.,  1.])

        Now using the *BFGS* algorithm, using the first derivative and a few
        options:

        >>> res = minimize(rosen, x0, method='BFGS', jac=rosen_der,
        ...                options={'gtol': 1e-6, 'disp': True})
        Optimization terminated successfully.
                 Current function value: 0.000000
                 Iterations: 26
                 Function evaluations: 31
                 Gradient evaluations: 31
        >>> res.x
        array([ 1.,  1.,  1.,  1.,  1.])
        >>> print(res.message)
        Optimization terminated successfully.
        >>> res.hess_inv
        array([
            [ 0.00749589,  0.01255155,  0.02396251,  0.04750988,  0.09495377],  # may vary
            [ 0.01255155,  0.02510441,  0.04794055,  0.09502834,  0.18996269],
            [ 0.02396251,  0.04794055,  0.09631614,  0.19092151,  0.38165151],
            [ 0.04750988,  0.09502834,  0.19092151,  0.38341252,  0.7664427 ],
            [ 0.09495377,  0.18996269,  0.38165151,  0.7664427,   1.53713523]
        ])


        Next, consider a minimization problem with several constraints (namely
        Example 16.4 from [5]_). The objective function is:

        >>> fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2

        There are three constraints defined as:

        >>> cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + 2},
        ...         {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6},
        ...         {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2})

        And variables must be positive, hence the following bounds:

        >>> bnds = ((0, None), (0, None))

        The optimization problem is solved using the SLSQP method as:

        >>> res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds,
        ...                constraints=cons)

        It should converge to the theoretical solution (1.4 ,1.7).

    minimize_scalar(fun, bracket=None, bounds=None, args=(), method=None, tol=None, options=None)
        Local minimization of scalar function of one variable.

        Parameters
        ----------
        fun : callable
            Objective function.
            Scalar function, must return a scalar.
        bracket : sequence, optional
            For methods 'brent' and 'golden', `bracket` defines the bracketing
            interval and is required.
            Either a triple ``(xa, xb, xc)`` satisfying ``xa < xb < xc`` and
            ``func(xb) < func(xa) and  func(xb) < func(xc)``, or a pair
            ``(xa, xb)`` to be used as initial points for a downhill bracket search
            (see `scipy.optimize.bracket`).
            The minimizer ``res.x`` will not necessarily satisfy
            ``xa <= res.x <= xb``.
        bounds : sequence, optional
            For method 'bounded', `bounds` is mandatory and must have two finite
            items corresponding to the optimization bounds.
        args : tuple, optional
            Extra arguments passed to the objective function.
        method : str or callable, optional
            Type of solver.  Should be one of:

                - :ref:`Brent <optimize.minimize_scalar-brent>`
                - :ref:`Bounded <optimize.minimize_scalar-bounded>`
                - :ref:`Golden <optimize.minimize_scalar-golden>`
                - custom - a callable object (added in version 0.14.0), see below

            Default is "Bounded" if bounds are provided and "Brent" otherwise.
            See the 'Notes' section for details of each solver.

        tol : float, optional
            Tolerance for termination. For detailed control, use solver-specific
            options.
        options : dict, optional
            A dictionary of solver options.

                maxiter : int
                    Maximum number of iterations to perform.
                disp : bool
                    Set to True to print convergence messages.

            See :func:`show_options()` for solver-specific options.

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a ``OptimizeResult`` object.
            Important attributes are: ``x`` the solution array, ``success`` a
            Boolean flag indicating if the optimizer exited successfully and
            ``message`` which describes the cause of the termination. See
            `OptimizeResult` for a description of other attributes.

        See also
        --------
        minimize : Interface to minimization algorithms for scalar multivariate
            functions
        show_options : Additional options accepted by the solvers

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter. The default method is the ``"Bounded"`` Brent method if
        `bounds` are passed and unbounded ``"Brent"`` otherwise.

        Method :ref:`Brent <optimize.minimize_scalar-brent>` uses Brent's
        algorithm [1]_ to find a local minimum.  The algorithm uses inverse
        parabolic interpolation when possible to speed up convergence of
        the golden section method.

        Method :ref:`Golden <optimize.minimize_scalar-golden>` uses the
        golden section search technique [1]_. It uses analog of the bisection
        method to decrease the bracketed interval. It is usually
        preferable to use the *Brent* method.

        Method :ref:`Bounded <optimize.minimize_scalar-bounded>` can
        perform bounded minimization [2]_ [3]_. It uses the Brent method to find a
        local minimum in the interval x1 < xopt < x2.

        Note that the Brent and Golden methods do not guarantee success unless a
        valid ``bracket`` triple is provided. If a three-point bracket cannot be
        found, consider `scipy.optimize.minimize`. Also, all methods are intended
        only for local minimization. When the function of interest has more than
        one local minimum, consider :ref:`global_optimization`.

        **Custom minimizers**

        It may be useful to pass a custom minimization method, for example
        when using some library frontend to minimize_scalar. You can simply
        pass a callable as the ``method`` parameter.

        The callable is called as ``method(fun, args, **kwargs, **options)``
        where ``kwargs`` corresponds to any other parameters passed to `minimize`
        (such as `bracket`, `tol`, etc.), except the `options` dict, which has
        its contents also passed as `method` parameters pair by pair.  The method
        shall return an `OptimizeResult` object.

        The provided `method` callable must be able to accept (and possibly ignore)
        arbitrary parameters; the set of parameters accepted by `minimize` may
        expand in future versions and then these parameters will be passed to
        the method. You can find an example in the scipy.optimize tutorial.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1] Press, W., S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery.
               Numerical Recipes in C. Cambridge University Press.
        .. [2] Forsythe, G.E., M. A. Malcolm, and C. B. Moler. "Computer Methods
               for Mathematical Computations." Prentice-Hall Series in Automatic
               Computation 259 (1977).
        .. [3] Brent, Richard P. Algorithms for Minimization Without Derivatives.
               Courier Corporation, 2013.

        Examples
        --------
        Consider the problem of minimizing the following function.

        >>> def f(x):
        ...     return (x - 2) * x * (x + 2)**2

        Using the *Brent* method, we find the local minimum as:

        >>> from scipy.optimize import minimize_scalar
        >>> res = minimize_scalar(f)
        >>> res.fun
        -9.9149495908

        The minimizer is:

        >>> res.x
        1.28077640403

        Using the *Bounded* method, we find a local minimum with specified
        bounds as:

        >>> res = minimize_scalar(f, bounds=(-3, -1), method='bounded')
        >>> res.fun  # minimum
        3.28365179850e-13
        >>> res.x  # minimizer
        -2.0000002026

    newton(func, x0, fprime=None, args=(), tol=1.48e-08, maxiter=50, fprime2=None, x1=None, rtol=0.0, full_output=False, disp=True)
        Find a root of a real or complex function using the Newton-Raphson
        (or secant or Halley's) method.

        Find a root of the scalar-valued function `func` given a nearby scalar
        starting point `x0`.
        The Newton-Raphson method is used if the derivative `fprime` of `func`
        is provided, otherwise the secant method is used. If the second order
        derivative `fprime2` of `func` is also provided, then Halley's method is
        used.

        If `x0` is a sequence with more than one item, `newton` returns an array:
        the roots of the function from each (scalar) starting point in `x0`.
        In this case, `func` must be vectorized to return a sequence or array of
        the same shape as its first argument. If `fprime` (`fprime2`) is given,
        then its return must also have the same shape: each element is the first
        (second) derivative of `func` with respect to its only variable evaluated
        at each element of its first argument.

        `newton` is for finding roots of a scalar-valued functions of a single
        variable. For problems involving several variables, see `root`.

        Parameters
        ----------
        func : callable
            The function whose root is wanted. It must be a function of a
            single variable of the form ``f(x,a,b,c...)``, where ``a,b,c...``
            are extra arguments that can be passed in the `args` parameter.
        x0 : float, sequence, or ndarray
            An initial estimate of the root that should be somewhere near the
            actual root. If not scalar, then `func` must be vectorized and return
            a sequence or array of the same shape as its first argument.
        fprime : callable, optional
            The derivative of the function when available and convenient. If it
            is None (default), then the secant method is used.
        args : tuple, optional
            Extra arguments to be used in the function call.
        tol : float, optional
            The allowable error of the root's value. If `func` is complex-valued,
            a larger `tol` is recommended as both the real and imaginary parts
            of `x` contribute to ``|x - x0|``.
        maxiter : int, optional
            Maximum number of iterations.
        fprime2 : callable, optional
            The second order derivative of the function when available and
            convenient. If it is None (default), then the normal Newton-Raphson
            or the secant method is used. If it is not None, then Halley's method
            is used.
        x1 : float, optional
            Another estimate of the root that should be somewhere near the
            actual root. Used if `fprime` is not provided.
        rtol : float, optional
            Tolerance (relative) for termination.
        full_output : bool, optional
            If `full_output` is False (default), the root is returned.
            If True and `x0` is scalar, the return value is ``(x, r)``, where ``x``
            is the root and ``r`` is a `RootResults` object.
            If True and `x0` is non-scalar, the return value is ``(x, converged,
            zero_der)`` (see Returns section for details).
        disp : bool, optional
            If True, raise a RuntimeError if the algorithm didn't converge, with
            the error message containing the number of iterations and current
            function value. Otherwise, the convergence status is recorded in a
            `RootResults` return object.
            Ignored if `x0` is not scalar.
            *Note: this has little to do with displaying, however,
            the `disp` keyword cannot be renamed for backwards compatibility.*

        Returns
        -------
        root : float, sequence, or ndarray
            Estimated location where function is zero.
        r : `RootResults`, optional
            Present if ``full_output=True`` and `x0` is scalar.
            Object containing information about the convergence. In particular,
            ``r.converged`` is True if the routine converged.
        converged : ndarray of bool, optional
            Present if ``full_output=True`` and `x0` is non-scalar.
            For vector functions, indicates which elements converged successfully.
        zero_der : ndarray of bool, optional
            Present if ``full_output=True`` and `x0` is non-scalar.
            For vector functions, indicates which elements had a zero derivative.

        See Also
        --------
        root_scalar : interface to root solvers for scalar functions
        root : interface to root solvers for multi-input, multi-output functions

        Notes
        -----
        The convergence rate of the Newton-Raphson method is quadratic,
        the Halley method is cubic, and the secant method is
        sub-quadratic. This means that if the function is well-behaved
        the actual error in the estimated root after the nth iteration
        is approximately the square (cube for Halley) of the error
        after the (n-1)th step. However, the stopping criterion used
        here is the step size and there is no guarantee that a root
        has been found. Consequently, the result should be verified.
        Safer algorithms are brentq, brenth, ridder, and bisect,
        but they all require that the root first be bracketed in an
        interval where the function changes sign. The brentq algorithm
        is recommended for general use in one dimensional problems
        when such an interval has been found.

        When `newton` is used with arrays, it is best suited for the following
        types of problems:

        * The initial guesses, `x0`, are all relatively the same distance from
          the roots.
        * Some or all of the extra arguments, `args`, are also arrays so that a
          class of similar problems can be solved together.
        * The size of the initial guesses, `x0`, is larger than O(100) elements.
          Otherwise, a naive loop may perform as well or better than a vector.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import optimize

        >>> def f(x):
        ...     return (x**3 - 1)  # only one real root at x = 1

        ``fprime`` is not provided, use the secant method:

        >>> root = optimize.newton(f, 1.5)
        >>> root
        1.0000000000000016
        >>> root = optimize.newton(f, 1.5, fprime2=lambda x: 6 * x)
        >>> root
        1.0000000000000016

        Only ``fprime`` is provided, use the Newton-Raphson method:

        >>> root = optimize.newton(f, 1.5, fprime=lambda x: 3 * x**2)
        >>> root
        1.0

        Both ``fprime2`` and ``fprime`` are provided, use Halley's method:

        >>> root = optimize.newton(f, 1.5, fprime=lambda x: 3 * x**2,
        ...                        fprime2=lambda x: 6 * x)
        >>> root
        1.0

        When we want to find roots for a set of related starting values and/or
        function parameters, we can provide both of those as an array of inputs:

        >>> f = lambda x, a: x**3 - a
        >>> fder = lambda x, a: 3 * x**2
        >>> rng = np.random.default_rng()
        >>> x = rng.standard_normal(100)
        >>> a = np.arange(-50, 50)
        >>> vec_res = optimize.newton(f, x, fprime=fder, args=(a, ), maxiter=200)

        The above is the equivalent of solving for each value in ``(x, a)``
        separately in a for-loop, just faster:

        >>> loop_res = [optimize.newton(f, x0, fprime=fder, args=(a0,),
        ...                             maxiter=200)
        ...             for x0, a0 in zip(x, a)]
        >>> np.allclose(vec_res, loop_res)
        True

        Plot the results found for all values of ``a``:

        >>> analytical_result = np.sign(a) * np.abs(a)**(1/3)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(a, analytical_result, 'o')
        >>> ax.plot(a, vec_res, '.')
        >>> ax.set_xlabel('$a$')
        >>> ax.set_ylabel('$x$ where $f(x, a)=0$')
        >>> plt.show()

    newton_krylov(F, xin, iter=None, rdiff=None, method='lgmres', inner_maxiter=20, inner_M=None, outer_k=10, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)
        Find a root of a function, using Krylov approximation for inverse Jacobian.

        This method is suitable for solving large-scale problems.

        Parameters
        ----------
        F : function(x) -> f
            Function whose root to find; should take and return an array-like
            object.
        xin : array_like
            Initial guess for the solution
        rdiff : float, optional
            Relative step size to use in numerical differentiation.
        method : str or callable, optional
            Krylov method to use to approximate the Jacobian.  Can be a string,
            or a function implementing the same interface as the iterative
            solvers in `scipy.sparse.linalg`. If a string, needs to be one of:
            ``'lgmres'``, ``'gmres'``, ``'bicgstab'``, ``'cgs'``, ``'minres'``,
            ``'tfqmr'``.

            The default is `scipy.sparse.linalg.lgmres`.
        inner_maxiter : int, optional
            Parameter to pass to the "inner" Krylov solver: maximum number of
            iterations. Iteration will stop after maxiter steps even if the
            specified tolerance has not been achieved.
        inner_M : LinearOperator or InverseJacobian
            Preconditioner for the inner Krylov iteration.
            Note that you can use also inverse Jacobians as (adaptive)
            preconditioners. For example,

            >>> from scipy.optimize import BroydenFirst, KrylovJacobian
            >>> from scipy.optimize import InverseJacobian
            >>> jac = BroydenFirst()
            >>> kjac = KrylovJacobian(inner_M=InverseJacobian(jac))

            If the preconditioner has a method named 'update', it will be called
            as ``update(x, f)`` after each nonlinear step, with ``x`` giving
            the current point, and ``f`` the current function value.
        outer_k : int, optional
            Size of the subspace kept across LGMRES nonlinear iterations.
            See `scipy.sparse.linalg.lgmres` for details.
        inner_kwargs : kwargs
            Keyword parameters for the "inner" Krylov solver
            (defined with `method`). Parameter names must start with
            the `inner_` prefix which will be stripped before passing on
            the inner method. See, e.g., `scipy.sparse.linalg.gmres` for details.
        iter : int, optional
            Number of iterations to make. If omitted (default), make as many
            as required to meet tolerances.
        verbose : bool, optional
            Print status to stdout on every iteration.
        maxiter : int, optional
            Maximum number of iterations to make. If more are needed to
            meet convergence, `NoConvergence` is raised.
        f_tol : float, optional
            Absolute tolerance (in max-norm) for the residual.
            If omitted, default is 6e-6.
        f_rtol : float, optional
            Relative tolerance for the residual. If omitted, not used.
        x_tol : float, optional
            Absolute minimum step size, as determined from the Jacobian
            approximation. If the step size is smaller than this, optimization
            is terminated as successful. If omitted, not used.
        x_rtol : float, optional
            Relative minimum step size. If omitted, not used.
        tol_norm : function(vector) -> scalar, optional
            Norm to use in convergence check. Default is the maximum norm.
        line_search : {None, 'armijo' (default), 'wolfe'}, optional
            Which type of a line search to use to determine the step size in the
            direction given by the Jacobian approximation. Defaults to 'armijo'.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual.

        Returns
        -------
        sol : ndarray
            An array (of similar array type as `x0`) containing the final solution.

        Raises
        ------
        NoConvergence
            When a solution was not found.

        See Also
        --------
        root : Interface to root finding algorithms for multivariate
               functions. See ``method='krylov'`` in particular.
        scipy.sparse.linalg.gmres
        scipy.sparse.linalg.lgmres

        Notes
        -----
        This function implements a Newton-Krylov solver. The basic idea is
        to compute the inverse of the Jacobian with an iterative Krylov
        method. These methods require only evaluating the Jacobian-vector
        products, which are conveniently approximated by a finite difference:

        .. math:: J v \approx (f(x + \omega*v/|v|) - f(x)) / \omega

        Due to the use of iterative matrix inverses, these methods can
        deal with large nonlinear problems.

        SciPy's `scipy.sparse.linalg` module offers a selection of Krylov
        solvers to choose from. The default here is `lgmres`, which is a
        variant of restarted GMRES iteration that reuses some of the
        information obtained in the previous Newton steps to invert
        Jacobians in subsequent steps.

        For a review on Newton-Krylov methods, see for example [1]_,
        and for the LGMRES sparse inverse method, see [2]_.

        References
        ----------
        .. [1] C. T. Kelley, Solving Nonlinear Equations with Newton's Method,
               SIAM, pp.57-83, 2003.
               :doi:`10.1137/1.9780898718898.ch3`
        .. [2] D.A. Knoll and D.E. Keyes, J. Comp. Phys. 193, 357 (2004).
               :doi:`10.1016/j.jcp.2003.08.010`
        .. [3] A.H. Baker and E.R. Jessup and T. Manteuffel,
               SIAM J. Matrix Anal. Appl. 26, 962 (2005).
               :doi:`10.1137/S0895479803422014`

        Examples
        --------
        The following functions define a system of nonlinear equations

        >>> def fun(x):
        ...     return [x[0] + 0.5 * x[1] - 1.0,
        ...             0.5 * (x[1] - x[0]) ** 2]

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.newton_krylov(fun, [0, 0])
        >>> sol
        array([0.66731771, 0.66536458])

    nnls(A, b, maxiter=None, *, atol=None)
        Solve ``argmin_x || Ax - b ||_2`` for ``x>=0``.

        This problem, often called as NonNegative Least Squares, is a convex
        optimization problem with convex constraints. It typically arises when
        the ``x`` models quantities for which only nonnegative values are
        attainable; weight of ingredients, component costs and so on.

        Parameters
        ----------
        A : (m, n) ndarray
            Coefficient array
        b : (m,) ndarray, float
            Right-hand side vector.
        maxiter: int, optional
            Maximum number of iterations, optional. Default value is ``3 * n``.
        atol: float
            Tolerance value used in the algorithm to assess closeness to zero in
            the projected residual ``(A.T @ (A x - b)`` entries. Increasing this
            value relaxes the solution constraints. A typical relaxation value can
            be selected as ``max(m, n) * np.linalg.norm(a, 1) * np.spacing(1.)``.
            This value is not set as default since the norm operation becomes
            expensive for large problems hence can be used only when necessary.

        Returns
        -------
        x : ndarray
            Solution vector.
        rnorm : float
            The 2-norm of the residual, ``|| Ax-b ||_2``.

        See Also
        --------
        lsq_linear : Linear least squares with bounds on the variables

        Notes
        -----
        The code is based on [2]_ which is an improved version of the classical
        algorithm of [1]_. It utilizes an active set method and solves the KKT
        (Karush-Kuhn-Tucker) conditions for the non-negative least squares problem.

        References
        ----------
        .. [1] : Lawson C., Hanson R.J., "Solving Least Squares Problems", SIAM,
           1995, :doi:`10.1137/1.9781611971217`
        .. [2] : Bro, Rasmus and de Jong, Sijmen, "A Fast Non-Negativity-
           Constrained Least Squares Algorithm", Journal Of Chemometrics, 1997,
           :doi:`10.1002/(SICI)1099-128X(199709/10)11:5<393::AID-CEM483>3.0.CO;2-L`

         Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import nnls
        ...
        >>> A = np.array([[1, 0], [1, 0], [0, 1]])
        >>> b = np.array([2, 1, 1])
        >>> nnls(A, b)
        (array([1.5, 1. ]), 0.7071067811865475)

        >>> b = np.array([-1, -1, -1])
        >>> nnls(A, b)
        (array([0., 0.]), 1.7320508075688772)

    quadratic_assignment(A, B, method='faq', options=None)
        Approximates solution to the quadratic assignment problem and
        the graph matching problem.

        Quadratic assignment solves problems of the following form:

        .. math::

            \min_P & \ {\ \text{trace}(A^T P B P^T)}\\
            \mbox{s.t. } & {P \ \epsilon \ \mathcal{P}}\\

        where :math:`\mathcal{P}` is the set of all permutation matrices,
        and :math:`A` and :math:`B` are square matrices.

        Graph matching tries to *maximize* the same objective function.
        This algorithm can be thought of as finding the alignment of the
        nodes of two graphs that minimizes the number of induced edge
        disagreements, or, in the case of weighted graphs, the sum of squared
        edge weight differences.

        Note that the quadratic assignment problem is NP-hard. The results given
        here are approximations and are not guaranteed to be optimal.


        Parameters
        ----------
        A : 2-D array, square
            The square matrix :math:`A` in the objective function above.

        B : 2-D array, square
            The square matrix :math:`B` in the objective function above.

        method :  str in {'faq', '2opt'} (default: 'faq')
            The algorithm used to solve the problem.
            :ref:`'faq' <optimize.qap-faq>` (default) and
            :ref:`'2opt' <optimize.qap-2opt>` are available.

        options : dict, optional
            A dictionary of solver options. All solvers support the following:

            maximize : bool (default: False)
                Maximizes the objective function if ``True``.

            partial_match : 2-D array of integers, optional (default: None)
                Fixes part of the matching. Also known as a "seed" [2]_.

                Each row of `partial_match` specifies a pair of matched nodes:
                node ``partial_match[i, 0]`` of `A` is matched to node
                ``partial_match[i, 1]`` of `B`. The array has shape ``(m, 2)``,
                where ``m`` is not greater than the number of nodes, :math:`n`.

            rng : {None, int, `numpy.random.Generator`,
                   `numpy.random.RandomState`}, optional

                If `seed` is None (or `np.random`), the `numpy.random.RandomState`
                singleton is used.
                If `seed` is an int, a new ``RandomState`` instance is used,
                seeded with `seed`.
                If `seed` is already a ``Generator`` or ``RandomState`` instance then
                that instance is used.

            For method-specific options, see
            :func:`show_options('quadratic_assignment') <show_options>`.

        Returns
        -------
        res : OptimizeResult
            `OptimizeResult` containing the following fields.

            col_ind : 1-D array
                Column indices corresponding to the best permutation found of the
                nodes of `B`.
            fun : float
                The objective value of the solution.
            nit : int
                The number of iterations performed during optimization.

        Notes
        -----
        The default method :ref:`'faq' <optimize.qap-faq>` uses the Fast
        Approximate QAP algorithm [1]_; it typically offers the best combination of
        speed and accuracy.
        Method :ref:`'2opt' <optimize.qap-2opt>` can be computationally expensive,
        but may be a useful alternative, or it can be used to refine the solution
        returned by another method.

        References
        ----------
        .. [1] J.T. Vogelstein, J.M. Conroy, V. Lyzinski, L.J. Podrazik,
               S.G. Kratzer, E.T. Harley, D.E. Fishkind, R.J. Vogelstein, and
               C.E. Priebe, "Fast approximate quadratic programming for graph
               matching," PLOS one, vol. 10, no. 4, p. e0121002, 2015,
               :doi:`10.1371/journal.pone.0121002`

        .. [2] D. Fishkind, S. Adali, H. Patsolic, L. Meng, D. Singh, V. Lyzinski,
               C. Priebe, "Seeded graph matching", Pattern Recognit. 87 (2019):
               203-215, :doi:`10.1016/j.patcog.2018.09.014`

        .. [3] "2-opt," Wikipedia.
               https://en.wikipedia.org/wiki/2-opt

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import quadratic_assignment
        >>> A = np.array([[0, 80, 150, 170], [80, 0, 130, 100],
        ...               [150, 130, 0, 120], [170, 100, 120, 0]])
        >>> B = np.array([[0, 5, 2, 7], [0, 0, 3, 8],
        ...               [0, 0, 0, 3], [0, 0, 0, 0]])
        >>> res = quadratic_assignment(A, B)
        >>> print(res)
             fun: 3260
         col_ind: [0 3 2 1]
             nit: 9

        The see the relationship between the returned ``col_ind`` and ``fun``,
        use ``col_ind`` to form the best permutation matrix found, then evaluate
        the objective function :math:`f(P) = trace(A^T P B P^T )`.

        >>> perm = res['col_ind']
        >>> P = np.eye(len(A), dtype=int)[perm]
        >>> fun = np.trace(A.T @ P @ B @ P.T)
        >>> print(fun)
        3260

        Alternatively, to avoid constructing the permutation matrix explicitly,
        directly permute the rows and columns of the distance matrix.

        >>> fun = np.trace(A.T @ B[perm][:, perm])
        >>> print(fun)
        3260

        Although not guaranteed in general, ``quadratic_assignment`` happens to
        have found the globally optimal solution.

        >>> from itertools import permutations
        >>> perm_opt, fun_opt = None, np.inf
        >>> for perm in permutations([0, 1, 2, 3]):
        ...     perm = np.array(perm)
        ...     fun = np.trace(A.T @ B[perm][:, perm])
        ...     if fun < fun_opt:
        ...         fun_opt, perm_opt = fun, perm
        >>> print(np.array_equal(perm_opt, res['col_ind']))
        True

        Here is an example for which the default method,
        :ref:`'faq' <optimize.qap-faq>`, does not find the global optimum.

        >>> A = np.array([[0, 5, 8, 6], [5, 0, 5, 1],
        ...               [8, 5, 0, 2], [6, 1, 2, 0]])
        >>> B = np.array([[0, 1, 8, 4], [1, 0, 5, 2],
        ...               [8, 5, 0, 5], [4, 2, 5, 0]])
        >>> res = quadratic_assignment(A, B)
        >>> print(res)
             fun: 178
         col_ind: [1 0 3 2]
             nit: 13

        If accuracy is important, consider using  :ref:`'2opt' <optimize.qap-2opt>`
        to refine the solution.

        >>> guess = np.array([np.arange(len(A)), res.col_ind]).T
        >>> res = quadratic_assignment(A, B, method="2opt",
        ...                            options = {'partial_guess': guess})
        >>> print(res)
             fun: 176
         col_ind: [1 2 3 0]
             nit: 17

    ridder(f, a, b, args=(), xtol=2e-12, rtol=np.float64(8.881784197001252e-16), maxiter=100, full_output=False, disp=True)
        Find a root of a function in an interval using Ridder's method.

        Parameters
        ----------
        f : function
            Python function returning a number. f must be continuous, and f(a) and
            f(b) must have opposite signs.
        a : scalar
            One end of the bracketing interval [a,b].
        b : scalar
            The other end of the bracketing interval [a,b].
        xtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter must be positive.
        rtol : number, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter cannot be smaller than its default value of
            ``4*np.finfo(float).eps``.
        maxiter : int, optional
            If convergence is not achieved in `maxiter` iterations, an error is
            raised. Must be >= 0.
        args : tuple, optional
            Containing extra arguments for the function `f`.
            `f` is called by ``apply(f, (x)+args)``.
        full_output : bool, optional
            If `full_output` is False, the root is returned. If `full_output` is
            True, the return value is ``(x, r)``, where `x` is the root, and `r` is
            a `RootResults` object.
        disp : bool, optional
            If True, raise RuntimeError if the algorithm didn't converge.
            Otherwise, the convergence status is recorded in any `RootResults`
            return object.

        Returns
        -------
        root : float
            Root of `f` between `a` and `b`.
        r : `RootResults` (present if ``full_output = True``)
            Object containing information about the convergence.
            In particular, ``r.converged`` is True if the routine converged.

        See Also
        --------
        brentq, brenth, bisect, newton : 1-D root-finding
        fixed_point : scalar fixed-point finder

        Notes
        -----
        Uses [Ridders1979]_ method to find a root of the function `f` between the
        arguments `a` and `b`. Ridders' method is faster than bisection, but not
        generally as fast as the Brent routines. [Ridders1979]_ provides the
        classic description and source of the algorithm. A description can also be
        found in any recent edition of Numerical Recipes.

        The routine used here diverges slightly from standard presentations in
        order to be a bit more careful of tolerance.

        References
        ----------
        .. [Ridders1979]
           Ridders, C. F. J. "A New Algorithm for Computing a
           Single Root of a Real Continuous Function."
           IEEE Trans. Circuits Systems 26, 979-980, 1979.

        Examples
        --------

        >>> def f(x):
        ...     return (x**2 - 1)

        >>> from scipy import optimize

        >>> root = optimize.ridder(f, 0, 2)
        >>> root
        1.0

        >>> root = optimize.ridder(f, -2, 0)
        >>> root
        -1.0

    root(fun, x0, args=(), method='hybr', jac=None, tol=None, callback=None, options=None)
        Find a root of a vector function.

        Parameters
        ----------
        fun : callable
            A vector function to find a root of.
        x0 : ndarray
            Initial guess.
        args : tuple, optional
            Extra arguments passed to the objective function and its Jacobian.
        method : str, optional
            Type of solver. Should be one of

                - 'hybr'             :ref:`(see here) <optimize.root-hybr>`
                - 'lm'               :ref:`(see here) <optimize.root-lm>`
                - 'broyden1'         :ref:`(see here) <optimize.root-broyden1>`
                - 'broyden2'         :ref:`(see here) <optimize.root-broyden2>`
                - 'anderson'         :ref:`(see here) <optimize.root-anderson>`
                - 'linearmixing'     :ref:`(see here) <optimize.root-linearmixing>`
                - 'diagbroyden'      :ref:`(see here) <optimize.root-diagbroyden>`
                - 'excitingmixing'   :ref:`(see here) <optimize.root-excitingmixing>`
                - 'krylov'           :ref:`(see here) <optimize.root-krylov>`
                - 'df-sane'          :ref:`(see here) <optimize.root-dfsane>`

        jac : bool or callable, optional
            If `jac` is a Boolean and is True, `fun` is assumed to return the
            value of Jacobian along with the objective function. If False, the
            Jacobian will be estimated numerically.
            `jac` can also be a callable returning the Jacobian of `fun`. In
            this case, it must accept the same arguments as `fun`.
        tol : float, optional
            Tolerance for termination. For detailed control, use solver-specific
            options.
        callback : function, optional
            Optional callback function. It is called on every iteration as
            ``callback(x, f)`` where `x` is the current solution and `f`
            the corresponding residual. For all methods but 'hybr' and 'lm'.
        options : dict, optional
            A dictionary of solver options. E.g., `xtol` or `maxiter`, see
            :obj:`show_options()` for details.

        Returns
        -------
        sol : OptimizeResult
            The solution represented as a ``OptimizeResult`` object.
            Important attributes are: ``x`` the solution array, ``success`` a
            Boolean flag indicating if the algorithm exited successfully and
            ``message`` which describes the cause of the termination. See
            `OptimizeResult` for a description of other attributes.

        See also
        --------
        show_options : Additional options accepted by the solvers

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter. The default method is *hybr*.

        Method *hybr* uses a modification of the Powell hybrid method as
        implemented in MINPACK [1]_.

        Method *lm* solves the system of nonlinear equations in a least squares
        sense using a modification of the Levenberg-Marquardt algorithm as
        implemented in MINPACK [1]_.

        Method *df-sane* is a derivative-free spectral method. [3]_

        Methods *broyden1*, *broyden2*, *anderson*, *linearmixing*,
        *diagbroyden*, *excitingmixing*, *krylov* are inexact Newton methods,
        with backtracking or full line searches [2]_. Each method corresponds
        to a particular Jacobian approximations.

        - Method *broyden1* uses Broyden's first Jacobian approximation, it is
          known as Broyden's good method.
        - Method *broyden2* uses Broyden's second Jacobian approximation, it
          is known as Broyden's bad method.
        - Method *anderson* uses (extended) Anderson mixing.
        - Method *Krylov* uses Krylov approximation for inverse Jacobian. It
          is suitable for large-scale problem.
        - Method *diagbroyden* uses diagonal Broyden Jacobian approximation.
        - Method *linearmixing* uses a scalar Jacobian approximation.
        - Method *excitingmixing* uses a tuned diagonal Jacobian
          approximation.

        .. warning::

            The algorithms implemented for methods *diagbroyden*,
            *linearmixing* and *excitingmixing* may be useful for specific
            problems, but whether they will work may depend strongly on the
            problem.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1] More, Jorge J., Burton S. Garbow, and Kenneth E. Hillstrom.
           1980. User Guide for MINPACK-1.
        .. [2] C. T. Kelley. 1995. Iterative Methods for Linear and Nonlinear
           Equations. Society for Industrial and Applied Mathematics.
           <https://archive.siam.org/books/kelley/fr16/>
        .. [3] W. La Cruz, J.M. Martinez, M. Raydan. Math. Comp. 75, 1429 (2006).

        Examples
        --------
        The following functions define a system of nonlinear equations and its
        jacobian.

        >>> import numpy as np
        >>> def fun(x):
        ...     return [x[0]  + 0.5 * (x[0] - x[1])**3 - 1.0,
        ...             0.5 * (x[1] - x[0])**3 + x[1]]

        >>> def jac(x):
        ...     return np.array([[1 + 1.5 * (x[0] - x[1])**2,
        ...                       -1.5 * (x[0] - x[1])**2],
        ...                      [-1.5 * (x[1] - x[0])**2,
        ...                       1 + 1.5 * (x[1] - x[0])**2]])

        A solution can be obtained as follows.

        >>> from scipy import optimize
        >>> sol = optimize.root(fun, [0, 0], jac=jac, method='hybr')
        >>> sol.x
        array([ 0.8411639,  0.1588361])

        **Large problem**

        Suppose that we needed to solve the following integrodifferential
        equation on the square :math:`[0,1]\times[0,1]`:

        .. math::

           \nabla^2 P = 10 \left(\int_0^1\int_0^1\cosh(P)\,dx\,dy\right)^2

        with :math:`P(x,1) = 1` and :math:`P=0` elsewhere on the boundary of
        the square.

        The solution can be found using the ``method='krylov'`` solver:

        >>> from scipy import optimize
        >>> # parameters
        >>> nx, ny = 75, 75
        >>> hx, hy = 1./(nx-1), 1./(ny-1)

        >>> P_left, P_right = 0, 0
        >>> P_top, P_bottom = 1, 0

        >>> def residual(P):
        ...    d2x = np.zeros_like(P)
        ...    d2y = np.zeros_like(P)
        ...
        ...    d2x[1:-1] = (P[2:]   - 2*P[1:-1] + P[:-2]) / hx/hx
        ...    d2x[0]    = (P[1]    - 2*P[0]    + P_left)/hx/hx
        ...    d2x[-1]   = (P_right - 2*P[-1]   + P[-2])/hx/hx
        ...
        ...    d2y[:,1:-1] = (P[:,2:] - 2*P[:,1:-1] + P[:,:-2])/hy/hy
        ...    d2y[:,0]    = (P[:,1]  - 2*P[:,0]    + P_bottom)/hy/hy
        ...    d2y[:,-1]   = (P_top   - 2*P[:,-1]   + P[:,-2])/hy/hy
        ...
        ...    return d2x + d2y - 10*np.cosh(P).mean()**2

        >>> guess = np.zeros((nx, ny), float)
        >>> sol = optimize.root(residual, guess, method='krylov')
        >>> print('Residual: %g' % abs(residual(sol.x)).max())
        Residual: 5.7972e-06  # may vary

        >>> import matplotlib.pyplot as plt
        >>> x, y = np.mgrid[0:1:(nx*1j), 0:1:(ny*1j)]
        >>> plt.pcolormesh(x, y, sol.x, shading='gouraud')
        >>> plt.colorbar()
        >>> plt.show()

    root_scalar(f, args=(), method=None, bracket=None, fprime=None, fprime2=None, x0=None, x1=None, xtol=None, rtol=None, maxiter=None, options=None)
        Find a root of a scalar function.

        Parameters
        ----------
        f : callable
            A function to find a root of.
        args : tuple, optional
            Extra arguments passed to the objective function and its derivative(s).
        method : str, optional
            Type of solver.  Should be one of

                - 'bisect'    :ref:`(see here) <optimize.root_scalar-bisect>`
                - 'brentq'    :ref:`(see here) <optimize.root_scalar-brentq>`
                - 'brenth'    :ref:`(see here) <optimize.root_scalar-brenth>`
                - 'ridder'    :ref:`(see here) <optimize.root_scalar-ridder>`
                - 'toms748'    :ref:`(see here) <optimize.root_scalar-toms748>`
                - 'newton'    :ref:`(see here) <optimize.root_scalar-newton>`
                - 'secant'    :ref:`(see here) <optimize.root_scalar-secant>`
                - 'halley'    :ref:`(see here) <optimize.root_scalar-halley>`

        bracket: A sequence of 2 floats, optional
            An interval bracketing a root.  `f(x, *args)` must have different
            signs at the two endpoints.
        x0 : float, optional
            Initial guess.
        x1 : float, optional
            A second guess.
        fprime : bool or callable, optional
            If `fprime` is a boolean and is True, `f` is assumed to return the
            value of the objective function and of the derivative.
            `fprime` can also be a callable returning the derivative of `f`. In
            this case, it must accept the same arguments as `f`.
        fprime2 : bool or callable, optional
            If `fprime2` is a boolean and is True, `f` is assumed to return the
            value of the objective function and of the
            first and second derivatives.
            `fprime2` can also be a callable returning the second derivative of `f`.
            In this case, it must accept the same arguments as `f`.
        xtol : float, optional
            Tolerance (absolute) for termination.
        rtol : float, optional
            Tolerance (relative) for termination.
        maxiter : int, optional
            Maximum number of iterations.
        options : dict, optional
            A dictionary of solver options. E.g., ``k``, see
            :obj:`show_options()` for details.

        Returns
        -------
        sol : RootResults
            The solution represented as a ``RootResults`` object.
            Important attributes are: ``root`` the solution , ``converged`` a
            boolean flag indicating if the algorithm exited successfully and
            ``flag`` which describes the cause of the termination. See
            `RootResults` for a description of other attributes.

        See also
        --------
        show_options : Additional options accepted by the solvers
        root : Find a root of a vector function.

        Notes
        -----
        This section describes the available solvers that can be selected by the
        'method' parameter.

        The default is to use the best method available for the situation
        presented.
        If a bracket is provided, it may use one of the bracketing methods.
        If a derivative and an initial value are specified, it may
        select one of the derivative-based methods.
        If no method is judged applicable, it will raise an Exception.

        Arguments for each method are as follows (x=required, o=optional).

        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        |                    method                     | f | args | bracket | x0 | x1 | fprime | fprime2 | xtol | rtol | maxiter | options |
        +===============================================+===+======+=========+====+====+========+=========+======+======+=========+=========+
        | :ref:`bisect <optimize.root_scalar-bisect>`   | x |  o   |    x    |    |    |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`brentq <optimize.root_scalar-brentq>`   | x |  o   |    x    |    |    |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`brenth <optimize.root_scalar-brenth>`   | x |  o   |    x    |    |    |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`ridder <optimize.root_scalar-ridder>`   | x |  o   |    x    |    |    |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`toms748 <optimize.root_scalar-toms748>` | x |  o   |    x    |    |    |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`secant <optimize.root_scalar-secant>`   | x |  o   |         | x  | o  |        |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`newton <optimize.root_scalar-newton>`   | x |  o   |         | x  |    |   o    |         |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+
        | :ref:`halley <optimize.root_scalar-halley>`   | x |  o   |         | x  |    |   x    |    x    |  o   |  o   |    o    |   o     |
        +-----------------------------------------------+---+------+---------+----+----+--------+---------+------+------+---------+---------+

        Examples
        --------

        Find the root of a simple cubic

        >>> from scipy import optimize
        >>> def f(x):
        ...     return (x**3 - 1)  # only one real root at x = 1

        >>> def fprime(x):
        ...     return 3*x**2

        The `brentq` method takes as input a bracket

        >>> sol = optimize.root_scalar(f, bracket=[0, 3], method='brentq')
        >>> sol.root, sol.iterations, sol.function_calls
        (1.0, 10, 11)

        The `newton` method takes as input a single point and uses the
        derivative(s).

        >>> sol = optimize.root_scalar(f, x0=0.2, fprime=fprime, method='newton')
        >>> sol.root, sol.iterations, sol.function_calls
        (1.0, 11, 22)

        The function can provide the value and derivative(s) in a single call.

        >>> def f_p_pp(x):
        ...     return (x**3 - 1), 3*x**2, 6*x

        >>> sol = optimize.root_scalar(
        ...     f_p_pp, x0=0.2, fprime=True, method='newton'
        ... )
        >>> sol.root, sol.iterations, sol.function_calls
        (1.0, 11, 11)

        >>> sol = optimize.root_scalar(
        ...     f_p_pp, x0=0.2, fprime=True, fprime2=True, method='halley'
        ... )
        >>> sol.root, sol.iterations, sol.function_calls
        (1.0, 7, 8)

    rosen(x)
        The Rosenbrock function.

        The function computed is::

            sum(100.0*(x[1:] - x[:-1]**2.0)**2.0 + (1 - x[:-1])**2.0)

        Parameters
        ----------
        x : array_like
            1-D array of points at which the Rosenbrock function is to be computed.

        Returns
        -------
        f : float
            The value of the Rosenbrock function.

        See Also
        --------
        rosen_der, rosen_hess, rosen_hess_prod

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import rosen
        >>> X = 0.1 * np.arange(10)
        >>> rosen(X)
        76.56

        For higher-dimensional input ``rosen`` broadcasts.
        In the following example, we use this to plot a 2D landscape.
        Note that ``rosen_hess`` does not broadcast in this manner.

        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.mplot3d import Axes3D
        >>> x = np.linspace(-1, 1, 50)
        >>> X, Y = np.meshgrid(x, x)
        >>> ax = plt.subplot(111, projection='3d')
        >>> ax.plot_surface(X, Y, rosen([X, Y]))
        >>> plt.show()

    rosen_der(x)
        The derivative (i.e. gradient) of the Rosenbrock function.

        Parameters
        ----------
        x : array_like
            1-D array of points at which the derivative is to be computed.

        Returns
        -------
        rosen_der : (N,) ndarray
            The gradient of the Rosenbrock function at `x`.

        See Also
        --------
        rosen, rosen_hess, rosen_hess_prod

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import rosen_der
        >>> X = 0.1 * np.arange(9)
        >>> rosen_der(X)
        array([ -2. ,  10.6,  15.6,  13.4,   6.4,  -3. , -12.4, -19.4,  62. ])

    rosen_hess(x)
        The Hessian matrix of the Rosenbrock function.

        Parameters
        ----------
        x : array_like
            1-D array of points at which the Hessian matrix is to be computed.

        Returns
        -------
        rosen_hess : ndarray
            The Hessian matrix of the Rosenbrock function at `x`.

        See Also
        --------
        rosen, rosen_der, rosen_hess_prod

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import rosen_hess
        >>> X = 0.1 * np.arange(4)
        >>> rosen_hess(X)
        array([[-38.,   0.,   0.,   0.],
               [  0., 134., -40.,   0.],
               [  0., -40., 130., -80.],
               [  0.,   0., -80., 200.]])

    rosen_hess_prod(x, p)
        Product of the Hessian matrix of the Rosenbrock function with a vector.

        Parameters
        ----------
        x : array_like
            1-D array of points at which the Hessian matrix is to be computed.
        p : array_like
            1-D array, the vector to be multiplied by the Hessian matrix.

        Returns
        -------
        rosen_hess_prod : ndarray
            The Hessian matrix of the Rosenbrock function at `x` multiplied
            by the vector `p`.

        See Also
        --------
        rosen, rosen_der, rosen_hess

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.optimize import rosen_hess_prod
        >>> X = 0.1 * np.arange(9)
        >>> p = 0.5 * np.arange(9)
        >>> rosen_hess_prod(X, p)
        array([  -0.,   27.,  -10.,  -95., -192., -265., -278., -195., -180.])

    shgo(func, bounds, args=(), constraints=None, n=100, iters=1, callback=None, minimizer_kwargs=None, options=None, sampling_method='simplicial', *, workers=1)
        Finds the global minimum of a function using SHG optimization.

        SHGO stands for "simplicial homology global optimization".

        Parameters
        ----------
        func : callable
            The objective function to be minimized.  Must be in the form
            ``f(x, *args)``, where ``x`` is the argument in the form of a 1-D array
            and ``args`` is a tuple of any additional fixed parameters needed to
            completely specify the function.
        bounds : sequence or `Bounds`
            Bounds for variables. There are two ways to specify the bounds:

            1. Instance of `Bounds` class.
            2. Sequence of ``(min, max)`` pairs for each element in `x`.

        args : tuple, optional
            Any additional fixed parameters needed to completely specify the
            objective function.
        constraints : {Constraint, dict} or List of {Constraint, dict}, optional
            Constraints definition. Only for COBYLA, COBYQA, SLSQP and trust-constr.
            See the tutorial [5]_ for further details on specifying constraints.

            .. note::

               Only COBYLA, COBYQA, SLSQP, and trust-constr local minimize methods
               currently support constraint arguments. If the ``constraints``
               sequence used in the local optimization problem is not defined in
               ``minimizer_kwargs`` and a constrained method is used then the
               global ``constraints`` will be used.
               (Defining a ``constraints`` sequence in ``minimizer_kwargs``
               means that ``constraints`` will not be added so if equality
               constraints and so forth need to be added then the inequality
               functions in ``constraints`` need to be added to
               ``minimizer_kwargs`` too).
               COBYLA only supports inequality constraints.

            .. versionchanged:: 1.11.0

               ``constraints`` accepts `NonlinearConstraint`, `LinearConstraint`.

        n : int, optional
            Number of sampling points used in the construction of the simplicial
            complex. For the default ``simplicial`` sampling method 2**dim + 1
            sampling points are generated instead of the default `n=100`. For all
            other specified values `n` sampling points are generated. For
            ``sobol``, ``halton`` and other arbitrary `sampling_methods` `n=100` or
            another specified number of sampling points are generated.
        iters : int, optional
            Number of iterations used in the construction of the simplicial
            complex. Default is 1.
        callback : callable, optional
            Called after each iteration, as ``callback(xk)``, where ``xk`` is the
            current parameter vector.
        minimizer_kwargs : dict, optional
            Extra keyword arguments to be passed to the minimizer
            ``scipy.optimize.minimize`` Some important options could be:

                * method : str
                    The minimization method. If not given, chosen to be one of
                    BFGS, L-BFGS-B, SLSQP, depending on whether or not the
                    problem has constraints or bounds.
                * args : tuple
                    Extra arguments passed to the objective function (``func``) and
                    its derivatives (Jacobian, Hessian).
                * options : dict, optional
                    Note that by default the tolerance is specified as
                    ``{ftol: 1e-12}``

        options : dict, optional
            A dictionary of solver options. Many of the options specified for the
            global routine are also passed to the scipy.optimize.minimize routine.
            The options that are also passed to the local routine are marked with
            "(L)".

            Stopping criteria, the algorithm will terminate if any of the specified
            criteria are met. However, the default algorithm does not require any
            to be specified:

            * maxfev : int (L)
                Maximum number of function evaluations in the feasible domain.
                (Note only methods that support this option will terminate
                the routine at precisely exact specified value. Otherwise the
                criterion will only terminate during a global iteration)
            * f_min
                Specify the minimum objective function value, if it is known.
            * f_tol : float
                Precision goal for the value of f in the stopping
                criterion. Note that the global routine will also
                terminate if a sampling point in the global routine is
                within this tolerance.
            * maxiter : int
                Maximum number of iterations to perform.
            * maxev : int
                Maximum number of sampling evaluations to perform (includes
                searching in infeasible points).
            * maxtime : float
                Maximum processing runtime allowed
            * minhgrd : int
                Minimum homology group rank differential. The homology group of the
                objective function is calculated (approximately) during every
                iteration. The rank of this group has a one-to-one correspondence
                with the number of locally convex subdomains in the objective
                function (after adequate sampling points each of these subdomains
                contain a unique global minimum). If the difference in the hgr is 0
                between iterations for ``maxhgrd`` specified iterations the
                algorithm will terminate.

            Objective function knowledge:

            * symmetry : list or bool
                Specify if the objective function contains symmetric variables.
                The search space (and therefore performance) is decreased by up to
                O(n!) times in the fully symmetric case. If `True` is specified
                then all variables will be set symmetric to the first variable.
                Default
                is set to False.

                E.g.  f(x) = (x_1 + x_2 + x_3) + (x_4)**2 + (x_5)**2 + (x_6)**2

                In this equation x_2 and x_3 are symmetric to x_1, while x_5 and
                x_6 are symmetric to x_4, this can be specified to the solver as:

                symmetry = [0,  # Variable 1
                            0,  # symmetric to variable 1
                            0,  # symmetric to variable 1
                            3,  # Variable 4
                            3,  # symmetric to variable 4
                            3,  # symmetric to variable 4
                            ]

            * jac : bool or callable, optional
                Jacobian (gradient) of objective function. Only for CG, BFGS,
                Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg. If ``jac`` is a
                boolean and is True, ``fun`` is assumed to return the gradient
                along with the objective function. If False, the gradient will be
                estimated numerically. ``jac`` can also be a callable returning the
                gradient of the objective. In this case, it must accept the same
                arguments as ``fun``. (Passed to `scipy.optimize.minimize`
                automatically)

            * hess, hessp : callable, optional
                Hessian (matrix of second-order derivatives) of objective function
                or Hessian of objective function times an arbitrary vector p.
                Only for Newton-CG, dogleg, trust-ncg. Only one of ``hessp`` or
                ``hess`` needs to be given. If ``hess`` is provided, then
                ``hessp`` will be ignored. If neither ``hess`` nor ``hessp`` is
                provided, then the Hessian product will be approximated using
                finite differences on ``jac``. ``hessp`` must compute the Hessian
                times an arbitrary vector. (Passed to `scipy.optimize.minimize`
                automatically)

            Algorithm settings:

            * minimize_every_iter : bool
                If True then promising global sampling points will be passed to a
                local minimization routine every iteration. If True then only the
                final minimizer pool will be run. Defaults to True.
            * local_iter : int
                Only evaluate a few of the best minimizer pool candidates every
                iteration. If False all potential points are passed to the local
                minimization routine.
            * infty_constraints : bool
                If True then any sampling points generated which are outside will
                the feasible domain will be saved and given an objective function
                value of ``inf``. If False then these points will be discarded.
                Using this functionality could lead to higher performance with
                respect to function evaluations before the global minimum is found,
                specifying False will use less memory at the cost of a slight
                decrease in performance. Defaults to True.

            Feedback:

            * disp : bool (L)
                Set to True to print convergence messages.

        sampling_method : str or function, optional
            Current built in sampling method options are ``halton``, ``sobol`` and
            ``simplicial``. The default ``simplicial`` provides
            the theoretical guarantee of convergence to the global minimum in
            finite time. ``halton`` and ``sobol`` method are faster in terms of
            sampling point generation at the cost of the loss of
            guaranteed convergence. It is more appropriate for most "easier"
            problems where the convergence is relatively fast.
            User defined sampling functions must accept two arguments of ``n``
            sampling points of dimension ``dim`` per call and output an array of
            sampling points with shape `n x dim`.

        workers : int or map-like callable, optional
            Sample and run the local serial minimizations in parallel.
            Supply -1 to use all available CPU cores, or an int to use
            that many Processes (uses `multiprocessing.Pool <multiprocessing>`).

            Alternatively supply a map-like callable, such as
            `multiprocessing.Pool.map` for parallel evaluation.
            This evaluation is carried out as ``workers(func, iterable)``.
            Requires that `func` be pickleable.

            .. versionadded:: 1.11.0

        Returns
        -------
        res : OptimizeResult
            The optimization result represented as a `OptimizeResult` object.
            Important attributes are:
            ``x`` the solution array corresponding to the global minimum,
            ``fun`` the function output at the global solution,
            ``xl`` an ordered list of local minima solutions,
            ``funl`` the function output at the corresponding local solutions,
            ``success`` a Boolean flag indicating if the optimizer exited
            successfully,
            ``message`` which describes the cause of the termination,
            ``nfev`` the total number of objective function evaluations including
            the sampling calls,
            ``nlfev`` the total number of objective function evaluations
            culminating from all local search optimizations,
            ``nit`` number of iterations performed by the global routine.

        Notes
        -----
        Global optimization using simplicial homology global optimization [1]_.
        Appropriate for solving general purpose NLP and blackbox optimization
        problems to global optimality (low-dimensional problems).

        In general, the optimization problems are of the form::

            minimize f(x) subject to

            g_i(x) >= 0,  i = 1,...,m
            h_j(x)  = 0,  j = 1,...,p

        where x is a vector of one or more variables. ``f(x)`` is the objective
        function ``R^n -> R``, ``g_i(x)`` are the inequality constraints, and
        ``h_j(x)`` are the equality constraints.

        Optionally, the lower and upper bounds for each element in x can also be
        specified using the `bounds` argument.

        While most of the theoretical advantages of SHGO are only proven for when
        ``f(x)`` is a Lipschitz smooth function, the algorithm is also proven to
        converge to the global optimum for the more general case where ``f(x)`` is
        non-continuous, non-convex and non-smooth, if the default sampling method
        is used [1]_.

        The local search method may be specified using the ``minimizer_kwargs``
        parameter which is passed on to ``scipy.optimize.minimize``. By default,
        the ``SLSQP`` method is used. In general, it is recommended to use the
        ``SLSQP``, ``COBYLA``, or ``COBYQA`` local minimization if inequality
        constraints are defined for the problem since the other methods do not use
        constraints.

        The ``halton`` and ``sobol`` method points are generated using
        `scipy.stats.qmc`. Any other QMC method could be used.

        References
        ----------
        .. [1] Endres, SC, Sandrock, C, Focke, WW (2018) "A simplicial homology
               algorithm for lipschitz optimisation", Journal of Global
               Optimization.
        .. [2] Joe, SW and Kuo, FY (2008) "Constructing Sobol' sequences with
               better  two-dimensional projections", SIAM J. Sci. Comput. 30,
               2635-2654.
        .. [3] Hock, W and Schittkowski, K (1981) "Test examples for nonlinear
               programming codes", Lecture Notes in Economics and Mathematical
               Systems, 187. Springer-Verlag, New York.
               http://www.ai7.uni-bayreuth.de/test_problem_coll.pdf
        .. [4] Wales, DJ (2015) "Perspective: Insight into reaction coordinates and
               dynamics from the potential energy landscape",
               Journal of Chemical Physics, 142(13), 2015.
        .. [5] https://docs.scipy.org/doc/scipy/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize

        Examples
        --------
        First consider the problem of minimizing the Rosenbrock function, `rosen`:

        >>> from scipy.optimize import rosen, shgo
        >>> bounds = [(0,2), (0, 2), (0, 2), (0, 2), (0, 2)]
        >>> result = shgo(rosen, bounds)
        >>> result.x, result.fun
        (array([1., 1., 1., 1., 1.]), 2.920392374190081e-18)

        Note that bounds determine the dimensionality of the objective
        function and is therefore a required input, however you can specify
        empty bounds using ``None`` or objects like ``np.inf`` which will be
        converted to large float numbers.

        >>> bounds = [(None, None), ]*4
        >>> result = shgo(rosen, bounds)
        >>> result.x
        array([0.99999851, 0.99999704, 0.99999411, 0.9999882 ])

        Next, we consider the Eggholder function, a problem with several local
        minima and one global minimum. We will demonstrate the use of arguments and
        the capabilities of `shgo`.
        (https://en.wikipedia.org/wiki/Test_functions_for_optimization)

        >>> import numpy as np
        >>> def eggholder(x):
        ...     return (-(x[1] + 47.0)
        ...             * np.sin(np.sqrt(abs(x[0]/2.0 + (x[1] + 47.0))))
        ...             - x[0] * np.sin(np.sqrt(abs(x[0] - (x[1] + 47.0))))
        ...             )
        ...
        >>> bounds = [(-512, 512), (-512, 512)]

        `shgo` has built-in low discrepancy sampling sequences. First, we will
        input 64 initial sampling points of the *Sobol'* sequence:

        >>> result = shgo(eggholder, bounds, n=64, sampling_method='sobol')
        >>> result.x, result.fun
        (array([512.        , 404.23180824]), -959.6406627208397)

        `shgo` also has a return for any other local minima that was found, these
        can be called using:

        >>> result.xl
        array([[ 512.        ,  404.23180824],
               [ 283.0759062 , -487.12565635],
               [-294.66820039, -462.01964031],
               [-105.87688911,  423.15323845],
               [-242.97926   ,  274.38030925],
               [-506.25823477,    6.3131022 ],
               [-408.71980731, -156.10116949],
               [ 150.23207937,  301.31376595],
               [  91.00920901, -391.283763  ],
               [ 202.89662724, -269.38043241],
               [ 361.66623976, -106.96493868],
               [-219.40612786, -244.06020508]])

        >>> result.funl
        array([-959.64066272, -718.16745962, -704.80659592, -565.99778097,
               -559.78685655, -557.36868733, -507.87385942, -493.9605115 ,
               -426.48799655, -421.15571437, -419.31194957, -410.98477763])

        These results are useful in applications where there are many global minima
        and the values of other global minima are desired or where the local minima
        can provide insight into the system (for example morphologies
        in physical chemistry [4]_).

        If we want to find a larger number of local minima, we can increase the
        number of sampling points or the number of iterations. We'll increase the
        number of sampling points to 64 and the number of iterations from the
        default of 1 to 3. Using ``simplicial`` this would have given us
        64 x 3 = 192 initial sampling points.

        >>> result_2 = shgo(eggholder,
        ...                 bounds, n=64, iters=3, sampling_method='sobol')
        >>> len(result.xl), len(result_2.xl)
        (12, 23)

        Note the difference between, e.g., ``n=192, iters=1`` and ``n=64,
        iters=3``.
        In the first case the promising points contained in the minimiser pool
        are processed only once. In the latter case it is processed every 64
        sampling points for a total of 3 times.

        To demonstrate solving problems with non-linear constraints consider the
        following example from Hock and Schittkowski problem 73 (cattle-feed)
        [3]_::

            minimize: f = 24.55 * x_1 + 26.75 * x_2 + 39 * x_3 + 40.50 * x_4

            subject to: 2.3 * x_1 + 5.6 * x_2 + 11.1 * x_3 + 1.3 * x_4 - 5    >= 0,

                        12 * x_1 + 11.9 * x_2 + 41.8 * x_3 + 52.1 * x_4 - 21
                            -1.645 * sqrt(0.28 * x_1**2 + 0.19 * x_2**2 +
                                          20.5 * x_3**2 + 0.62 * x_4**2)      >= 0,

                        x_1 + x_2 + x_3 + x_4 - 1                             == 0,

                        1 >= x_i >= 0 for all i

        The approximate answer given in [3]_ is::

            f([0.6355216, -0.12e-11, 0.3127019, 0.05177655]) = 29.894378

        >>> def f(x):  # (cattle-feed)
        ...     return 24.55*x[0] + 26.75*x[1] + 39*x[2] + 40.50*x[3]
        ...
        >>> def g1(x):
        ...     return 2.3*x[0] + 5.6*x[1] + 11.1*x[2] + 1.3*x[3] - 5  # >=0
        ...
        >>> def g2(x):
        ...     return (12*x[0] + 11.9*x[1] +41.8*x[2] + 52.1*x[3] - 21
        ...             - 1.645 * np.sqrt(0.28*x[0]**2 + 0.19*x[1]**2
        ...                             + 20.5*x[2]**2 + 0.62*x[3]**2)
        ...             ) # >=0
        ...
        >>> def h1(x):
        ...     return x[0] + x[1] + x[2] + x[3] - 1  # == 0
        ...
        >>> cons = ({'type': 'ineq', 'fun': g1},
        ...         {'type': 'ineq', 'fun': g2},
        ...         {'type': 'eq', 'fun': h1})
        >>> bounds = [(0, 1.0),]*4
        >>> res = shgo(f, bounds, n=150, constraints=cons)
        >>> res
         message: Optimization terminated successfully.
         success: True
             fun: 29.894378159142136
            funl: [ 2.989e+01]
               x: [ 6.355e-01  1.137e-13  3.127e-01  5.178e-02] # may vary
              xl: [[ 6.355e-01  1.137e-13  3.127e-01  5.178e-02]] # may vary
             nit: 1
            nfev: 142 # may vary
           nlfev: 35 # may vary
           nljev: 5
           nlhev: 0

        >>> g1(res.x), g2(res.x), h1(res.x)
        (-5.062616992290714e-14, -2.9594104944408173e-12, 0.0)

    show_options(solver=None, method=None, disp=True)
        Show documentation for additional options of optimization solvers.

        These are method-specific options that can be supplied through the
        ``options`` dict.

        Parameters
        ----------
        solver : str
            Type of optimization solver. One of 'minimize', 'minimize_scalar',
            'root', 'root_scalar', 'linprog', or 'quadratic_assignment'.
        method : str, optional
            If not given, shows all methods of the specified solver. Otherwise,
            show only the options for the specified method. Valid values
            corresponds to methods' names of respective solver (e.g., 'BFGS' for
            'minimize').
        disp : bool, optional
            Whether to print the result rather than returning it.

        Returns
        -------
        text
            Either None (for disp=True) or the text string (disp=False)

        Notes
        -----
        The solver-specific methods are:

        `scipy.optimize.minimize`

        - :ref:`Nelder-Mead <optimize.minimize-neldermead>`
        - :ref:`Powell      <optimize.minimize-powell>`
        - :ref:`CG          <optimize.minimize-cg>`
        - :ref:`BFGS        <optimize.minimize-bfgs>`
        - :ref:`Newton-CG   <optimize.minimize-newtoncg>`
        - :ref:`L-BFGS-B    <optimize.minimize-lbfgsb>`
        - :ref:`TNC         <optimize.minimize-tnc>`
        - :ref:`COBYLA      <optimize.minimize-cobyla>`
        - :ref:`COBYQA      <optimize.minimize-cobyqa>`
        - :ref:`SLSQP       <optimize.minimize-slsqp>`
        - :ref:`dogleg      <optimize.minimize-dogleg>`
        - :ref:`trust-ncg   <optimize.minimize-trustncg>`

        `scipy.optimize.root`

        - :ref:`hybr              <optimize.root-hybr>`
        - :ref:`lm                <optimize.root-lm>`
        - :ref:`broyden1          <optimize.root-broyden1>`
        - :ref:`broyden2          <optimize.root-broyden2>`
        - :ref:`anderson          <optimize.root-anderson>`
        - :ref:`linearmixing      <optimize.root-linearmixing>`
        - :ref:`diagbroyden       <optimize.root-diagbroyden>`
        - :ref:`excitingmixing    <optimize.root-excitingmixing>`
        - :ref:`krylov            <optimize.root-krylov>`
        - :ref:`df-sane           <optimize.root-dfsane>`

        `scipy.optimize.minimize_scalar`

        - :ref:`brent       <optimize.minimize_scalar-brent>`
        - :ref:`golden      <optimize.minimize_scalar-golden>`
        - :ref:`bounded     <optimize.minimize_scalar-bounded>`

        `scipy.optimize.root_scalar`

        - :ref:`bisect  <optimize.root_scalar-bisect>`
        - :ref:`brentq  <optimize.root_scalar-brentq>`
        - :ref:`brenth  <optimize.root_scalar-brenth>`
        - :ref:`ridder  <optimize.root_scalar-ridder>`
        - :ref:`toms748 <optimize.root_scalar-toms748>`
        - :ref:`newton  <optimize.root_scalar-newton>`
        - :ref:`secant  <optimize.root_scalar-secant>`
        - :ref:`halley  <optimize.root_scalar-halley>`

        `scipy.optimize.linprog`

        - :ref:`simplex           <optimize.linprog-simplex>`
        - :ref:`interior-point    <optimize.linprog-interior-point>`
        - :ref:`revised simplex   <optimize.linprog-revised_simplex>`
        - :ref:`highs             <optimize.linprog-highs>`
        - :ref:`highs-ds          <optimize.linprog-highs-ds>`
        - :ref:`highs-ipm         <optimize.linprog-highs-ipm>`

        `scipy.optimize.quadratic_assignment`

        - :ref:`faq             <optimize.qap-faq>`
        - :ref:`2opt            <optimize.qap-2opt>`

        Examples
        --------
        We can print documentations of a solver in stdout:

        >>> from scipy.optimize import show_options
        >>> show_options(solver="minimize")
        ...

        Specifying a method is possible:

        >>> show_options(solver="minimize", method="Nelder-Mead")
        ...

        We can also get the documentations as a string:

        >>> show_options(solver="minimize", method="Nelder-Mead", disp=False)
        Minimization of scalar function of one or more variables using the ...

    toms748(f, a, b, args=(), k=1, xtol=2e-12, rtol=np.float64(8.881784197001252e-16), maxiter=100, full_output=False, disp=True)
        Find a root using TOMS Algorithm 748 method.

        Implements the Algorithm 748 method of Alefeld, Potro and Shi to find a
        root of the function `f` on the interval `[a , b]`, where `f(a)` and
        `f(b)` must have opposite signs.

        It uses a mixture of inverse cubic interpolation and
        "Newton-quadratic" steps. [APS1995].

        Parameters
        ----------
        f : function
            Python function returning a scalar. The function :math:`f`
            must be continuous, and :math:`f(a)` and :math:`f(b)`
            have opposite signs.
        a : scalar,
            lower boundary of the search interval
        b : scalar,
            upper boundary of the search interval
        args : tuple, optional
            containing extra arguments for the function `f`.
            `f` is called by ``f(x, *args)``.
        k : int, optional
            The number of Newton quadratic steps to perform each
            iteration. ``k>=1``.
        xtol : scalar, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
            parameter must be positive.
        rtol : scalar, optional
            The computed root ``x0`` will satisfy ``np.allclose(x, x0,
            atol=xtol, rtol=rtol)``, where ``x`` is the exact root.
        maxiter : int, optional
            If convergence is not achieved in `maxiter` iterations, an error is
            raised. Must be >= 0.
        full_output : bool, optional
            If `full_output` is False, the root is returned. If `full_output` is
            True, the return value is ``(x, r)``, where `x` is the root, and `r` is
            a `RootResults` object.
        disp : bool, optional
            If True, raise RuntimeError if the algorithm didn't converge.
            Otherwise, the convergence status is recorded in the `RootResults`
            return object.

        Returns
        -------
        root : float
            Approximate root of `f`
        r : `RootResults` (present if ``full_output = True``)
            Object containing information about the convergence. In particular,
            ``r.converged`` is True if the routine converged.

        See Also
        --------
        brentq, brenth, ridder, bisect, newton
        fsolve : find roots in N dimensions.

        Notes
        -----
        `f` must be continuous.
        Algorithm 748 with ``k=2`` is asymptotically the most efficient
        algorithm known for finding roots of a four times continuously
        differentiable function.
        In contrast with Brent's algorithm, which may only decrease the length of
        the enclosing bracket on the last step, Algorithm 748 decreases it each
        iteration with the same asymptotic efficiency as it finds the root.

        For easy statement of efficiency indices, assume that `f` has 4
        continuouous deriviatives.
        For ``k=1``, the convergence order is at least 2.7, and with about
        asymptotically 2 function evaluations per iteration, the efficiency
        index is approximately 1.65.
        For ``k=2``, the order is about 4.6 with asymptotically 3 function
        evaluations per iteration, and the efficiency index 1.66.
        For higher values of `k`, the efficiency index approaches
        the kth root of ``(3k-2)``, hence ``k=1`` or ``k=2`` are
        usually appropriate.

        References
        ----------
        .. [APS1995]
           Alefeld, G. E. and Potra, F. A. and Shi, Yixun,
           *Algorithm 748: Enclosing Zeros of Continuous Functions*,
           ACM Trans. Math. Softw. Volume 221(1995)
           doi = {10.1145/210089.210111}

        Examples
        --------
        >>> def f(x):
        ...     return (x**3 - 1)  # only one real root at x = 1

        >>> from scipy import optimize
        >>> root, results = optimize.toms748(f, 0, 2, full_output=True)
        >>> root
        1.0
        >>> results
              converged: True
                   flag: converged
         function_calls: 11
             iterations: 5
                   root: 1.0
                 method: toms748

DATA
    __all__ = ['BFGS', 'Bounds', 'BroydenFirst', 'HessianUpdateStrategy', ...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\optimize\__init__.py

scipy.show_config
Python Library Documentation: function show in module scipy.__config__

show(mode='stdout')
    Show libraries and system information on which SciPy was built
    and is being used

    Parameters
    ----------
    mode : {`'stdout'`, `'dicts'`}, optional.
        Indicates how to display the config information.
        `'stdout'` prints to console, `'dicts'` returns a dictionary
        of the configuration.

    Returns
    -------
    out : {`dict`, `None`}
        If mode is `'dicts'`, a dict is returned, else None

    Notes
    -----
    1. The `'stdout'` mode will give more readable
       output if ``pyyaml`` is installed
scipy.signal
Python Library Documentation: package scipy.signal in scipy

NAME
    scipy.signal

DESCRIPTION
    =======================================
    Signal processing (:mod:`scipy.signal`)
    =======================================

    Convolution
    ===========

    .. autosummary::
       :toctree: generated/

       convolve           -- N-D convolution.
       correlate          -- N-D correlation.
       fftconvolve        -- N-D convolution using the FFT.
       oaconvolve         -- N-D convolution using the overlap-add method.
       convolve2d         -- 2-D convolution (more options).
       correlate2d        -- 2-D correlation (more options).
       sepfir2d           -- Convolve with a 2-D separable FIR filter.
       choose_conv_method -- Chooses faster of FFT and direct convolution methods.
       correlation_lags   -- Determines lag indices for 1D cross-correlation.

    B-splines
    =========

    .. autosummary::
       :toctree: generated/

       gauss_spline   -- Gaussian approximation to the B-spline basis function.
       cspline1d      -- Coefficients for 1-D cubic (3rd order) B-spline.
       qspline1d      -- Coefficients for 1-D quadratic (2nd order) B-spline.
       cspline2d      -- Coefficients for 2-D cubic (3rd order) B-spline.
       qspline2d      -- Coefficients for 2-D quadratic (2nd order) B-spline.
       cspline1d_eval -- Evaluate a cubic spline at the given points.
       qspline1d_eval -- Evaluate a quadratic spline at the given points.
       spline_filter  -- Smoothing spline (cubic) filtering of a rank-2 array.

    Filtering
    =========

    .. autosummary::
       :toctree: generated/

       order_filter  -- N-D order filter.
       medfilt       -- N-D median filter.
       medfilt2d     -- 2-D median filter (faster).
       wiener        -- N-D Wiener filter.

       symiirorder1  -- 2nd-order IIR filter (cascade of first-order systems).
       symiirorder2  -- 4th-order IIR filter (cascade of second-order systems).
       lfilter       -- 1-D FIR and IIR digital linear filtering.
       lfiltic       -- Construct initial conditions for `lfilter`.
       lfilter_zi    -- Compute an initial state zi for the lfilter function that
                     -- corresponds to the steady state of the step response.
       filtfilt      -- A forward-backward filter.
       savgol_filter -- Filter a signal using the Savitzky-Golay filter.

       deconvolve    -- 1-D deconvolution using lfilter.

       sosfilt       -- 1-D IIR digital linear filtering using
                     -- a second-order sections filter representation.
       sosfilt_zi    -- Compute an initial state zi for the sosfilt function that
                     -- corresponds to the steady state of the step response.
       sosfiltfilt   -- A forward-backward filter for second-order sections.
       hilbert       -- Compute 1-D analytic signal, using the Hilbert transform.
       hilbert2      -- Compute 2-D analytic signal, using the Hilbert transform.

       decimate      -- Downsample a signal.
       detrend       -- Remove linear and/or constant trends from data.
       resample      -- Resample using Fourier method.
       resample_poly -- Resample using polyphase filtering method.
       upfirdn       -- Upsample, apply FIR filter, downsample.

    Filter design
    =============

    .. autosummary::
       :toctree: generated/

       bilinear      -- Digital filter from an analog filter using
                        -- the bilinear transform.
       bilinear_zpk  -- Digital filter from an analog filter using
                        -- the bilinear transform.
       findfreqs     -- Find array of frequencies for computing filter response.
       firls         -- FIR filter design using least-squares error minimization.
       firwin        -- Windowed FIR filter design, with frequency response
                        -- defined as pass and stop bands.
       firwin2       -- Windowed FIR filter design, with arbitrary frequency
                        -- response.
       freqs         -- Analog filter frequency response from TF coefficients.
       freqs_zpk     -- Analog filter frequency response from ZPK coefficients.
       freqz         -- Digital filter frequency response from TF coefficients.
       freqz_zpk     -- Digital filter frequency response from ZPK coefficients.
       sosfreqz      -- Digital filter frequency response for SOS format filter.
       gammatone     -- FIR and IIR gammatone filter design.
       group_delay   -- Digital filter group delay.
       iirdesign     -- IIR filter design given bands and gains.
       iirfilter     -- IIR filter design given order and critical frequencies.
       kaiser_atten  -- Compute the attenuation of a Kaiser FIR filter, given
                        -- the number of taps and the transition width at
                        -- discontinuities in the frequency response.
       kaiser_beta   -- Compute the Kaiser parameter beta, given the desired
                        -- FIR filter attenuation.
       kaiserord     -- Design a Kaiser window to limit ripple and width of
                        -- transition region.
       minimum_phase -- Convert a linear phase FIR filter to minimum phase.
       savgol_coeffs -- Compute the FIR filter coefficients for a Savitzky-Golay
                        -- filter.
       remez         -- Optimal FIR filter design.

       unique_roots  -- Unique roots and their multiplicities.
       residue       -- Partial fraction expansion of b(s) / a(s).
       residuez      -- Partial fraction expansion of b(z) / a(z).
       invres        -- Inverse partial fraction expansion for analog filter.
       invresz       -- Inverse partial fraction expansion for digital filter.
       BadCoefficients  -- Warning on badly conditioned filter coefficients.

    Lower-level filter design functions:

    .. autosummary::
       :toctree: generated/

       abcd_normalize -- Check state-space matrices and ensure they are rank-2.
       band_stop_obj  -- Band Stop Objective Function for order minimization.
       besselap       -- Return (z,p,k) for analog prototype of Bessel filter.
       buttap         -- Return (z,p,k) for analog prototype of Butterworth filter.
       cheb1ap        -- Return (z,p,k) for type I Chebyshev filter.
       cheb2ap        -- Return (z,p,k) for type II Chebyshev filter.
       cmplx_sort     -- Sort roots based on magnitude.
       ellipap        -- Return (z,p,k) for analog prototype of elliptic filter.
       lp2bp          -- Transform a lowpass filter prototype to a bandpass filter.
       lp2bp_zpk      -- Transform a lowpass filter prototype to a bandpass filter.
       lp2bs          -- Transform a lowpass filter prototype to a bandstop filter.
       lp2bs_zpk      -- Transform a lowpass filter prototype to a bandstop filter.
       lp2hp          -- Transform a lowpass filter prototype to a highpass filter.
       lp2hp_zpk      -- Transform a lowpass filter prototype to a highpass filter.
       lp2lp          -- Transform a lowpass filter prototype to a lowpass filter.
       lp2lp_zpk      -- Transform a lowpass filter prototype to a lowpass filter.
       normalize      -- Normalize polynomial representation of a transfer function.



    Matlab-style IIR filter design
    ==============================

    .. autosummary::
       :toctree: generated/

       butter -- Butterworth
       buttord
       cheby1 -- Chebyshev Type I
       cheb1ord
       cheby2 -- Chebyshev Type II
       cheb2ord
       ellip -- Elliptic (Cauer)
       ellipord
       bessel -- Bessel (no order selection available -- try butterod)
       iirnotch      -- Design second-order IIR notch digital filter.
       iirpeak       -- Design second-order IIR peak (resonant) digital filter.
       iircomb       -- Design IIR comb filter.

    Continuous-time linear systems
    ==============================

    .. autosummary::
       :toctree: generated/

       lti              -- Continuous-time linear time invariant system base class.
       StateSpace       -- Linear time invariant system in state space form.
       TransferFunction -- Linear time invariant system in transfer function form.
       ZerosPolesGain   -- Linear time invariant system in zeros, poles, gain form.
       lsim             -- Continuous-time simulation of output to linear system.
       impulse          -- Impulse response of linear, time-invariant (LTI) system.
       step             -- Step response of continuous-time LTI system.
       freqresp         -- Frequency response of a continuous-time LTI system.
       bode             -- Bode magnitude and phase data (continuous-time LTI).

    Discrete-time linear systems
    ============================

    .. autosummary::
       :toctree: generated/

       dlti             -- Discrete-time linear time invariant system base class.
       StateSpace       -- Linear time invariant system in state space form.
       TransferFunction -- Linear time invariant system in transfer function form.
       ZerosPolesGain   -- Linear time invariant system in zeros, poles, gain form.
       dlsim            -- Simulation of output to a discrete-time linear system.
       dimpulse         -- Impulse response of a discrete-time LTI system.
       dstep            -- Step response of a discrete-time LTI system.
       dfreqresp        -- Frequency response of a discrete-time LTI system.
       dbode            -- Bode magnitude and phase data (discrete-time LTI).

    LTI representations
    ===================

    .. autosummary::
       :toctree: generated/

       tf2zpk        -- Transfer function to zero-pole-gain.
       tf2sos        -- Transfer function to second-order sections.
       tf2ss         -- Transfer function to state-space.
       zpk2tf        -- Zero-pole-gain to transfer function.
       zpk2sos       -- Zero-pole-gain to second-order sections.
       zpk2ss        -- Zero-pole-gain to state-space.
       ss2tf         -- State-pace to transfer function.
       ss2zpk        -- State-space to pole-zero-gain.
       sos2zpk       -- Second-order sections to zero-pole-gain.
       sos2tf        -- Second-order sections to transfer function.
       cont2discrete -- Continuous-time to discrete-time LTI conversion.
       place_poles   -- Pole placement.

    Waveforms
    =========

    .. autosummary::
       :toctree: generated/

       chirp        -- Frequency swept cosine signal, with several freq functions.
       gausspulse   -- Gaussian modulated sinusoid.
       max_len_seq  -- Maximum length sequence.
       sawtooth     -- Periodic sawtooth.
       square       -- Square wave.
       sweep_poly   -- Frequency swept cosine signal; freq is arbitrary polynomial.
       unit_impulse -- Discrete unit impulse.

    Window functions
    ================

    For window functions, see the `scipy.signal.windows` namespace.

    In the `scipy.signal` namespace, there is a convenience function to
    obtain these windows by name:

    .. autosummary::
       :toctree: generated/

       get_window -- Return a window of a given length and type.

    Wavelets
    ========

    .. autosummary::
       :toctree: generated/

       cascade      -- Compute scaling function and wavelet from coefficients.
       daub         -- Return low-pass.
       morlet       -- Complex Morlet wavelet.
       qmf          -- Return quadrature mirror filter from low-pass.
       ricker       -- Return ricker wavelet.
       morlet2      -- Return Morlet wavelet, compatible with cwt.
       cwt          -- Perform continuous wavelet transform.

    Peak finding
    ============

    .. autosummary::
       :toctree: generated/

       argrelmin        -- Calculate the relative minima of data.
       argrelmax        -- Calculate the relative maxima of data.
       argrelextrema    -- Calculate the relative extrema of data.
       find_peaks       -- Find a subset of peaks inside a signal.
       find_peaks_cwt   -- Find peaks in a 1-D array with wavelet transformation.
       peak_prominences -- Calculate the prominence of each peak in a signal.
       peak_widths      -- Calculate the width of each peak in a signal.

    Spectral analysis
    =================

    .. autosummary::
       :toctree: generated/

       periodogram    -- Compute a (modified) periodogram.
       welch          -- Compute a periodogram using Welch's method.
       csd            -- Compute the cross spectral density, using Welch's method.
       coherence      -- Compute the magnitude squared coherence, using Welch's method.
       spectrogram    -- Compute the spectrogram (legacy).
       lombscargle    -- Computes the Lomb-Scargle periodogram.
       vectorstrength -- Computes the vector strength.
       ShortTimeFFT   -- Interface for calculating the                      :ref:`Short Time Fourier Transform <tutorial_stft>` and                      its inverse.
       stft           -- Compute the Short Time Fourier Transform (legacy).
       istft          -- Compute the Inverse Short Time Fourier Transform (legacy).
       check_COLA     -- Check the COLA constraint for iSTFT reconstruction.
       check_NOLA     -- Check the NOLA constraint for iSTFT reconstruction.

    Chirp Z-transform and Zoom FFT
    ============================================

    .. autosummary::
       :toctree: generated/

       czt - Chirp z-transform convenience function
       zoom_fft - Zoom FFT convenience function
       CZT - Chirp z-transform function generator
       ZoomFFT - Zoom FFT function generator
       czt_points - Output the z-plane points sampled by a chirp z-transform

    The functions are simpler to use than the classes, but are less efficient when
    using the same transform on many arrays of the same length, since they
    repeatedly generate the same chirp signal with every call.  In these cases,
    use the classes to create a reusable function instead.

PACKAGE CONTENTS
    _arraytools
    _bsplines
    _czt
    _filter_design
    _fir_filter_design
    _lti_conversion
    _ltisys
    _max_len_seq
    _max_len_seq_inner
    _peak_finding
    _peak_finding_utils
    _savitzky_golay
    _short_time_fft
    _signaltools
    _sigtools
    _sosfilt
    _spectral
    _spectral_py
    _spline
    _upfirdn
    _upfirdn_apply
    _waveforms
    _wavelets
    bsplines
    filter_design
    fir_filter_design
    lti_conversion
    ltisys
    signaltools
    spectral
    spline
    tests (package)
    waveforms
    wavelets
    windows (package)

CLASSES
    builtins.UserWarning(builtins.Warning)
        scipy.signal._filter_design.BadCoefficients
    builtins.object
        scipy.signal._czt.CZT
            scipy.signal._czt.ZoomFFT
        scipy.signal._short_time_fft.ShortTimeFFT
    scipy.signal._ltisys.LinearTimeInvariant(builtins.object)
        scipy.signal._ltisys.StateSpace
        scipy.signal._ltisys.TransferFunction
        scipy.signal._ltisys.ZerosPolesGain
        scipy.signal._ltisys.dlti
        scipy.signal._ltisys.lti

    class BadCoefficients(builtins.UserWarning)
     |  Warning about badly conditioned filter coefficients
     |
     |  Method resolution order:
     |      BadCoefficients
     |      builtins.UserWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.UserWarning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.UserWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.UserWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class CZT(builtins.object)
     |  CZT(n, m=None, w=None, a=(1+0j))
     |
     |  Create a callable chirp z-transform function.
     |
     |  Transform to compute the frequency response around a spiral.
     |  Objects of this class are callables which can compute the
     |  chirp z-transform on their inputs.  This object precalculates the constant
     |  chirps used in the given transform.
     |
     |  Parameters
     |  ----------
     |  n : int
     |      The size of the signal.
     |  m : int, optional
     |      The number of output points desired.  Default is `n`.
     |  w : complex, optional
     |      The ratio between points in each step.  This must be precise or the
     |      accumulated error will degrade the tail of the output sequence.
     |      Defaults to equally spaced points around the entire unit circle.
     |  a : complex, optional
     |      The starting point in the complex plane.  Default is 1+0j.
     |
     |  Returns
     |  -------
     |  f : CZT
     |      Callable object ``f(x, axis=-1)`` for computing the chirp z-transform
     |      on `x`.
     |
     |  See Also
     |  --------
     |  czt : Convenience function for quickly calculating CZT.
     |  ZoomFFT : Class that creates a callable partial FFT function.
     |
     |  Notes
     |  -----
     |  The defaults are chosen such that ``f(x)`` is equivalent to
     |  ``fft.fft(x)`` and, if ``m > len(x)``, that ``f(x, m)`` is equivalent to
     |  ``fft.fft(x, m)``.
     |
     |  If `w` does not lie on the unit circle, then the transform will be
     |  around a spiral with exponentially-increasing radius.  Regardless,
     |  angle will increase linearly.
     |
     |  For transforms that do lie on the unit circle, accuracy is better when
     |  using `ZoomFFT`, since any numerical error in `w` is
     |  accumulated for long data lengths, drifting away from the unit circle.
     |
     |  The chirp z-transform can be faster than an equivalent FFT with
     |  zero padding.  Try it with your own array sizes to see.
     |
     |  However, the chirp z-transform is considerably less precise than the
     |  equivalent zero-padded FFT.
     |
     |  As this CZT is implemented using the Bluestein algorithm, it can compute
     |  large prime-length Fourier transforms in O(N log N) time, rather than the
     |  O(N**2) time required by the direct DFT calculation.  (`scipy.fft` also
     |  uses Bluestein's algorithm'.)
     |
     |  (The name "chirp z-transform" comes from the use of a chirp in the
     |  Bluestein algorithm.  It does not decompose signals into chirps, like
     |  other transforms with "chirp" in the name.)
     |
     |  References
     |  ----------
     |  .. [1] Leo I. Bluestein, "A linear filtering approach to the computation
     |         of the discrete Fourier transform," Northeast Electronics Research
     |         and Engineering Meeting Record 10, 218-219 (1968).
     |  .. [2] Rabiner, Schafer, and Rader, "The chirp z-transform algorithm and
     |         its application," Bell Syst. Tech. J. 48, 1249-1292 (1969).
     |
     |  Examples
     |  --------
     |  Compute multiple prime-length FFTs:
     |
     |  >>> from scipy.signal import CZT
     |  >>> import numpy as np
     |  >>> a = np.random.rand(7)
     |  >>> b = np.random.rand(7)
     |  >>> c = np.random.rand(7)
     |  >>> czt_7 = CZT(n=7)
     |  >>> A = czt_7(a)
     |  >>> B = czt_7(b)
     |  >>> C = czt_7(c)
     |
     |  Display the points at which the FFT is calculated:
     |
     |  >>> czt_7.points()
     |  array([ 1.00000000+0.j        ,  0.62348980+0.78183148j,
     |         -0.22252093+0.97492791j, -0.90096887+0.43388374j,
     |         -0.90096887-0.43388374j, -0.22252093-0.97492791j,
     |          0.62348980-0.78183148j])
     |  >>> import matplotlib.pyplot as plt
     |  >>> plt.plot(czt_7.points().real, czt_7.points().imag, 'o')
     |  >>> plt.gca().add_patch(plt.Circle((0,0), radius=1, fill=False, alpha=.3))
     |  >>> plt.axis('equal')
     |  >>> plt.show()
     |
     |  Methods defined here:
     |
     |  __call__(self, x, *, axis=-1)
     |      Calculate the chirp z-transform of a signal.
     |
     |      Parameters
     |      ----------
     |      x : array
     |          The signal to transform.
     |      axis : int, optional
     |          Axis over which to compute the FFT. If not given, the last axis is
     |          used.
     |
     |      Returns
     |      -------
     |      out : ndarray
     |          An array of the same dimensions as `x`, but with the length of the
     |          transformed axis set to `m`.
     |
     |  __init__(self, n, m=None, w=None, a=(1+0j))
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  points(self)
     |      Return the points at which the chirp z-transform is computed.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ShortTimeFFT(builtins.object)
     |  ShortTimeFFT(win: 'np.ndarray', hop: 'int', fs: 'float', *, fft_mode: 'FFT_MODE_TYPE' = 'onesided', mfft: 'int | None' = None, dual_win: 'np.ndarray | None' = None, scale_to: "Literal['magnitude', 'psd'] | None" = None, phase_shift: 'int | None' = 0)
     |
     |  Provide a parametrized discrete Short-time Fourier transform (stft)
     |  and its inverse (istft).
     |
     |  .. currentmodule:: scipy.signal.ShortTimeFFT
     |
     |  The `~ShortTimeFFT.stft` calculates sequential FFTs by sliding a
     |  window (`win`) over an input signal by `hop` increments. It can be used to
     |  quantify the change of the spectrum over time.
     |
     |  The `~ShortTimeFFT.stft` is represented by a complex-valued matrix S[q,p]
     |  where the p-th column represents an FFT with the window centered at the
     |  time t[p] = p * `delta_t` = p * `hop` * `T` where `T` is  the sampling
     |  interval of the input signal. The q-th row represents the values at the
     |  frequency f[q] = q * `delta_f` with `delta_f` = 1 / (`mfft` * `T`) being
     |  the bin width of the FFT.
     |
     |  The inverse STFT `~ShortTimeFFT.istft` is calculated by reversing the steps
     |  of the STFT: Take the IFFT of the p-th slice of S[q,p] and multiply the
     |  result with the so-called dual window (see `dual_win`). Shift the result by
     |  p * `delta_t` and add the result to previous shifted results to reconstruct
     |  the signal. If only the dual window is known and the STFT is invertible,
     |  `from_dual` can be used to instantiate this class.
     |
     |  Due to the convention of time t = 0 being at the first sample of the input
     |  signal, the STFT values typically have negative time slots. Hence,
     |  negative indexes like `p_min` or `k_min` do not indicate counting
     |  backwards from an array's end like in standard Python indexing but being
     |  left of t = 0.
     |
     |  More detailed information can be found in the :ref:`tutorial_stft` section
     |  of the :ref:`user_guide`.
     |
     |  Note that all parameters of the initializer, except `scale_to` (which uses
     |  `scaling`) have identical named attributes.
     |
     |  Parameters
     |  ----------
     |  win : np.ndarray
     |      The window must be a real- or complex-valued 1d array.
     |  hop : int
     |      The increment in samples, by which the window is shifted in each step.
     |  fs : float
     |      Sampling frequency of input signal and window. Its relation to the
     |      sampling interval `T` is ``T = 1 / fs``.
     |  fft_mode : 'twosided', 'centered', 'onesided', 'onesided2X'
     |      Mode of FFT to be used (default 'onesided').
     |      See property `fft_mode` for details.
     |  mfft: int | None
     |      Length of the FFT used, if a zero padded FFT is desired.
     |      If ``None`` (default), the length of the window `win` is used.
     |  dual_win : np.ndarray | None
     |      The dual window of `win`. If set to ``None``, it is calculated if
     |      needed.
     |  scale_to : 'magnitude', 'psd' | None
     |      If not ``None`` (default) the window function is scaled, so each STFT
     |      column represents  either a 'magnitude' or a power spectral density
     |      ('psd') spectrum. This parameter sets the property `scaling` to the
     |      same value. See method `scale_to` for details.
     |  phase_shift : int | None
     |      If set, add a linear phase `phase_shift` / `mfft` * `f` to each
     |      frequency `f`. The default value 0 ensures that there is no phase shift
     |      on the zeroth slice (in which t=0 is centered). See property
     |      `phase_shift` for more details.
     |
     |  Examples
     |  --------
     |  The following example shows the magnitude of the STFT of a sine with
     |  varying frequency :math:`f_i(t)` (marked by a red dashed line in the plot):
     |
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.signal import ShortTimeFFT
     |  >>> from scipy.signal.windows import gaussian
     |  ...
     |  >>> T_x, N = 1 / 20, 1000  # 20 Hz sampling rate for 50 s signal
     |  >>> t_x = np.arange(N) * T_x  # time indexes for signal
     |  >>> f_i = 1 * np.arctan((t_x - t_x[N // 2]) / 2) + 5  # varying frequency
     |  >>> x = np.sin(2*np.pi*np.cumsum(f_i)*T_x) # the signal
     |
     |  The utilized Gaussian window is 50 samples or 2.5 s long. The parameter
     |  ``mfft=200`` in `ShortTimeFFT` causes the spectrum to be oversampled
     |  by a factor of 4:
     |
     |  >>> g_std = 8  # standard deviation for Gaussian window in samples
     |  >>> w = gaussian(50, std=g_std, sym=True)  # symmetric Gaussian window
     |  >>> SFT = ShortTimeFFT(w, hop=10, fs=1/T_x, mfft=200, scale_to='magnitude')
     |  >>> Sx = SFT.stft(x)  # perform the STFT
     |
     |  In the plot, the time extent of the signal `x` is marked by vertical dashed
     |  lines. Note that the SFT produces values outside the time range of `x`. The
     |  shaded areas on the left and the right indicate border effects caused
     |  by  the window slices in that area not fully being inside time range of
     |  `x`:
     |
     |  >>> fig1, ax1 = plt.subplots(figsize=(6., 4.))  # enlarge plot a bit
     |  >>> t_lo, t_hi = SFT.extent(N)[:2]  # time range of plot
     |  >>> ax1.set_title(rf"STFT ({SFT.m_num*SFT.T:g}$\,s$ Gaussian window, " +
     |  ...               rf"$\sigma_t={g_std*SFT.T}\,$s)")
     |  >>> ax1.set(xlabel=f"Time $t$ in seconds ({SFT.p_num(N)} slices, " +
     |  ...                rf"$\Delta t = {SFT.delta_t:g}\,$s)",
     |  ...         ylabel=f"Freq. $f$ in Hz ({SFT.f_pts} bins, " +
     |  ...                rf"$\Delta f = {SFT.delta_f:g}\,$Hz)",
     |  ...         xlim=(t_lo, t_hi))
     |  ...
     |  >>> im1 = ax1.imshow(abs(Sx), origin='lower', aspect='auto',
     |  ...                  extent=SFT.extent(N), cmap='viridis')
     |  >>> ax1.plot(t_x, f_i, 'r--', alpha=.5, label='$f_i(t)$')
     |  >>> fig1.colorbar(im1, label="Magnitude $|S_x(t, f)|$")
     |  ...
     |  >>> # Shade areas where window slices stick out to the side:
     |  >>> for t0_, t1_ in [(t_lo, SFT.lower_border_end[0] * SFT.T),
     |  ...                  (SFT.upper_border_begin(N)[0] * SFT.T, t_hi)]:
     |  ...     ax1.axvspan(t0_, t1_, color='w', linewidth=0, alpha=.2)
     |  >>> for t_ in [0, N * SFT.T]:  # mark signal borders with vertical line:
     |  ...     ax1.axvline(t_, color='y', linestyle='--', alpha=0.5)
     |  >>> ax1.legend()
     |  >>> fig1.tight_layout()
     |  >>> plt.show()
     |
     |  Reconstructing the signal with the `~ShortTimeFFT.istft` is
     |  straightforward, but note that the length of `x1` should be specified,
     |  since the SFT length increases in `hop` steps:
     |
     |  >>> SFT.invertible  # check if invertible
     |  True
     |  >>> x1 = SFT.istft(Sx, k1=N)
     |  >>> np.allclose(x, x1)
     |  True
     |
     |  It is possible to calculate the SFT of signal parts:
     |
     |  >>> p_q = SFT.nearest_k_p(N // 2)
     |  >>> Sx0 = SFT.stft(x[:p_q])
     |  >>> Sx1 = SFT.stft(x[p_q:])
     |
     |  When assembling sequential STFT parts together, the overlap needs to be
     |  considered:
     |
     |  >>> p0_ub = SFT.upper_border_begin(p_q)[1] - SFT.p_min
     |  >>> p1_le = SFT.lower_border_end[1] - SFT.p_min
     |  >>> Sx01 = np.hstack((Sx0[:, :p0_ub],
     |  ...                   Sx0[:, p0_ub:] + Sx1[:, :p1_le],
     |  ...                   Sx1[:, p1_le:]))
     |  >>> np.allclose(Sx01, Sx)  # Compare with SFT of complete signal
     |  True
     |
     |  It is also possible to calculate the `itsft` for signal parts:
     |
     |  >>> y_p = SFT.istft(Sx, N//3, N//2)
     |  >>> np.allclose(y_p, x[N//3:N//2])
     |  True
     |
     |  Methods defined here:
     |
     |  __init__(self, win: 'np.ndarray', hop: 'int', fs: 'float', *, fft_mode: 'FFT_MODE_TYPE' = 'onesided', mfft: 'int | None' = None, dual_win: 'np.ndarray | None' = None, scale_to: "Literal['magnitude', 'psd'] | None" = None, phase_shift: 'int | None' = 0)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  extent(self, n: 'int', axes_seq: "Literal['tf', 'ft']" = 'tf', center_bins: 'bool' = False) -> 'tuple[float, float, float, float]'
     |      Return minimum and maximum values time-frequency values.
     |
     |      A tuple with four floats  ``(t0, t1, f0, f1)`` for 'tf' and
     |      ``(f0, f1, t0, t1)`` for 'ft' is returned describing the corners
     |      of the time-frequency domain of the `~ShortTimeFFT.stft`.
     |      That tuple can be passed to `matplotlib.pyplot.imshow` as a parameter
     |      with the same name.
     |
     |      Parameters
     |      ----------
     |      n : int
     |          Number of samples in input signal.
     |      axes_seq : {'tf', 'ft'}
     |          Return time extent first and then frequency extent or vice-versa.
     |      center_bins: bool
     |          If set (default ``False``), the values of the time slots and
     |          frequency bins are moved from the side the middle. This is useful,
     |          when plotting the `~ShortTimeFFT.stft` values as step functions,
     |          i.e., with no interpolation.
     |
     |      See Also
     |      --------
     |      :func:`matplotlib.pyplot.imshow`: Display data as an image.
     |      :class:`scipy.signal.ShortTimeFFT`: Class this method belongs to.
     |
     |  istft(self, S: 'np.ndarray', k0: 'int' = 0, k1: 'int | None' = None, *, f_axis: 'int' = -2, t_axis: 'int' = -1) -> 'np.ndarray'
     |      Inverse short-time Fourier transform.
     |
     |      It returns an array of dimension ``S.ndim - 1``  which is real
     |      if `onesided_fft` is set, else complex. If the STFT is not
     |      `invertible`, or the parameters are out of bounds  a ``ValueError`` is
     |      raised.
     |
     |      Parameters
     |      ----------
     |      S
     |          A complex valued array where `f_axis` denotes the frequency
     |          values and the `t-axis` dimension the temporal values of the
     |          STFT values.
     |      k0, k1
     |          The start and the end index of the reconstructed signal. The
     |          default (``k0 = 0``, ``k1 = None``) assumes that the maximum length
     |          signal should be reconstructed.
     |      f_axis, t_axis
     |          The axes in `S` denoting the frequency and the time dimension.
     |
     |      Notes
     |      -----
     |      It is required that `S` has `f_pts` entries along the `f_axis`. For
     |      the `t_axis` it is assumed that the first entry corresponds to
     |      `p_min` * `delta_t` (being <= 0). The length of `t_axis` needs to be
     |      compatible with `k1`. I.e., ``S.shape[t_axis] >= self.p_max(k1)`` must
     |      hold, if `k1` is not ``None``. Else `k1` is set to `k_max` with::
     |
     |          q_max = S.shape[t_range] + self.p_min
     |          k_max = (q_max - 1) * self.hop + self.m_num - self.m_num_mid
     |
     |      The :ref:`tutorial_stft` section of the :ref:`user_guide` discussed the
     |      slicing behavior by means of an example.
     |
     |      See Also
     |      --------
     |      invertible: Check if STFT is invertible.
     |      :meth:`~ShortTimeFFT.stft`: Perform Short-time Fourier transform.
     |      :class:`scipy.signal.ShortTimeFFT`: Class this method belongs to.
     |
     |  k_max(self, n: 'int') -> 'int'
     |      First sample index after signal end not touched by a time slice.
     |
     |      `k_max` - 1 is the largest sample index of the slice `p_max` for a
     |      given input signal of `n` samples.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  nearest_k_p(self, k: 'int', left: 'bool' = True) -> 'int'
     |      Return nearest sample index k_p for which t[k_p] == t[p] holds.
     |
     |      The nearest next smaller time sample p (where t[p] is the center
     |      position of the window of the p-th slice) is p_k = k // `hop`.
     |      If `hop` is a divisor of `k` than `k` is returned.
     |      If `left` is set than p_k * `hop` is returned else (p_k+1) * `hop`.
     |
     |      This method can be used to slice an input signal into chunks for
     |      calculating the STFT and iSTFT incrementally.
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT (``hop*T``)
     |      hop: Time increment in signal samples for sliding window.
     |      T: Sampling interval of input signal and of the window (``1/fs``).
     |      fs: Sampling frequency (being ``1/T``)
     |      t: Times of STFT for an input signal with `n` samples.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  p_max(self, n: 'int') -> 'int'
     |      Index of first non-overlapping upper time slice for `n` sample
     |      input.
     |
     |      Note that center point t[p_max] = (p_max(n)-1) * `delta_t` is typically
     |      larger than last time index t[n-1] == (`n`-1) * `T`. The upper border
     |      of samples indexes covered by the window slices is given by `k_max`.
     |      Furthermore, `p_max` does not denote the number of slices `p_num` since
     |      `p_min` is typically less than zero.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      p_min: The smallest possible slice index.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  p_num(self, n: 'int') -> 'int'
     |      Number of time slices for an input signal with `n` samples.
     |
     |      It is given by `p_num` = `p_max` - `p_min` with `p_min` typically
     |      being negative.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      lower_border_end: Where pre-padding effects end.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_range: Determine and validate slice index range.
     |      upper_border_begin: Where post-padding effects start.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  p_range(self, n: 'int', p0: 'int | None' = None, p1: 'int | None' = None) -> 'tuple[int, int]'
     |      Determine and validate slice index range.
     |
     |      Parameters
     |      ----------
     |      n : int
     |          Number of samples of input signal, assuming t[0] = 0.
     |      p0 : int | None
     |          First slice index. If 0 then the first slice is centered at t = 0.
     |          If ``None`` then `p_min` is used. Note that p0 may be < 0 if
     |          slices are left of t = 0.
     |      p1 : int | None
     |          End of interval (last value is p1-1).
     |          If ``None`` then `p_max(n)` is used.
     |
     |
     |      Returns
     |      -------
     |      p0_ : int
     |          The fist slice index
     |      p1_ : int
     |          End of interval (last value is p1-1).
     |
     |      Notes
     |      -----
     |      A ``ValueError`` is raised if ``p_min <= p0 < p1 <= p_max(n)`` does not
     |      hold.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      lower_border_end: Where pre-padding effects end.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      upper_border_begin: Where post-padding effects start.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  scale_to(self, scaling: "Literal['magnitude', 'psd']")
     |      Scale window to obtain 'magnitude' or 'psd' scaling for the STFT.
     |
     |      The window of a 'magnitude' spectrum has an integral of one, i.e., unit
     |      area for non-negative windows. This ensures that absolute the values of
     |      spectrum does not change if the length of the window changes (given
     |      the input signal is stationary).
     |
     |      To represent the power spectral density ('psd') for varying length
     |      windows the area of the absolute square of the window needs to be
     |      unity.
     |
     |      The `scaling` property shows the current scaling. The properties
     |      `fac_magnitude` and `fac_psd` show the scaling factors required to
     |      scale the STFT values to a magnitude or a psd spectrum.
     |
     |      This method is called, if the initializer parameter `scale_to` is set.
     |
     |      See Also
     |      --------
     |      fac_magnitude: Scaling factor for to  a magnitude spectrum.
     |      fac_psd: Scaling factor for to  a power spectral density spectrum.
     |      fft_mode: Mode of utilized FFT
     |      scaling: Normalization applied to the window function.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  spectrogram(self, x: 'np.ndarray', y: 'np.ndarray | None' = None, detr: "Callable[[np.ndarray], np.ndarray] | Literal['linear', 'constant'] | None" = None, *, p0: 'int | None' = None, p1: 'int | None' = None, k_offset: 'int' = 0, padding: 'PAD_TYPE' = 'zeros', axis: 'int' = -1) -> 'np.ndarray'
     |      Calculate spectrogram or cross-spectrogram.
     |
     |      The spectrogram is the absolute square of the STFT, i.e, it is
     |      ``abs(S[q,p])**2`` for given ``S[q,p]``  and thus is always
     |      non-negative.
     |      For two STFTs ``Sx[q,p], Sy[q,p]``, the cross-spectrogram is defined
     |      as ``Sx[q,p] * np.conj(Sx[q,p])`` and is complex-valued.
     |      This is a convenience function for calling `~ShortTimeFFT.stft` /
     |      `stft_detrend`, hence all parameters are discussed there. If `y` is not
     |      ``None`` it needs to have the same shape as `x`.
     |
     |      Examples
     |      --------
     |      The following example shows the spectrogram of a square wave with
     |      varying frequency :math:`f_i(t)` (marked by a green dashed line in the
     |      plot) sampled with 20 Hz:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> import numpy as np
     |      >>> from scipy.signal import square, ShortTimeFFT
     |      >>> from scipy.signal.windows import gaussian
     |      ...
     |      >>> T_x, N = 1 / 20, 1000  # 20 Hz sampling rate for 50 s signal
     |      >>> t_x = np.arange(N) * T_x  # time indexes for signal
     |      >>> f_i = 5e-3*(t_x - t_x[N // 3])**2 + 1  # varying frequency
     |      >>> x = square(2*np.pi*np.cumsum(f_i)*T_x)  # the signal
     |
     |      The utitlized Gaussian window is 50 samples or 2.5 s long. The
     |      parameter ``mfft=800`` (oversampling factor 16) and the `hop` interval
     |      of 2 in `ShortTimeFFT` was chosen to produce a sufficient number of
     |      points:
     |
     |      >>> g_std = 12  # standard deviation for Gaussian window in samples
     |      >>> win = gaussian(50, std=g_std, sym=True)  # symmetric Gaussian wind.
     |      >>> SFT = ShortTimeFFT(win, hop=2, fs=1/T_x, mfft=800, scale_to='psd')
     |      >>> Sx2 = SFT.spectrogram(x)  # calculate absolute square of STFT
     |
     |      The plot's colormap is logarithmically scaled as the power spectral
     |      density is in dB. The time extent of the signal `x` is marked by
     |      vertical dashed lines and the shaded areas mark the presence of border
     |      effects:
     |
     |      >>> fig1, ax1 = plt.subplots(figsize=(6., 4.))  # enlarge plot a bit
     |      >>> t_lo, t_hi = SFT.extent(N)[:2]  # time range of plot
     |      >>> ax1.set_title(rf"Spectrogram ({SFT.m_num*SFT.T:g}$\,s$ Gaussian " +
     |      ...               rf"window, $\sigma_t={g_std*SFT.T:g}\,$s)")
     |      >>> ax1.set(xlabel=f"Time $t$ in seconds ({SFT.p_num(N)} slices, " +
     |      ...                rf"$\Delta t = {SFT.delta_t:g}\,$s)",
     |      ...         ylabel=f"Freq. $f$ in Hz ({SFT.f_pts} bins, " +
     |      ...                rf"$\Delta f = {SFT.delta_f:g}\,$Hz)",
     |      ...         xlim=(t_lo, t_hi))
     |      >>> Sx_dB = 10 * np.log10(np.fmax(Sx2, 1e-4))  # limit range to -40 dB
     |      >>> im1 = ax1.imshow(Sx_dB, origin='lower', aspect='auto',
     |      ...                  extent=SFT.extent(N), cmap='magma')
     |      >>> ax1.plot(t_x, f_i, 'g--', alpha=.5, label='$f_i(t)$')
     |      >>> fig1.colorbar(im1, label='Power Spectral Density ' +
     |      ...                          r"$20\,\log_{10}|S_x(t, f)|$ in dB")
     |      ...
     |      >>> # Shade areas where window slices stick out to the side:
     |      >>> for t0_, t1_ in [(t_lo, SFT.lower_border_end[0] * SFT.T),
     |      ...                  (SFT.upper_border_begin(N)[0] * SFT.T, t_hi)]:
     |      ...     ax1.axvspan(t0_, t1_, color='w', linewidth=0, alpha=.3)
     |      >>> for t_ in [0, N * SFT.T]:  # mark signal borders with vertical line
     |      ...     ax1.axvline(t_, color='c', linestyle='--', alpha=0.5)
     |      >>> ax1.legend()
     |      >>> fig1.tight_layout()
     |      >>> plt.show()
     |
     |      The logarithmic scaling reveals the odd harmonics of the square wave,
     |      which are reflected at the Nyquist frequency of 10 Hz. This aliasing
     |      is also the main source of the noise artifacts in the plot.
     |
     |
     |      See Also
     |      --------
     |      :meth:`~ShortTimeFFT.stft`: Perform the short-time Fourier transform.
     |      stft_detrend: STFT with a trend subtracted from each segment.
     |      :class:`scipy.signal.ShortTimeFFT`: Class this method belongs to.
     |
     |  stft(self, x: 'np.ndarray', p0: 'int | None' = None, p1: 'int | None' = None, *, k_offset: 'int' = 0, padding: 'PAD_TYPE' = 'zeros', axis: 'int' = -1) -> 'np.ndarray'
     |      Perform the short-time Fourier transform.
     |
     |      A two-dimensional matrix with ``p1-p0`` columns is calculated.
     |      The `f_pts` rows represent value at the frequencies `f`. The q-th
     |      column of the windowed FFT with the window `win` is centered at t[q].
     |      The columns represent the values at the frequencies `f`.
     |
     |      Parameters
     |      ----------
     |      x
     |          The input signal as real or complex valued array. For complex values, the
     |          property `fft_mode` must be set to 'twosided' or 'centered'.
     |      p0
     |          The first element of the range of slices to calculate. If ``None``
     |          then it is set to :attr:`p_min`, which is the smallest possible
     |          slice.
     |      p1
     |          The end of the array. If ``None`` then `p_max(n)` is used.
     |      k_offset
     |          Index of first sample (t = 0) in `x`.
     |      padding
     |          Kind of values which are added, when the sliding window sticks out
     |          on either the lower or upper end of the input `x`. Zeros are added
     |          if the default 'zeros' is set. For 'edge' either the first or the
     |          last value of `x` is used. 'even' pads by reflecting the
     |          signal on the first or last sample and 'odd' additionally
     |          multiplies it with -1.
     |      axis
     |          The axis of `x` over which to compute the STFT.
     |          If not given, the last axis is used.
     |
     |      Returns
     |      -------
     |      S
     |          A complex array is returned with the dimension always being larger
     |          by one than of `x`. The last axis always represent the time slices
     |          of the STFT. `axis` defines the frequency axis (default second to
     |          last). E.g., for a one-dimensional `x`, a complex 2d array is
     |          returned, with axis 0 representing frequency and axis 1 the time
     |          slices.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      delta_t: Time increment of STFT
     |      f: Frequencies values of the STFT.
     |      invertible: Check if STFT is invertible.
     |      :meth:`~ShortTimeFFT.istft`: Inverse short-time Fourier transform.
     |      p_range: Determine and validate slice index range.
     |      stft_detrend: STFT with detrended segments.
     |      t: Times of STFT for an input signal with `n` samples.
     |      :class:`scipy.signal.ShortTimeFFT`: Class this method belongs to.
     |
     |  stft_detrend(self, x: 'np.ndarray', detr: "Callable[[np.ndarray], np.ndarray] | Literal['linear', 'constant'] | None", p0: 'int | None' = None, p1: 'int | None' = None, *, k_offset: 'int' = 0, padding: 'PAD_TYPE' = 'zeros', axis: 'int' = -1) -> 'np.ndarray'
     |      Short-time Fourier transform with a trend being subtracted from each
     |      segment beforehand.
     |
     |      If `detr` is set to 'constant', the mean is subtracted, if set to
     |      "linear", the linear trend is removed. This is achieved by calling
     |      :func:`scipy.signal.detrend`. If `detr` is a function, `detr` is
     |      applied to each segment.
     |      All other parameters have the same meaning as in `~ShortTimeFFT.stft`.
     |
     |      Note that due to the detrending, the original signal cannot be
     |      reconstructed by the `~ShortTimeFFT.istft`.
     |
     |      See Also
     |      --------
     |      invertible: Check if STFT is invertible.
     |      :meth:`~ShortTimeFFT.istft`: Inverse short-time Fourier transform.
     |      :meth:`~ShortTimeFFT.stft`: Short-time Fourier transform
     |                                 (without detrending).
     |      :class:`scipy.signal.ShortTimeFFT`: Class this method belongs to.
     |
     |  t(self, n: 'int', p0: 'int | None' = None, p1: 'int | None' = None, k_offset: 'int' = 0) -> 'np.ndarray'
     |      Times of STFT for an input signal with `n` samples.
     |
     |      Returns a 1d array with times of the `~ShortTimeFFT.stft` values with
     |      the same  parametrization. Note that the slices are
     |      ``delta_t = hop * T`` time units apart.
     |
     |       Parameters
     |      ----------
     |      n
     |          Number of sample of the input signal.
     |      p0
     |          The first element of the range of slices to calculate. If ``None``
     |          then it is set to :attr:`p_min`, which is the smallest possible
     |          slice.
     |      p1
     |          The end of the array. If ``None`` then `p_max(n)` is used.
     |      k_offset
     |          Index of first sample (t = 0) in `x`.
     |
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT (``hop*T``)
     |      hop: Time increment in signal samples for sliding window.
     |      nearest_k_p: Nearest sample index k_p for which t[k_p] == t[p] holds.
     |      T: Sampling interval of input signal and of the window (``1/fs``).
     |      fs: Sampling frequency (being ``1/T``)
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  upper_border_begin(self, n: 'int') -> 'tuple[int, int]'
     |      First signal index and first slice index affected by post-padding.
     |
     |      Describes the point where the window does begin stick out to the right
     |      of the signal domain.
     |      A detailed example is given :ref:`tutorial_stft_sliding_win` section
     |      of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      lower_border_end: Where pre-padding effects end.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      ShortTimeFFT: Class this method belongs to.
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  from_dual(dual_win: 'np.ndarray', hop: 'int', fs: 'float', *, fft_mode: 'FFT_MODE_TYPE' = 'onesided', mfft: 'int | None' = None, scale_to: "Literal['magnitude', 'psd'] | None" = None, phase_shift: 'int | None' = 0)
     |      Instantiate a `ShortTimeFFT` by only providing a dual window.
     |
     |      If an STFT is invertible, it is possible to calculate the window `win`
     |      from a given dual window `dual_win`. All other parameters have the
     |      same meaning as in the initializer of `ShortTimeFFT`.
     |
     |      As explained in the :ref:`tutorial_stft` section of the
     |      :ref:`user_guide`, an invertible STFT can be interpreted as series
     |      expansion of time-shifted and frequency modulated dual windows. E.g.,
     |      the series coefficient S[q,p] belongs to the term, which shifted
     |      `dual_win` by p * `delta_t` and multiplied it by
     |      exp( 2 * j * pi * t * q * `delta_f`).
     |
     |
     |      Examples
     |      --------
     |      The following example discusses decomposing a signal into time- and
     |      frequency-shifted Gaussians. A Gaussian with standard deviation of
     |      one made up of 51 samples will be used:
     |
     |      >>> import numpy as np
     |      >>> import matplotlib.pyplot as plt
     |      >>> from scipy.signal import ShortTimeFFT
     |      >>> from scipy.signal.windows import gaussian
     |      ...
     |      >>> T, N = 0.1, 51
     |      >>> d_win = gaussian(N, std=1/T, sym=True)  # symmetric Gaussian window
     |      >>> t = T * (np.arange(N) - N//2)
     |      ...
     |      >>> fg1, ax1 = plt.subplots()
     |      >>> ax1.set_title(r"Dual Window: Gaussian with $\sigma_t=1$")
     |      >>> ax1.set(xlabel=f"Time $t$ in seconds ({N} samples, $T={T}$ s)",
     |      ...        xlim=(t[0], t[-1]), ylim=(0, 1.1*max(d_win)))
     |      >>> ax1.plot(t, d_win, 'C0-')
     |
     |      The following plot with the overlap of 41, 11 and 2 samples show how
     |      the `hop` interval affects the shape of the window `win`:
     |
     |      >>> fig2, axx = plt.subplots(3, 1, sharex='all')
     |      ...
     |      >>> axx[0].set_title(r"Windows for hop$\in\{10, 40, 49\}$")
     |      >>> for c_, h_ in enumerate([10, 40, 49]):
     |      ...     SFT = ShortTimeFFT.from_dual(d_win, h_, 1/T)
     |      ...     axx[c_].plot(t + h_ * T, SFT.win, 'k--', alpha=.3, label=None)
     |      ...     axx[c_].plot(t - h_ * T, SFT.win, 'k:', alpha=.3, label=None)
     |      ...     axx[c_].plot(t, SFT.win, f'C{c_+1}',
     |      ...                     label=r"$\Delta t=%0.1f\,$s" % SFT.delta_t)
     |      ...     axx[c_].set_ylim(0, 1.1*max(SFT.win))
     |      ...     axx[c_].legend(loc='center')
     |      >>> axx[-1].set(xlabel=f"Time $t$ in seconds ({N} samples, $T={T}$ s)",
     |      ...             xlim=(t[0], t[-1]))
     |      >>> plt.show()
     |
     |      Beside the window `win` centered at t = 0 the previous (t = -`delta_t`)
     |      and following window (t = `delta_t`) are depicted. It can be seen that
     |      for small `hop` intervals, the window is compact and smooth, having a
     |      good time-frequency concentration in the STFT. For the large `hop`
     |      interval of 4.9 s, the window has small values around t = 0, which are
     |      not covered by the overlap of the adjacent windows, which could lead to
     |      numeric inaccuracies. Furthermore, the peaky shape at the beginning and
     |      the end of the window points to a higher bandwidth, resulting in a
     |      poorer time-frequency resolution of the STFT.
     |      Hence, the choice of the `hop` interval will be a compromise between
     |      a time-frequency resolution and memory requirements demanded by small
     |      `hop` sizes.
     |
     |      See Also
     |      --------
     |      from_window: Create instance by wrapping `get_window`.
     |      ShortTimeFFT: Create instance using standard initializer.
     |
     |  from_window(win_param: 'str | tuple | float', fs: 'float', nperseg: 'int', noverlap: 'int', *, symmetric_win: 'bool' = False, fft_mode: 'FFT_MODE_TYPE' = 'onesided', mfft: 'int | None' = None, scale_to: "Literal['magnitude', 'psd'] | None" = None, phase_shift: 'int | None' = 0)
     |      Instantiate `ShortTimeFFT` by using `get_window`.
     |
     |      The method `get_window` is used to create a window of length
     |      `nperseg`. The parameter names `noverlap`, and `nperseg` are used here,
     |      since they more inline with other classical STFT libraries.
     |
     |      Parameters
     |      ----------
     |      win_param: Union[str, tuple, float],
     |          Parameters passed to `get_window`. For windows with no parameters,
     |          it may be a string (e.g., ``'hann'``), for parametrized windows a
     |          tuple, (e.g., ``('gaussian', 2.)``) or a single float specifying
     |          the shape parameter of a kaiser window (i.e. ``4.``  and
     |          ``('kaiser', 4.)`` are equal. See `get_window` for more details.
     |      fs : float
     |          Sampling frequency of input signal. Its relation to the
     |          sampling interval `T` is ``T = 1 / fs``.
     |      nperseg: int
     |          Window length in samples, which corresponds to the `m_num`.
     |      noverlap: int
     |          Window overlap in samples. It relates to the `hop` increment by
     |          ``hop = npsereg - noverlap``.
     |      symmetric_win: bool
     |          If ``True`` then a symmetric window is generated, else a periodic
     |          window is generated (default). Though symmetric windows seem for
     |          most applications to be more sensible, the default of a periodic
     |          windows was chosen to correspond to the default of `get_window`.
     |      fft_mode : 'twosided', 'centered', 'onesided', 'onesided2X'
     |          Mode of FFT to be used (default 'onesided').
     |          See property `fft_mode` for details.
     |      mfft: int | None
     |          Length of the FFT used, if a zero padded FFT is desired.
     |          If ``None`` (default), the length of the window `win` is used.
     |      scale_to : 'magnitude', 'psd' | None
     |          If not ``None`` (default) the window function is scaled, so each
     |          STFT column represents  either a 'magnitude' or a power spectral
     |          density ('psd') spectrum. This parameter sets the property
     |          `scaling` to the same value. See method `scale_to` for details.
     |      phase_shift : int | None
     |          If set, add a linear phase `phase_shift` / `mfft` * `f` to each
     |          frequency `f`. The default value 0 ensures that there is no phase
     |          shift on the zeroth slice (in which t=0 is centered). See property
     |          `phase_shift` for more details.
     |
     |      Examples
     |      --------
     |      The following instances ``SFT0`` and ``SFT1`` are equivalent:
     |
     |      >>> from scipy.signal import ShortTimeFFT, get_window
     |      >>> nperseg = 9  # window length
     |      >>> w = get_window(('gaussian', 2.), nperseg)
     |      >>> fs = 128  # sampling frequency
     |      >>> hop = 3  # increment of STFT time slice
     |      >>> SFT0 = ShortTimeFFT(w, hop, fs=fs)
     |      >>> SFT1 = ShortTimeFFT.from_window(('gaussian', 2.), fs, nperseg,
     |      ...                                 noverlap=nperseg-hop)
     |
     |      See Also
     |      --------
     |      scipy.signal.get_window: Return a window of a given length and type.
     |      from_dual: Create instance using dual window.
     |      ShortTimeFFT: Create instance using standard initializer.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  delta_f
     |      Width of the frequency bins of the STFT.
     |
     |      Return the frequency interval `delta_f` = 1 / (`mfft` * `T`).
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT.
     |      f_pts: Number of points along the frequency axis.
     |      f: Frequencies values of the STFT.
     |      mfft: Length of the input for FFT used.
     |      T: Sampling interval.
     |      t: Times of STFT for an input signal with `n` samples.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  delta_t
     |      Time increment of STFT.
     |
     |      The time increment `delta_t` = `T` * `hop` represents the sample
     |      increment `hop` converted to time based on the sampling interval `T`.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      hop: Hop size in signal samples for sliding window.
     |      t: Times of STFT for an input signal with `n` samples.
     |      T: Sampling interval of input signal and window `win`.
     |      ShortTimeFFT: Class this property belongs to
     |
     |  dual_win
     |      Canonical dual window.
     |
     |      A STFT can be interpreted as the input signal being expressed as a
     |      weighted sum of modulated and time-shifted dual windows. Note that for
     |      a given window there exist many dual windows. The canonical window is
     |      the one with the minimal energy (i.e., :math:`L_2` norm).
     |
     |      `dual_win` has same length as `win`, namely `m_num` samples.
     |
     |      If the dual window cannot be calculated a ``ValueError`` is raised.
     |      This attribute is read only and calculated lazily.
     |
     |      See Also
     |      --------
     |      dual_win: Canonical dual window.
     |      m_num: Number of samples in window `win`.
     |      win: Window function as real- or complex-valued 1d array.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  f
     |      Frequencies values of the STFT.
     |
     |      A 1d array of length `f_pts` with `delta_f` spaced entries is returned.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      f_pts: Number of points along the frequency axis.
     |      mfft: Length of the input for FFT used.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  f_pts
     |      Number of points along the frequency axis.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      f: Frequencies values of the STFT.
     |      mfft: Length of the input for FFT used.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  fac_magnitude
     |      Factor to multiply the STFT values by to scale each frequency slice
     |      to a magnitude spectrum.
     |
     |      It is 1 if attribute ``scaling == 'magnitude'``.
     |      The window can be scaled to a magnitude spectrum by using the method
     |      `scale_to`.
     |
     |      See Also
     |      --------
     |      fac_psd: Scaling factor for to a power spectral density spectrum.
     |      scale_to: Scale window to obtain 'magnitude' or 'psd' scaling.
     |      scaling: Normalization applied to the window function.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  fac_psd
     |      Factor to multiply the STFT values by to scale each frequency slice
     |      to a power spectral density (PSD).
     |
     |      It is 1 if attribute ``scaling == 'psd'``.
     |      The window can be scaled to a psd spectrum by using the method
     |      `scale_to`.
     |
     |      See Also
     |      --------
     |      fac_magnitude: Scaling factor for to a magnitude spectrum.
     |      scale_to: Scale window to obtain 'magnitude' or 'psd' scaling.
     |      scaling: Normalization applied to the window function.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  hop
     |      Time increment in signal samples for sliding window.
     |
     |      This attribute is read only, since `dual_win` depends on it.
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT (``hop*T``)
     |      m_num: Number of samples in window `win`.
     |      m_num_mid: Center index of window `win`.
     |      mfft: Length of input for the FFT used - may be larger than `m_num`.
     |      T: Sampling interval of input signal and of the window.
     |      win: Window function as real- or complex-valued 1d array.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  invertible
     |      Check if STFT is invertible.
     |
     |      This is achieved by trying to calculate the canonical dual window.
     |
     |      See Also
     |      --------
     |      :meth:`~ShortTimeFFT.istft`: Inverse short-time Fourier transform.
     |      m_num: Number of samples in window `win` and `dual_win`.
     |      dual_win: Canonical dual window.
     |      win: Window for STFT.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  k_min
     |      The smallest possible signal index of the STFT.
     |
     |      `k_min` is the index of the left-most non-zero value of the lowest
     |      slice `p_min`. Since the zeroth slice is centered over the zeroth
     |      sample of the input signal, `k_min` is never positive.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_max: First sample index after signal end not touched by a time slice.
     |      lower_border_end: Where pre-padding effects end.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      upper_border_begin: Where post-padding effects start.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  lower_border_end
     |      First signal index and first slice index unaffected by pre-padding.
     |
     |      Describes the point where the window does not stick out to the left
     |      of the signal domain.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      lower_border_end: Where pre-padding effects end.
     |      p_min: The smallest possible slice index.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      upper_border_begin: Where post-padding effects start.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  m_num
     |      Number of samples in window `win`.
     |
     |      Note that the FFT can be oversampled by zero-padding. This is achieved
     |      by setting the `mfft` property.
     |
     |      See Also
     |      --------
     |      m_num_mid: Center index of window `win`.
     |      mfft: Length of input for the FFT used - may be larger than `m_num`.
     |      hop: Time increment in signal samples for sliding window.
     |      win: Window function as real- or complex-valued 1d array.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  m_num_mid
     |      Center index of window `win`.
     |
     |      For odd `m_num`, ``(m_num - 1) / 2`` is returned and
     |      for even `m_num` (per definition) ``m_num / 2`` is returned.
     |
     |      See Also
     |      --------
     |      m_num: Number of samples in window `win`.
     |      mfft: Length of input for the FFT used - may be larger than `m_num`.
     |      hop: ime increment in signal samples for sliding window.
     |      win: Window function as real- or complex-valued 1d array.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  onesided_fft
     |      Return True if a one-sided FFT is used.
     |
     |      Returns ``True`` if `fft_mode` is either 'onesided' or 'onesided2X'.
     |
     |      See Also
     |      --------
     |      fft_mode: Utilized FFT ('twosided', 'centered', 'onesided' or
     |               'onesided2X')
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  p_min
     |      The smallest possible slice index.
     |
     |      `p_min` is the index of the left-most slice, where the window still
     |      sticks into the signal, i.e., has non-zero part for t >= 0.
     |      `k_min` is the smallest index where the window function of the slice
     |      `p_min` is non-zero.
     |
     |      Since, per convention the zeroth slice is centered at t=0,
     |      `p_min` <= 0 always holds.
     |      A detailed example is provided in the :ref:`tutorial_stft_sliding_win`
     |      section of the :ref:`user_guide`.
     |
     |      See Also
     |      --------
     |      k_min: The smallest possible signal index.
     |      k_max: First sample index after signal end not touched by a time slice.
     |      p_max: Index of first non-overlapping upper time slice.
     |      p_num: Number of time slices, i.e., `p_max` - `p_min`.
     |      p_range: Determine and validate slice index range.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  scaling
     |      Normalization applied to the window function
     |      ('magnitude', 'psd' or ``None``).
     |
     |      If not ``None``, the FFTs can be either interpreted as a magnitude or
     |      a power spectral density spectrum.
     |
     |      The window function can be scaled by calling the `scale_to` method,
     |      or it is set by the initializer parameter ``scale_to``.
     |
     |      See Also
     |      --------
     |      fac_magnitude: Scaling factor for to a magnitude spectrum.
     |      fac_psd: Scaling factor for to  a power spectral density spectrum.
     |      fft_mode: Mode of utilized FFT
     |      scale_to: Scale window to obtain 'magnitude' or 'psd' scaling.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  win
     |      Window function as real- or complex-valued 1d array.
     |
     |      This attribute is read only, since `dual_win` depends on it.
     |
     |      See Also
     |      --------
     |      dual_win: Canonical dual window.
     |      m_num: Number of samples in window `win`.
     |      m_num_mid: Center index of window `win`.
     |      mfft: Length of input for the FFT used - may be larger than `m_num`.
     |      hop: ime increment in signal samples for sliding window.
     |      win: Window function as real- or complex-valued 1d array.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  T
     |      Sampling interval of input signal and of the window.
     |
     |      A ``ValueError`` is raised if it is set to a non-positive value.
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT (``hop*T``)
     |      hop: Time increment in signal samples for sliding window.
     |      fs: Sampling frequency (being ``1/T``)
     |      t: Times of STFT for an input signal with `n` samples.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  fft_mode
     |      Mode of utilized FFT ('twosided', 'centered', 'onesided' or
     |      'onesided2X').
     |
     |      It can have the following values:
     |
     |      'twosided':
     |          Two-sided FFT, where values for the negative frequencies are in
     |          upper half of the array. Corresponds to :func:`~scipy.fft.fft()`.
     |      'centered':
     |          Two-sided FFT with the values being ordered along monotonically
     |          increasing frequencies. Corresponds to applying
     |          :func:`~scipy.fft.fftshift()` to :func:`~scipy.fft.fft()`.
     |      'onesided':
     |          Calculates only values for non-negative frequency values.
     |          Corresponds to :func:`~scipy.fft.rfft()`.
     |      'onesided2X':
     |          Like `onesided`, but the non-zero frequencies are doubled if
     |          `scaling` is set to 'magnitude' or multiplied by ``sqrt(2)`` if
     |          set to 'psd'. If `scaling` is ``None``, setting `fft_mode` to
     |          `onesided2X` is not allowed.
     |          If the FFT length `mfft` is even, the last FFT value is not paired,
     |          and thus it is not scaled.
     |
     |      Note that `onesided` and `onesided2X` do not work for complex-valued signals or
     |      complex-valued windows. Furthermore, the frequency values can be obtained by
     |      reading the `f` property, and the number of samples by accessing the `f_pts`
     |      property.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      f: Frequencies values of the STFT.
     |      f_pts: Width of the frequency bins of the STFT.
     |      onesided_fft: True if a one-sided FFT is used.
     |      scaling: Normalization applied to the window function
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  fs
     |      Sampling frequency of input signal and of the window.
     |
     |      The sampling frequency is the inverse of the sampling interval `T`.
     |      A ``ValueError`` is raised if it is set to a non-positive value.
     |
     |      See Also
     |      --------
     |      delta_t: Time increment of STFT (``hop*T``)
     |      hop: Time increment in signal samples for sliding window.
     |      T: Sampling interval of input signal and of the window (``1/fs``).
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  mfft
     |      Length of input for the FFT used - may be larger than window
     |      length `m_num`.
     |
     |      If not set, `mfft` defaults to the window length `m_num`.
     |
     |      See Also
     |      --------
     |      f_pts: Number of points along the frequency axis.
     |      f: Frequencies values of the STFT.
     |      m_num: Number of samples in window `win`.
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  phase_shift
     |      If set, add linear phase `phase_shift` / `mfft` * `f` to each FFT
     |      slice of frequency `f`.
     |
     |      Shifting (more precisely `rolling`) an `mfft`-point FFT input by
     |      `phase_shift` samples results in a multiplication of the output by
     |      ``np.exp(2j*np.pi*q*phase_shift/mfft)`` at the frequency q * `delta_f`.
     |
     |      The default value 0 ensures that there is no phase shift on the
     |      zeroth slice (in which t=0 is centered).
     |      No phase shift (``phase_shift is None``) is equivalent to
     |      ``phase_shift = -mfft//2``. In this case slices are not shifted
     |      before calculating the FFT.
     |
     |      The absolute value of `phase_shift` is limited to be less than `mfft`.
     |
     |      See Also
     |      --------
     |      delta_f: Width of the frequency bins of the STFT.
     |      f: Frequencies values of the STFT.
     |      mfft: Length of input for the FFT used
     |      ShortTimeFFT: Class this property belongs to.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {'_dual_win': 'np.ndarray | None', '_fac_mag': 'floa...

    class StateSpace(LinearTimeInvariant)
     |  StateSpace(*system, **kwargs)
     |
     |  Linear Time Invariant system in state-space form.
     |
     |  Represents the system as the continuous-time, first order differential
     |  equation :math:`\dot{x} = A x + B u` or the discrete-time difference
     |  equation :math:`x[k+1] = A x[k] + B u[k]`. `StateSpace` systems
     |  inherit additional functionality from the `lti`, respectively the `dlti`
     |  classes, depending on which system representation is used.
     |
     |  Parameters
     |  ----------
     |  *system: arguments
     |      The `StateSpace` class can be instantiated with 1 or 4 arguments.
     |      The following gives the number of input arguments and their
     |      interpretation:
     |
     |          * 1: `lti` or `dlti` system: (`StateSpace`, `TransferFunction` or
     |            `ZerosPolesGain`)
     |          * 4: array_like: (A, B, C, D)
     |  dt: float, optional
     |      Sampling time [s] of the discrete-time systems. Defaults to `None`
     |      (continuous-time). Must be specified as a keyword argument, for
     |      example, ``dt=0.1``.
     |
     |  See Also
     |  --------
     |  TransferFunction, ZerosPolesGain, lti, dlti
     |  ss2zpk, ss2tf, zpk2sos
     |
     |  Notes
     |  -----
     |  Changing the value of properties that are not part of the
     |  `StateSpace` system representation (such as `zeros` or `poles`) is very
     |  inefficient and may lead to numerical inaccuracies.  It is better to
     |  convert to the specific system representation first. For example, call
     |  ``sys = sys.to_zpk()`` before accessing/changing the zeros, poles or gain.
     |
     |  Examples
     |  --------
     |  >>> from scipy import signal
     |  >>> import numpy as np
     |  >>> a = np.array([[0, 1], [0, 0]])
     |  >>> b = np.array([[0], [1]])
     |  >>> c = np.array([[1, 0]])
     |  >>> d = np.array([[0]])
     |
     |  >>> sys = signal.StateSpace(a, b, c, d)
     |  >>> print(sys)
     |  StateSpaceContinuous(
     |  array([[0, 1],
     |         [0, 0]]),
     |  array([[0],
     |         [1]]),
     |  array([[1, 0]]),
     |  array([[0]]),
     |  dt: None
     |  )
     |
     |  >>> sys.to_discrete(0.1)
     |  StateSpaceDiscrete(
     |  array([[1. , 0.1],
     |         [0. , 1. ]]),
     |  array([[0.005],
     |         [0.1  ]]),
     |  array([[1, 0]]),
     |  array([[0]]),
     |  dt: 0.1
     |  )
     |
     |  >>> a = np.array([[1, 0.1], [0, 1]])
     |  >>> b = np.array([[0.005], [0.1]])
     |
     |  >>> signal.StateSpace(a, b, c, d, dt=0.1)
     |  StateSpaceDiscrete(
     |  array([[1. , 0.1],
     |         [0. , 1. ]]),
     |  array([[0.005],
     |         [0.1  ]]),
     |  array([[1, 0]]),
     |  array([[0]]),
     |  dt: 0.1
     |  )
     |
     |  Method resolution order:
     |      StateSpace
     |      LinearTimeInvariant
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __add__(self, other)
     |      Adds two systems in the sense of frequency domain addition.
     |
     |  __init__(self, *system, **kwargs)
     |      Initialize the state space lti/dlti system.
     |
     |  __mul__(self, other)
     |      Post-multiply another system or a scalar
     |
     |      Handles multiplication of systems in the sense of a frequency domain
     |      multiplication. That means, given two systems E1(s) and E2(s), their
     |      multiplication, H(s) = E1(s) * E2(s), means that applying H(s) to U(s)
     |      is equivalent to first applying E2(s), and then E1(s).
     |
     |      Notes
     |      -----
     |      For SISO systems the order of system application does not matter.
     |      However, for MIMO systems, where the two systems are matrices, the
     |      order above ensures standard Matrix multiplication rules apply.
     |
     |  __neg__(self)
     |      Negate the system (equivalent to pre-multiplying by -1).
     |
     |  __radd__(self, other)
     |
     |  __repr__(self)
     |      Return representation of the `StateSpace` system.
     |
     |  __rmul__(self, other)
     |      Pre-multiply a scalar or matrix (but not StateSpace)
     |
     |  __rsub__(self, other)
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |      Divide by a scalar
     |
     |  to_ss(self)
     |      Return a copy of the current `StateSpace` system.
     |
     |      Returns
     |      -------
     |      sys : instance of `StateSpace`
     |          The current system (copy)
     |
     |  to_tf(self, **kwargs)
     |      Convert system representation to `TransferFunction`.
     |
     |      Parameters
     |      ----------
     |      kwargs : dict, optional
     |          Additional keywords passed to `ss2zpk`
     |
     |      Returns
     |      -------
     |      sys : instance of `TransferFunction`
     |          Transfer function of the current system
     |
     |  to_zpk(self, **kwargs)
     |      Convert system representation to `ZerosPolesGain`.
     |
     |      Parameters
     |      ----------
     |      kwargs : dict, optional
     |          Additional keywords passed to `ss2zpk`
     |
     |      Returns
     |      -------
     |      sys : instance of `ZerosPolesGain`
     |          Zeros, poles, gain representation of the current system
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, *system, **kwargs)
     |      Create new StateSpace object and settle inheritance.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  A
     |      State matrix of the `StateSpace` system.
     |
     |  B
     |      Input matrix of the `StateSpace` system.
     |
     |  C
     |      Output matrix of the `StateSpace` system.
     |
     |  D
     |      Feedthrough matrix of the `StateSpace` system.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __array_priority__ = 100.0
     |
     |  __array_ufunc__ = None
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from LinearTimeInvariant:
     |
     |  dt
     |      Return the sampling time of the system, `None` for `lti` systems.
     |
     |  poles
     |      Poles of the system.
     |
     |  zeros
     |      Zeros of the system.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from LinearTimeInvariant:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class TransferFunction(LinearTimeInvariant)
     |  TransferFunction(*system, **kwargs)
     |
     |  Linear Time Invariant system class in transfer function form.
     |
     |  Represents the system as the continuous-time transfer function
     |  :math:`H(s)=\sum_{i=0}^N b[N-i] s^i / \sum_{j=0}^M a[M-j] s^j` or the
     |  discrete-time transfer function
     |  :math:`H(z)=\sum_{i=0}^N b[N-i] z^i / \sum_{j=0}^M a[M-j] z^j`, where
     |  :math:`b` are elements of the numerator `num`, :math:`a` are elements of
     |  the denominator `den`, and ``N == len(b) - 1``, ``M == len(a) - 1``.
     |  `TransferFunction` systems inherit additional
     |  functionality from the `lti`, respectively the `dlti` classes, depending on
     |  which system representation is used.
     |
     |  Parameters
     |  ----------
     |  *system: arguments
     |      The `TransferFunction` class can be instantiated with 1 or 2
     |      arguments. The following gives the number of input arguments and their
     |      interpretation:
     |
     |          * 1: `lti` or `dlti` system: (`StateSpace`, `TransferFunction` or
     |            `ZerosPolesGain`)
     |          * 2: array_like: (numerator, denominator)
     |  dt: float, optional
     |      Sampling time [s] of the discrete-time systems. Defaults to `None`
     |      (continuous-time). Must be specified as a keyword argument, for
     |      example, ``dt=0.1``.
     |
     |  See Also
     |  --------
     |  ZerosPolesGain, StateSpace, lti, dlti
     |  tf2ss, tf2zpk, tf2sos
     |
     |  Notes
     |  -----
     |  Changing the value of properties that are not part of the
     |  `TransferFunction` system representation (such as the `A`, `B`, `C`, `D`
     |  state-space matrices) is very inefficient and may lead to numerical
     |  inaccuracies.  It is better to convert to the specific system
     |  representation first. For example, call ``sys = sys.to_ss()`` before
     |  accessing/changing the A, B, C, D system matrices.
     |
     |  If (numerator, denominator) is passed in for ``*system``, coefficients
     |  for both the numerator and denominator should be specified in descending
     |  exponent order (e.g. ``s^2 + 3s + 5`` or ``z^2 + 3z + 5`` would be
     |  represented as ``[1, 3, 5]``)
     |
     |  Examples
     |  --------
     |  Construct the transfer function
     |  :math:`H(s) = \frac{s^2 + 3s + 3}{s^2 + 2s + 1}`:
     |
     |  >>> from scipy import signal
     |
     |  >>> num = [1, 3, 3]
     |  >>> den = [1, 2, 1]
     |
     |  >>> signal.TransferFunction(num, den)
     |  TransferFunctionContinuous(
     |  array([1., 3., 3.]),
     |  array([1., 2., 1.]),
     |  dt: None
     |  )
     |
     |  Construct the transfer function
     |  :math:`H(z) = \frac{z^2 + 3z + 3}{z^2 + 2z + 1}` with a sampling time of
     |  0.1 seconds:
     |
     |  >>> signal.TransferFunction(num, den, dt=0.1)
     |  TransferFunctionDiscrete(
     |  array([1., 3., 3.]),
     |  array([1., 2., 1.]),
     |  dt: 0.1
     |  )
     |
     |  Method resolution order:
     |      TransferFunction
     |      LinearTimeInvariant
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, *system, **kwargs)
     |      Initialize the state space LTI system.
     |
     |  __repr__(self)
     |      Return representation of the system's transfer function
     |
     |  to_ss(self)
     |      Convert system representation to `StateSpace`.
     |
     |      Returns
     |      -------
     |      sys : instance of `StateSpace`
     |          State space model of the current system
     |
     |  to_tf(self)
     |      Return a copy of the current `TransferFunction` system.
     |
     |      Returns
     |      -------
     |      sys : instance of `TransferFunction`
     |          The current system (copy)
     |
     |  to_zpk(self)
     |      Convert system representation to `ZerosPolesGain`.
     |
     |      Returns
     |      -------
     |      sys : instance of `ZerosPolesGain`
     |          Zeros, poles, gain representation of the current system
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, *system, **kwargs)
     |      Handle object conversion if input is an instance of lti.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  den
     |      Denominator of the `TransferFunction` system.
     |
     |  num
     |      Numerator of the `TransferFunction` system.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from LinearTimeInvariant:
     |
     |  dt
     |      Return the sampling time of the system, `None` for `lti` systems.
     |
     |  poles
     |      Poles of the system.
     |
     |  zeros
     |      Zeros of the system.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from LinearTimeInvariant:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ZerosPolesGain(LinearTimeInvariant)
     |  ZerosPolesGain(*system, **kwargs)
     |
     |  Linear Time Invariant system class in zeros, poles, gain form.
     |
     |  Represents the system as the continuous- or discrete-time transfer function
     |  :math:`H(s)=k \prod_i (s - z[i]) / \prod_j (s - p[j])`, where :math:`k` is
     |  the `gain`, :math:`z` are the `zeros` and :math:`p` are the `poles`.
     |  `ZerosPolesGain` systems inherit additional functionality from the `lti`,
     |  respectively the `dlti` classes, depending on which system representation
     |  is used.
     |
     |  Parameters
     |  ----------
     |  *system : arguments
     |      The `ZerosPolesGain` class can be instantiated with 1 or 3
     |      arguments. The following gives the number of input arguments and their
     |      interpretation:
     |
     |          * 1: `lti` or `dlti` system: (`StateSpace`, `TransferFunction` or
     |            `ZerosPolesGain`)
     |          * 3: array_like: (zeros, poles, gain)
     |  dt: float, optional
     |      Sampling time [s] of the discrete-time systems. Defaults to `None`
     |      (continuous-time). Must be specified as a keyword argument, for
     |      example, ``dt=0.1``.
     |
     |
     |  See Also
     |  --------
     |  TransferFunction, StateSpace, lti, dlti
     |  zpk2ss, zpk2tf, zpk2sos
     |
     |  Notes
     |  -----
     |  Changing the value of properties that are not part of the
     |  `ZerosPolesGain` system representation (such as the `A`, `B`, `C`, `D`
     |  state-space matrices) is very inefficient and may lead to numerical
     |  inaccuracies.  It is better to convert to the specific system
     |  representation first. For example, call ``sys = sys.to_ss()`` before
     |  accessing/changing the A, B, C, D system matrices.
     |
     |  Examples
     |  --------
     |  Construct the transfer function
     |  :math:`H(s) = \frac{5(s - 1)(s - 2)}{(s - 3)(s - 4)}`:
     |
     |  >>> from scipy import signal
     |
     |  >>> signal.ZerosPolesGain([1, 2], [3, 4], 5)
     |  ZerosPolesGainContinuous(
     |  array([1, 2]),
     |  array([3, 4]),
     |  5,
     |  dt: None
     |  )
     |
     |  Construct the transfer function
     |  :math:`H(z) = \frac{5(z - 1)(z - 2)}{(z - 3)(z - 4)}` with a sampling time
     |  of 0.1 seconds:
     |
     |  >>> signal.ZerosPolesGain([1, 2], [3, 4], 5, dt=0.1)
     |  ZerosPolesGainDiscrete(
     |  array([1, 2]),
     |  array([3, 4]),
     |  5,
     |  dt: 0.1
     |  )
     |
     |  Method resolution order:
     |      ZerosPolesGain
     |      LinearTimeInvariant
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, *system, **kwargs)
     |      Initialize the zeros, poles, gain system.
     |
     |  __repr__(self)
     |      Return representation of the `ZerosPolesGain` system.
     |
     |  to_ss(self)
     |      Convert system representation to `StateSpace`.
     |
     |      Returns
     |      -------
     |      sys : instance of `StateSpace`
     |          State space model of the current system
     |
     |  to_tf(self)
     |      Convert system representation to `TransferFunction`.
     |
     |      Returns
     |      -------
     |      sys : instance of `TransferFunction`
     |          Transfer function of the current system
     |
     |  to_zpk(self)
     |      Return a copy of the current 'ZerosPolesGain' system.
     |
     |      Returns
     |      -------
     |      sys : instance of `ZerosPolesGain`
     |          The current system (copy)
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, *system, **kwargs)
     |      Handle object conversion if input is an instance of `lti`
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  gain
     |      Gain of the `ZerosPolesGain` system.
     |
     |  poles
     |      Poles of the `ZerosPolesGain` system.
     |
     |  zeros
     |      Zeros of the `ZerosPolesGain` system.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from LinearTimeInvariant:
     |
     |  dt
     |      Return the sampling time of the system, `None` for `lti` systems.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from LinearTimeInvariant:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ZoomFFT(CZT)
     |  ZoomFFT(n, fn, m=None, *, fs=2, endpoint=False)
     |
     |  Create a callable zoom FFT transform function.
     |
     |  This is a specialization of the chirp z-transform (`CZT`) for a set of
     |  equally-spaced frequencies around the unit circle, used to calculate a
     |  section of the FFT more efficiently than calculating the entire FFT and
     |  truncating.
     |
     |  Parameters
     |  ----------
     |  n : int
     |      The size of the signal.
     |  fn : array_like
     |      A length-2 sequence [`f1`, `f2`] giving the frequency range, or a
     |      scalar, for which the range [0, `fn`] is assumed.
     |  m : int, optional
     |      The number of points to evaluate.  Default is `n`.
     |  fs : float, optional
     |      The sampling frequency.  If ``fs=10`` represented 10 kHz, for example,
     |      then `f1` and `f2` would also be given in kHz.
     |      The default sampling frequency is 2, so `f1` and `f2` should be
     |      in the range [0, 1] to keep the transform below the Nyquist
     |      frequency.
     |  endpoint : bool, optional
     |      If True, `f2` is the last sample. Otherwise, it is not included.
     |      Default is False.
     |
     |  Returns
     |  -------
     |  f : ZoomFFT
     |      Callable object ``f(x, axis=-1)`` for computing the zoom FFT on `x`.
     |
     |  See Also
     |  --------
     |  zoom_fft : Convenience function for calculating a zoom FFT.
     |
     |  Notes
     |  -----
     |  The defaults are chosen such that ``f(x, 2)`` is equivalent to
     |  ``fft.fft(x)`` and, if ``m > len(x)``, that ``f(x, 2, m)`` is equivalent to
     |  ``fft.fft(x, m)``.
     |
     |  Sampling frequency is 1/dt, the time step between samples in the
     |  signal `x`.  The unit circle corresponds to frequencies from 0 up
     |  to the sampling frequency.  The default sampling frequency of 2
     |  means that `f1`, `f2` values up to the Nyquist frequency are in the
     |  range [0, 1). For `f1`, `f2` values expressed in radians, a sampling
     |  frequency of 2*pi should be used.
     |
     |  Remember that a zoom FFT can only interpolate the points of the existing
     |  FFT.  It cannot help to resolve two separate nearby frequencies.
     |  Frequency resolution can only be increased by increasing acquisition
     |  time.
     |
     |  These functions are implemented using Bluestein's algorithm (as is
     |  `scipy.fft`). [2]_
     |
     |  References
     |  ----------
     |  .. [1] Steve Alan Shilling, "A study of the chirp z-transform and its
     |         applications", pg 29 (1970)
     |         https://krex.k-state.edu/dspace/bitstream/handle/2097/7844/LD2668R41972S43.pdf
     |  .. [2] Leo I. Bluestein, "A linear filtering approach to the computation
     |         of the discrete Fourier transform," Northeast Electronics Research
     |         and Engineering Meeting Record 10, 218-219 (1968).
     |
     |  Examples
     |  --------
     |  To plot the transform results use something like the following:
     |
     |  >>> import numpy as np
     |  >>> from scipy.signal import ZoomFFT
     |  >>> t = np.linspace(0, 1, 1021)
     |  >>> x = np.cos(2*np.pi*15*t) + np.sin(2*np.pi*17*t)
     |  >>> f1, f2 = 5, 27
     |  >>> transform = ZoomFFT(len(x), [f1, f2], len(x), fs=1021)
     |  >>> X = transform(x)
     |  >>> f = np.linspace(f1, f2, len(x))
     |  >>> import matplotlib.pyplot as plt
     |  >>> plt.plot(f, 20*np.log10(np.abs(X)))
     |  >>> plt.show()
     |
     |  Method resolution order:
     |      ZoomFFT
     |      CZT
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, n, fn, m=None, *, fs=2, endpoint=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from CZT:
     |
     |  __call__(self, x, *, axis=-1)
     |      Calculate the chirp z-transform of a signal.
     |
     |      Parameters
     |      ----------
     |      x : array
     |          The signal to transform.
     |      axis : int, optional
     |          Axis over which to compute the FFT. If not given, the last axis is
     |          used.
     |
     |      Returns
     |      -------
     |      out : ndarray
     |          An array of the same dimensions as `x`, but with the length of the
     |          transformed axis set to `m`.
     |
     |  points(self)
     |      Return the points at which the chirp z-transform is computed.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from CZT:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class dlti(LinearTimeInvariant)
     |  dlti(*system, **kwargs)
     |
     |  Discrete-time linear time invariant system base class.
     |
     |  Parameters
     |  ----------
     |  *system: arguments
     |      The `dlti` class can be instantiated with either 2, 3 or 4 arguments.
     |      The following gives the number of arguments and the corresponding
     |      discrete-time subclass that is created:
     |
     |          * 2: `TransferFunction`:  (numerator, denominator)
     |          * 3: `ZerosPolesGain`: (zeros, poles, gain)
     |          * 4: `StateSpace`:  (A, B, C, D)
     |
     |      Each argument can be an array or a sequence.
     |  dt: float, optional
     |      Sampling time [s] of the discrete-time systems. Defaults to ``True``
     |      (unspecified sampling time). Must be specified as a keyword argument,
     |      for example, ``dt=0.1``.
     |
     |  See Also
     |  --------
     |  ZerosPolesGain, StateSpace, TransferFunction, lti
     |
     |  Notes
     |  -----
     |  `dlti` instances do not exist directly. Instead, `dlti` creates an instance
     |  of one of its subclasses: `StateSpace`, `TransferFunction` or
     |  `ZerosPolesGain`.
     |
     |  Changing the value of properties that are not directly part of the current
     |  system representation (such as the `zeros` of a `StateSpace` system) is
     |  very inefficient and may lead to numerical inaccuracies.  It is better to
     |  convert to the specific system representation first. For example, call
     |  ``sys = sys.to_zpk()`` before accessing/changing the zeros, poles or gain.
     |
     |  If (numerator, denominator) is passed in for ``*system``, coefficients for
     |  both the numerator and denominator should be specified in descending
     |  exponent order (e.g., ``z^2 + 3z + 5`` would be represented as ``[1, 3,
     |  5]``).
     |
     |  .. versionadded:: 0.18.0
     |
     |  Examples
     |  --------
     |  >>> from scipy import signal
     |
     |  >>> signal.dlti(1, 2, 3, 4)
     |  StateSpaceDiscrete(
     |  array([[1]]),
     |  array([[2]]),
     |  array([[3]]),
     |  array([[4]]),
     |  dt: True
     |  )
     |
     |  >>> signal.dlti(1, 2, 3, 4, dt=0.1)
     |  StateSpaceDiscrete(
     |  array([[1]]),
     |  array([[2]]),
     |  array([[3]]),
     |  array([[4]]),
     |  dt: 0.1
     |  )
     |
     |  Construct the transfer function
     |  :math:`H(z) = \frac{5(z - 1)(z - 2)}{(z - 3)(z - 4)}` with a sampling time
     |  of 0.1 seconds:
     |
     |  >>> signal.dlti([1, 2], [3, 4], 5, dt=0.1)
     |  ZerosPolesGainDiscrete(
     |  array([1, 2]),
     |  array([3, 4]),
     |  5,
     |  dt: 0.1
     |  )
     |
     |  Construct the transfer function :math:`H(z) = \frac{3z + 4}{1z + 2}` with
     |  a sampling time of 0.1 seconds:
     |
     |  >>> signal.dlti([3, 4], [1, 2], dt=0.1)
     |  TransferFunctionDiscrete(
     |  array([3., 4.]),
     |  array([1., 2.]),
     |  dt: 0.1
     |  )
     |
     |  Method resolution order:
     |      dlti
     |      LinearTimeInvariant
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, *system, **kwargs)
     |      Initialize the `lti` baseclass.
     |
     |      The heavy lifting is done by the subclasses.
     |
     |  bode(self, w=None, n=100)
     |      Calculate Bode magnitude and phase data of a discrete-time system.
     |
     |      Returns a 3-tuple containing arrays of frequencies [rad/s], magnitude
     |      [dB] and phase [deg]. See `dbode` for details.
     |
     |      Examples
     |      --------
     |      >>> from scipy import signal
     |      >>> import matplotlib.pyplot as plt
     |
     |      Construct the transfer function :math:`H(z) = \frac{1}{z^2 + 2z + 3}`
     |      with sampling time 0.5s:
     |
     |      >>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.5)
     |
     |      Equivalent: signal.dbode(sys)
     |
     |      >>> w, mag, phase = sys.bode()
     |
     |      >>> plt.figure()
     |      >>> plt.semilogx(w, mag)    # Bode magnitude plot
     |      >>> plt.figure()
     |      >>> plt.semilogx(w, phase)  # Bode phase plot
     |      >>> plt.show()
     |
     |  freqresp(self, w=None, n=10000, whole=False)
     |      Calculate the frequency response of a discrete-time system.
     |
     |      Returns a 2-tuple containing arrays of frequencies [rad/s] and
     |      complex magnitude.
     |      See `dfreqresp` for details.
     |
     |  impulse(self, x0=None, t=None, n=None)
     |      Return the impulse response of the discrete-time `dlti` system.
     |      See `dimpulse` for details.
     |
     |  output(self, u, t, x0=None)
     |      Return the response of the discrete-time system to input `u`.
     |      See `dlsim` for details.
     |
     |  step(self, x0=None, t=None, n=None)
     |      Return the step response of the discrete-time `dlti` system.
     |      See `dstep` for details.
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, *system, **kwargs)
     |      Create an instance of the appropriate subclass.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  dt
     |      Return the sampling time of the system.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from LinearTimeInvariant:
     |
     |  poles
     |      Poles of the system.
     |
     |  zeros
     |      Zeros of the system.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from LinearTimeInvariant:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class lti(LinearTimeInvariant)
     |  lti(*system)
     |
     |  Continuous-time linear time invariant system base class.
     |
     |  Parameters
     |  ----------
     |  *system : arguments
     |      The `lti` class can be instantiated with either 2, 3 or 4 arguments.
     |      The following gives the number of arguments and the corresponding
     |      continuous-time subclass that is created:
     |
     |          * 2: `TransferFunction`:  (numerator, denominator)
     |          * 3: `ZerosPolesGain`: (zeros, poles, gain)
     |          * 4: `StateSpace`:  (A, B, C, D)
     |
     |      Each argument can be an array or a sequence.
     |
     |  See Also
     |  --------
     |  ZerosPolesGain, StateSpace, TransferFunction, dlti
     |
     |  Notes
     |  -----
     |  `lti` instances do not exist directly. Instead, `lti` creates an instance
     |  of one of its subclasses: `StateSpace`, `TransferFunction` or
     |  `ZerosPolesGain`.
     |
     |  If (numerator, denominator) is passed in for ``*system``, coefficients for
     |  both the numerator and denominator should be specified in descending
     |  exponent order (e.g., ``s^2 + 3s + 5`` would be represented as ``[1, 3,
     |  5]``).
     |
     |  Changing the value of properties that are not directly part of the current
     |  system representation (such as the `zeros` of a `StateSpace` system) is
     |  very inefficient and may lead to numerical inaccuracies. It is better to
     |  convert to the specific system representation first. For example, call
     |  ``sys = sys.to_zpk()`` before accessing/changing the zeros, poles or gain.
     |
     |  Examples
     |  --------
     |  >>> from scipy import signal
     |
     |  >>> signal.lti(1, 2, 3, 4)
     |  StateSpaceContinuous(
     |  array([[1]]),
     |  array([[2]]),
     |  array([[3]]),
     |  array([[4]]),
     |  dt: None
     |  )
     |
     |  Construct the transfer function
     |  :math:`H(s) = \frac{5(s - 1)(s - 2)}{(s - 3)(s - 4)}`:
     |
     |  >>> signal.lti([1, 2], [3, 4], 5)
     |  ZerosPolesGainContinuous(
     |  array([1, 2]),
     |  array([3, 4]),
     |  5,
     |  dt: None
     |  )
     |
     |  Construct the transfer function :math:`H(s) = \frac{3s + 4}{1s + 2}`:
     |
     |  >>> signal.lti([3, 4], [1, 2])
     |  TransferFunctionContinuous(
     |  array([3., 4.]),
     |  array([1., 2.]),
     |  dt: None
     |  )
     |
     |  Method resolution order:
     |      lti
     |      LinearTimeInvariant
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, *system)
     |      Initialize the `lti` baseclass.
     |
     |      The heavy lifting is done by the subclasses.
     |
     |  bode(self, w=None, n=100)
     |      Calculate Bode magnitude and phase data of a continuous-time system.
     |
     |      Returns a 3-tuple containing arrays of frequencies [rad/s], magnitude
     |      [dB] and phase [deg]. See `bode` for details.
     |
     |      Examples
     |      --------
     |      >>> from scipy import signal
     |      >>> import matplotlib.pyplot as plt
     |
     |      >>> sys = signal.TransferFunction([1], [1, 1])
     |      >>> w, mag, phase = sys.bode()
     |
     |      >>> plt.figure()
     |      >>> plt.semilogx(w, mag)    # Bode magnitude plot
     |      >>> plt.figure()
     |      >>> plt.semilogx(w, phase)  # Bode phase plot
     |      >>> plt.show()
     |
     |  freqresp(self, w=None, n=10000)
     |      Calculate the frequency response of a continuous-time system.
     |
     |      Returns a 2-tuple containing arrays of frequencies [rad/s] and
     |      complex magnitude.
     |      See `freqresp` for details.
     |
     |  impulse(self, X0=None, T=None, N=None)
     |      Return the impulse response of a continuous-time system.
     |      See `impulse` for details.
     |
     |  output(self, U, T, X0=None)
     |      Return the response of a continuous-time system to input `U`.
     |      See `lsim` for details.
     |
     |  step(self, X0=None, T=None, N=None)
     |      Return the step response of a continuous-time system.
     |      See `step` for details.
     |
     |  to_discrete(self, dt, method='zoh', alpha=None)
     |      Return a discretized version of the current system.
     |
     |      Parameters: See `cont2discrete` for details.
     |
     |      Returns
     |      -------
     |      sys: instance of `dlti`
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, *system)
     |      Create an instance of the appropriate subclass.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from LinearTimeInvariant:
     |
     |  dt
     |      Return the sampling time of the system, `None` for `lti` systems.
     |
     |  poles
     |      Poles of the system.
     |
     |  zeros
     |      Zeros of the system.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from LinearTimeInvariant:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    abcd_normalize(A=None, B=None, C=None, D=None)
        Check state-space matrices and ensure they are 2-D.

        If enough information on the system is provided, that is, enough
        properly-shaped arrays are passed to the function, the missing ones
        are built from this information, ensuring the correct number of
        rows and columns. Otherwise a ValueError is raised.

        Parameters
        ----------
        A, B, C, D : array_like, optional
            State-space matrices. All of them are None (missing) by default.
            See `ss2tf` for format.

        Returns
        -------
        A, B, C, D : array
            Properly shaped state-space matrices.

        Raises
        ------
        ValueError
            If not enough information on the system was provided.

    argrelextrema(data, comparator, axis=0, order=1, mode='clip')
        Calculate the relative extrema of `data`.

        Parameters
        ----------
        data : ndarray
            Array in which to find the relative extrema.
        comparator : callable
            Function to use to compare two data points.
            Should take two arrays as arguments.
        axis : int, optional
            Axis over which to select from `data`. Default is 0.
        order : int, optional
            How many points on each side to use for the comparison
            to consider ``comparator(n, n+x)`` to be True.
        mode : str, optional
            How the edges of the vector are treated. 'wrap' (wrap around) or
            'clip' (treat overflow as the same as the last (or first) element).
            Default is 'clip'. See `numpy.take`.

        Returns
        -------
        extrema : tuple of ndarrays
            Indices of the maxima in arrays of integers. ``extrema[k]`` is
            the array of indices of axis `k` of `data`. Note that the
            return value is a tuple even when `data` is 1-D.

        See Also
        --------
        argrelmin, argrelmax

        Notes
        -----

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import argrelextrema
        >>> x = np.array([2, 1, 2, 3, 2, 0, 1, 0])
        >>> argrelextrema(x, np.greater)
        (array([3, 6]),)
        >>> y = np.array([[1, 2, 1, 2],
        ...               [2, 2, 0, 0],
        ...               [5, 3, 4, 4]])
        ...
        >>> argrelextrema(y, np.less, axis=1)
        (array([0, 2]), array([2, 1]))

    argrelmax(data, axis=0, order=1, mode='clip')
        Calculate the relative maxima of `data`.

        Parameters
        ----------
        data : ndarray
            Array in which to find the relative maxima.
        axis : int, optional
            Axis over which to select from `data`. Default is 0.
        order : int, optional
            How many points on each side to use for the comparison
            to consider ``comparator(n, n+x)`` to be True.
        mode : str, optional
            How the edges of the vector are treated.
            Available options are 'wrap' (wrap around) or 'clip' (treat overflow
            as the same as the last (or first) element).
            Default 'clip'. See `numpy.take`.

        Returns
        -------
        extrema : tuple of ndarrays
            Indices of the maxima in arrays of integers. ``extrema[k]`` is
            the array of indices of axis `k` of `data`. Note that the
            return value is a tuple even when `data` is 1-D.

        See Also
        --------
        argrelextrema, argrelmin, find_peaks

        Notes
        -----
        This function uses `argrelextrema` with np.greater as comparator. Therefore,
        it  requires a strict inequality on both sides of a value to consider it a
        maximum. This means flat maxima (more than one sample wide) are not detected.
        In case of 1-D `data` `find_peaks` can be used to detect all
        local maxima, including flat ones.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import argrelmax
        >>> x = np.array([2, 1, 2, 3, 2, 0, 1, 0])
        >>> argrelmax(x)
        (array([3, 6]),)
        >>> y = np.array([[1, 2, 1, 2],
        ...               [2, 2, 0, 0],
        ...               [5, 3, 4, 4]])
        ...
        >>> argrelmax(y, axis=1)
        (array([0]), array([1]))

    argrelmin(data, axis=0, order=1, mode='clip')
        Calculate the relative minima of `data`.

        Parameters
        ----------
        data : ndarray
            Array in which to find the relative minima.
        axis : int, optional
            Axis over which to select from `data`. Default is 0.
        order : int, optional
            How many points on each side to use for the comparison
            to consider ``comparator(n, n+x)`` to be True.
        mode : str, optional
            How the edges of the vector are treated.
            Available options are 'wrap' (wrap around) or 'clip' (treat overflow
            as the same as the last (or first) element).
            Default 'clip'. See numpy.take.

        Returns
        -------
        extrema : tuple of ndarrays
            Indices of the minima in arrays of integers. ``extrema[k]`` is
            the array of indices of axis `k` of `data`. Note that the
            return value is a tuple even when `data` is 1-D.

        See Also
        --------
        argrelextrema, argrelmax, find_peaks

        Notes
        -----
        This function uses `argrelextrema` with np.less as comparator. Therefore, it
        requires a strict inequality on both sides of a value to consider it a
        minimum. This means flat minima (more than one sample wide) are not detected.
        In case of 1-D `data` `find_peaks` can be used to detect all
        local minima, including flat ones, by calling it with negated `data`.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import argrelmin
        >>> x = np.array([2, 1, 2, 3, 2, 0, 1, 0])
        >>> argrelmin(x)
        (array([1, 5]),)
        >>> y = np.array([[1, 2, 1, 2],
        ...               [2, 2, 0, 0],
        ...               [5, 3, 4, 4]])
        ...
        >>> argrelmin(y, axis=1)
        (array([0, 2]), array([2, 1]))

    band_stop_obj(wp, ind, passb, stopb, gpass, gstop, type)
        Band Stop Objective Function for order minimization.

        Returns the non-integer order for an analog band stop filter.

        Parameters
        ----------
        wp : scalar
            Edge of passband `passb`.
        ind : int, {0, 1}
            Index specifying which `passb` edge to vary (0 or 1).
        passb : ndarray
            Two element sequence of fixed passband edges.
        stopb : ndarray
            Two element sequence of fixed stopband edges.
        gstop : float
            Amount of attenuation in stopband in dB.
        gpass : float
            Amount of ripple in the passband in dB.
        type : {'butter', 'cheby', 'ellip'}
            Type of filter.

        Returns
        -------
        n : scalar
            Filter order (possibly non-integer).

    bessel(N, Wn, btype='low', analog=False, output='ba', norm='phase', fs=None)
        Bessel/Thomson digital and analog filter design.

        Design an Nth-order digital or analog Bessel filter and return the
        filter coefficients.

        Parameters
        ----------
        N : int
            The order of the filter.
        Wn : array_like
            A scalar or length-2 sequence giving the critical frequencies (defined
            by the `norm` parameter).
            For analog filters, `Wn` is an angular frequency (e.g., rad/s).

            For digital filters, `Wn` are in the same units as `fs`.  By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`Wn` is thus in
            half-cycles / sample.)
        btype : {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optional
            The type of filter.  Default is 'lowpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned. (See Notes.)
        output : {'ba', 'zpk', 'sos'}, optional
            Type of output:  numerator/denominator ('ba'), pole-zero ('zpk'), or
            second-order sections ('sos'). Default is 'ba'.
        norm : {'phase', 'delay', 'mag'}, optional
            Critical frequency normalization:

            ``phase``
                The filter is normalized such that the phase response reaches its
                midpoint at angular (e.g. rad/s) frequency `Wn`. This happens for
                both low-pass and high-pass filters, so this is the
                "phase-matched" case.

                The magnitude response asymptotes are the same as a Butterworth
                filter of the same order with a cutoff of `Wn`.

                This is the default, and matches MATLAB's implementation.

            ``delay``
                The filter is normalized such that the group delay in the passband
                is 1/`Wn` (e.g., seconds). This is the "natural" type obtained by
                solving Bessel polynomials.

            ``mag``
                The filter is normalized such that the gain magnitude is -3 dB at
                angular frequency `Wn`.

            .. versionadded:: 0.18.0
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        Notes
        -----
        Also known as a Thomson filter, the analog Bessel filter has maximally
        flat group delay and maximally linear phase response, with very little
        ringing in the step response. [1]_

        The Bessel is inherently an analog filter. This function generates digital
        Bessel filters using the bilinear transform, which does not preserve the
        phase response of the analog filter. As such, it is only approximately
        correct at frequencies below about fs/4. To get maximally-flat group
        delay at higher frequencies, the analog Bessel filter must be transformed
        using phase-preserving techniques.

        See `besselap` for implementation details and references.

        The ``'sos'`` output parameter was added in 0.16.0.

        References
        ----------
        .. [1] Thomson, W.E., "Delay Networks having Maximally Flat Frequency
               Characteristics", Proceedings of the Institution of Electrical
               Engineers, Part III, November 1949, Vol. 96, No. 44, pp. 487-490.

        Examples
        --------
        Plot the phase-normalized frequency response, showing the relationship
        to the Butterworth's cutoff frequency (green):

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.butter(4, 100, 'low', analog=True)
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(np.abs(h)), color='silver', ls='dashed')
        >>> b, a = signal.bessel(4, 100, 'low', analog=True, norm='phase')
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(np.abs(h)))
        >>> plt.title('Bessel filter magnitude response (with Butterworth)')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(100, color='green')  # cutoff frequency
        >>> plt.show()

        and the phase midpoint:

        >>> plt.figure()
        >>> plt.semilogx(w, np.unwrap(np.angle(h)))
        >>> plt.axvline(100, color='green')  # cutoff frequency
        >>> plt.axhline(-np.pi, color='red')  # phase midpoint
        >>> plt.title('Bessel filter phase response')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Phase [radians]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.show()

        Plot the magnitude-normalized frequency response, showing the -3 dB cutoff:

        >>> b, a = signal.bessel(3, 10, 'low', analog=True, norm='mag')
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(np.abs(h)))
        >>> plt.axhline(-3, color='red')  # -3 dB magnitude
        >>> plt.axvline(10, color='green')  # cutoff frequency
        >>> plt.title('Magnitude-normalized Bessel filter frequency response')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.show()

        Plot the delay-normalized filter, showing the maximally-flat group delay
        at 0.1 seconds:

        >>> b, a = signal.bessel(5, 1/0.1, 'low', analog=True, norm='delay')
        >>> w, h = signal.freqs(b, a)
        >>> plt.figure()
        >>> plt.semilogx(w[1:], -np.diff(np.unwrap(np.angle(h)))/np.diff(w))
        >>> plt.axhline(0.1, color='red')  # 0.1 seconds group delay
        >>> plt.title('Bessel filter group delay')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Group delay [seconds]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.show()

    besselap(N, norm='phase')
        Return (z,p,k) for analog prototype of an Nth-order Bessel filter.

        Parameters
        ----------
        N : int
            The order of the filter.
        norm : {'phase', 'delay', 'mag'}, optional
            Frequency normalization:

            ``phase``
                The filter is normalized such that the phase response reaches its
                midpoint at an angular (e.g., rad/s) cutoff frequency of 1. This
                happens for both low-pass and high-pass filters, so this is the
                "phase-matched" case. [6]_

                The magnitude response asymptotes are the same as a Butterworth
                filter of the same order with a cutoff of `Wn`.

                This is the default, and matches MATLAB's implementation.

            ``delay``
                The filter is normalized such that the group delay in the passband
                is 1 (e.g., 1 second). This is the "natural" type obtained by
                solving Bessel polynomials

            ``mag``
                The filter is normalized such that the gain magnitude is -3 dB at
                angular frequency 1. This is called "frequency normalization" by
                Bond. [1]_

            .. versionadded:: 0.18.0

        Returns
        -------
        z : ndarray
            Zeros of the transfer function. Is always an empty array.
        p : ndarray
            Poles of the transfer function.
        k : scalar
            Gain of the transfer function. For phase-normalized, this is always 1.

        See Also
        --------
        bessel : Filter design function using this prototype

        Notes
        -----
        To find the pole locations, approximate starting points are generated [2]_
        for the zeros of the ordinary Bessel polynomial [3]_, then the
        Aberth-Ehrlich method [4]_ [5]_ is used on the Kv(x) Bessel function to
        calculate more accurate zeros, and these locations are then inverted about
        the unit circle.

        References
        ----------
        .. [1] C.R. Bond, "Bessel Filter Constants",
               http://www.crbond.com/papers/bsf.pdf
        .. [2] Campos and Calderon, "Approximate closed-form formulas for the
               zeros of the Bessel Polynomials", :arXiv:`1105.0957`.
        .. [3] Thomson, W.E., "Delay Networks having Maximally Flat Frequency
               Characteristics", Proceedings of the Institution of Electrical
               Engineers, Part III, November 1949, Vol. 96, No. 44, pp. 487-490.
        .. [4] Aberth, "Iteration Methods for Finding all Zeros of a Polynomial
               Simultaneously", Mathematics of Computation, Vol. 27, No. 122,
               April 1973
        .. [5] Ehrlich, "A modified Newton method for polynomials", Communications
               of the ACM, Vol. 10, Issue 2, pp. 107-108, Feb. 1967,
               :DOI:`10.1145/363067.363115`
        .. [6] Miller and Bohn, "A Bessel Filter Crossover, and Its Relation to
               Others", RaneNote 147, 1998,
               https://www.ranecommercial.com/legacy/note147.html

    bilinear(b, a, fs=1.0)
        Return a digital IIR filter from an analog one using a bilinear transform.

        Transform a set of poles and zeros from the analog s-plane to the digital
        z-plane using Tustin's method, which substitutes ``2*fs*(z-1) / (z+1)`` for
        ``s``, maintaining the shape of the frequency response.

        Parameters
        ----------
        b : array_like
            Numerator of the analog filter transfer function.
        a : array_like
            Denominator of the analog filter transfer function.
        fs : float
            Sample rate, as ordinary frequency (e.g., hertz). No prewarping is
            done in this function.

        Returns
        -------
        b : ndarray
            Numerator of the transformed digital filter transfer function.
        a : ndarray
            Denominator of the transformed digital filter transfer function.

        See Also
        --------
        lp2lp, lp2hp, lp2bp, lp2bs
        bilinear_zpk

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> fs = 100
        >>> bf = 2 * np.pi * np.array([7, 13])
        >>> filts = signal.lti(*signal.butter(4, bf, btype='bandpass',
        ...                                   analog=True))
        >>> filtz = signal.lti(*signal.bilinear(filts.num, filts.den, fs))
        >>> wz, hz = signal.freqz(filtz.num, filtz.den)
        >>> ws, hs = signal.freqs(filts.num, filts.den, worN=fs*wz)

        >>> plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hz).clip(1e-15)),
        ...              label=r'$|H_z(e^{j \omega})|$')
        >>> plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hs).clip(1e-15)),
        ...              label=r'$|H(j \omega)|$')
        >>> plt.legend()
        >>> plt.xlabel('Frequency [Hz]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.grid(True)

    bilinear_zpk(z, p, k, fs)
        Return a digital IIR filter from an analog one using a bilinear transform.

        Transform a set of poles and zeros from the analog s-plane to the digital
        z-plane using Tustin's method, which substitutes ``2*fs*(z-1) / (z+1)`` for
        ``s``, maintaining the shape of the frequency response.

        Parameters
        ----------
        z : array_like
            Zeros of the analog filter transfer function.
        p : array_like
            Poles of the analog filter transfer function.
        k : float
            System gain of the analog filter transfer function.
        fs : float
            Sample rate, as ordinary frequency (e.g., hertz). No prewarping is
            done in this function.

        Returns
        -------
        z : ndarray
            Zeros of the transformed digital filter transfer function.
        p : ndarray
            Poles of the transformed digital filter transfer function.
        k : float
            System gain of the transformed digital filter.

        See Also
        --------
        lp2lp_zpk, lp2hp_zpk, lp2bp_zpk, lp2bs_zpk
        bilinear

        Notes
        -----
        .. versionadded:: 1.1.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> fs = 100
        >>> bf = 2 * np.pi * np.array([7, 13])
        >>> filts = signal.lti(*signal.butter(4, bf, btype='bandpass', analog=True,
        ...                                   output='zpk'))
        >>> filtz = signal.lti(*signal.bilinear_zpk(filts.zeros, filts.poles,
        ...                                         filts.gain, fs))
        >>> wz, hz = signal.freqz_zpk(filtz.zeros, filtz.poles, filtz.gain)
        >>> ws, hs = signal.freqs_zpk(filts.zeros, filts.poles, filts.gain,
        ...                           worN=fs*wz)
        >>> plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hz).clip(1e-15)),
        ...              label=r'$|H_z(e^{j \omega})|$')
        >>> plt.semilogx(wz*fs/(2*np.pi), 20*np.log10(np.abs(hs).clip(1e-15)),
        ...              label=r'$|H(j \omega)|$')
        >>> plt.legend()
        >>> plt.xlabel('Frequency [Hz]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.grid(True)

    bode(system, w=None, n=100)
        Calculate Bode magnitude and phase data of a continuous-time system.

        Parameters
        ----------
        system : an instance of the LTI class or a tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `lti`)
                * 2 (num, den)
                * 3 (zeros, poles, gain)
                * 4 (A, B, C, D)

        w : array_like, optional
            Array of frequencies (in rad/s). Magnitude and phase data is calculated
            for every value in this array. If not given a reasonable set will be
            calculated.
        n : int, optional
            Number of frequency points to compute if `w` is not given. The `n`
            frequencies are logarithmically spaced in an interval chosen to
            include the influence of the poles and zeros of the system.

        Returns
        -------
        w : 1D ndarray
            Frequency array [rad/s]
        mag : 1D ndarray
            Magnitude array [dB]
        phase : 1D ndarray
            Phase array [deg]

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``).

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> sys = signal.TransferFunction([1], [1, 1])
        >>> w, mag, phase = signal.bode(sys)

        >>> plt.figure()
        >>> plt.semilogx(w, mag)    # Bode magnitude plot
        >>> plt.figure()
        >>> plt.semilogx(w, phase)  # Bode phase plot
        >>> plt.show()

    buttap(N)
        Return (z,p,k) for analog prototype of Nth-order Butterworth filter.

        The filter will have an angular (e.g., rad/s) cutoff frequency of 1.

        See Also
        --------
        butter : Filter design function using this prototype

    butter(N, Wn, btype='low', analog=False, output='ba', fs=None)
        Butterworth digital and analog filter design.

        Design an Nth-order digital or analog Butterworth filter and return
        the filter coefficients.

        Parameters
        ----------
        N : int
            The order of the filter. For 'bandpass' and 'bandstop' filters,
            the resulting order of the final second-order sections ('sos')
            matrix is ``2*N``, with `N` the number of biquad sections
            of the desired system.
        Wn : array_like
            The critical frequency or frequencies. For lowpass and highpass
            filters, Wn is a scalar; for bandpass and bandstop filters,
            Wn is a length-2 sequence.

            For a Butterworth filter, this is the point at which the gain
            drops to 1/sqrt(2) that of the passband (the "-3 dB point").

            For digital filters, if `fs` is not specified, `Wn` units are
            normalized from 0 to 1, where 1 is the Nyquist frequency (`Wn` is
            thus in half cycles / sample and defined as 2*critical frequencies
            / `fs`). If `fs` is specified, `Wn` is in the same units as `fs`.

            For analog filters, `Wn` is an angular frequency (e.g. rad/s).
        btype : {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optional
            The type of filter.  Default is 'lowpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        output : {'ba', 'zpk', 'sos'}, optional
            Type of output:  numerator/denominator ('ba'), pole-zero ('zpk'), or
            second-order sections ('sos'). Default is 'ba' for backwards
            compatibility, but 'sos' should be used for general-purpose filtering.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        buttord, buttap

        Notes
        -----
        The Butterworth filter has maximally flat frequency response in the
        passband.

        The ``'sos'`` output parameter was added in 0.16.0.

        If the transfer function form ``[b, a]`` is requested, numerical
        problems can occur since the conversion between roots and
        the polynomial coefficients is a numerically sensitive operation,
        even for N >= 4. It is recommended to work with the SOS
        representation.

        .. warning::
            Designing high-order and narrowband IIR filters in TF form can
            result in unstable or incorrect filtering due to floating point
            numerical precision issues. Consider inspecting output filter
            characteristics `freqz` or designing the filters with second-order
            sections via ``output='sos'``.

        Examples
        --------
        Design an analog filter and plot its frequency response, showing the
        critical points:

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.butter(4, 100, 'low', analog=True)
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Butterworth filter frequency response')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(100, color='green') # cutoff frequency
        >>> plt.show()

        Generate a signal made up of 10 Hz and 20 Hz, sampled at 1 kHz

        >>> t = np.linspace(0, 1, 1000, False)  # 1 second
        >>> sig = np.sin(2*np.pi*10*t) + np.sin(2*np.pi*20*t)
        >>> fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
        >>> ax1.plot(t, sig)
        >>> ax1.set_title('10 Hz and 20 Hz sinusoids')
        >>> ax1.axis([0, 1, -2, 2])

        Design a digital high-pass filter at 15 Hz to remove the 10 Hz tone, and
        apply it to the signal. (It's recommended to use second-order sections
        format when filtering, to avoid numerical error with transfer function
        (``ba``) format):

        >>> sos = signal.butter(10, 15, 'hp', fs=1000, output='sos')
        >>> filtered = signal.sosfilt(sos, sig)
        >>> ax2.plot(t, filtered)
        >>> ax2.set_title('After 15 Hz high-pass filter')
        >>> ax2.axis([0, 1, -2, 2])
        >>> ax2.set_xlabel('Time [seconds]')
        >>> plt.tight_layout()
        >>> plt.show()

    buttord(wp, ws, gpass, gstop, analog=False, fs=None)
        Butterworth filter order selection.

        Return the order of the lowest order digital or analog Butterworth filter
        that loses no more than `gpass` dB in the passband and has at least
        `gstop` dB attenuation in the stopband.

        Parameters
        ----------
        wp, ws : float
            Passband and stopband edge frequencies.

            For digital filters, these are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`wp` and `ws` are thus in
            half-cycles / sample.) For example:

                - Lowpass:   wp = 0.2,          ws = 0.3
                - Highpass:  wp = 0.3,          ws = 0.2
                - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
                - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]

            For analog filters, `wp` and `ws` are angular frequencies (e.g., rad/s).
        gpass : float
            The maximum loss in the passband (dB).
        gstop : float
            The minimum attenuation in the stopband (dB).
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        ord : int
            The lowest order for a Butterworth filter which meets specs.
        wn : ndarray or float
            The Butterworth natural frequency (i.e. the "3dB frequency"). Should
            be used with `butter` to give filter results. If `fs` is specified,
            this is in the same units, and `fs` must also be passed to `butter`.

        See Also
        --------
        butter : Filter design using order and critical points
        cheb1ord : Find order and critical points from passband and stopband spec
        cheb2ord, ellipord
        iirfilter : General filter design using order and critical frequencies
        iirdesign : General filter design using passband and stopband spec

        Examples
        --------
        Design an analog bandpass filter with passband within 3 dB from 20 to
        50 rad/s, while rejecting at least -40 dB below 14 and above 60 rad/s.
        Plot its frequency response, showing the passband and stopband
        constraints in gray.

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> N, Wn = signal.buttord([20, 50], [14, 60], 3, 40, True)
        >>> b, a = signal.butter(N, Wn, 'band', True)
        >>> w, h = signal.freqs(b, a, np.logspace(1, 2, 500))
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Butterworth bandpass filter fit to constraints')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.grid(which='both', axis='both')
        >>> plt.fill([1,  14,  14,   1], [-40, -40, 99, 99], '0.9', lw=0) # stop
        >>> plt.fill([20, 20,  50,  50], [-99, -3, -3, -99], '0.9', lw=0) # pass
        >>> plt.fill([60, 60, 1e9, 1e9], [99, -40, -40, 99], '0.9', lw=0) # stop
        >>> plt.axis([10, 100, -60, 3])
        >>> plt.show()

    cascade(hk, J=7)
        Return (x, phi, psi) at dyadic points ``K/2**J`` from filter coefficients.

        .. deprecated:: 1.12.0

            scipy.signal.cascade is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        Parameters
        ----------
        hk : array_like
            Coefficients of low-pass filter.
        J : int, optional
            Values will be computed at grid points ``K/2**J``. Default is 7.

        Returns
        -------
        x : ndarray
            The dyadic points ``K/2**J`` for ``K=0...N * (2**J)-1`` where
            ``len(hk) = len(gk) = N+1``.
        phi : ndarray
            The scaling function ``phi(x)`` at `x`:
            ``phi(x) = sum(hk * phi(2x-k))``, where k is from 0 to N.
        psi : ndarray, optional
            The wavelet function ``psi(x)`` at `x`:
            ``phi(x) = sum(gk * phi(2x-k))``, where k is from 0 to N.
            `psi` is only returned if `gk` is not None.

        Notes
        -----
        The algorithm uses the vector cascade algorithm described by Strang and
        Nguyen in "Wavelets and Filter Banks".  It builds a dictionary of values
        and slices for quick reuse.  Then inserts vectors into final vector at the
        end.

    cheb1ap(N, rp)
        Return (z,p,k) for Nth-order Chebyshev type I analog lowpass filter.

        The returned filter prototype has `rp` decibels of ripple in the passband.

        The filter's angular (e.g. rad/s) cutoff frequency is normalized to 1,
        defined as the point at which the gain first drops below ``-rp``.

        See Also
        --------
        cheby1 : Filter design function using this prototype

    cheb1ord(wp, ws, gpass, gstop, analog=False, fs=None)
        Chebyshev type I filter order selection.

        Return the order of the lowest order digital or analog Chebyshev Type I
        filter that loses no more than `gpass` dB in the passband and has at
        least `gstop` dB attenuation in the stopband.

        Parameters
        ----------
        wp, ws : float
            Passband and stopband edge frequencies.

            For digital filters, these are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`wp` and `ws` are thus in
            half-cycles / sample.)  For example:

                - Lowpass:   wp = 0.2,          ws = 0.3
                - Highpass:  wp = 0.3,          ws = 0.2
                - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
                - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]

            For analog filters, `wp` and `ws` are angular frequencies (e.g., rad/s).
        gpass : float
            The maximum loss in the passband (dB).
        gstop : float
            The minimum attenuation in the stopband (dB).
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        ord : int
            The lowest order for a Chebyshev type I filter that meets specs.
        wn : ndarray or float
            The Chebyshev natural frequency (the "3dB frequency") for use with
            `cheby1` to give filter results. If `fs` is specified,
            this is in the same units, and `fs` must also be passed to `cheby1`.

        See Also
        --------
        cheby1 : Filter design using order and critical points
        buttord : Find order and critical points from passband and stopband spec
        cheb2ord, ellipord
        iirfilter : General filter design using order and critical frequencies
        iirdesign : General filter design using passband and stopband spec

        Examples
        --------
        Design a digital lowpass filter such that the passband is within 3 dB up
        to 0.2*(fs/2), while rejecting at least -40 dB above 0.3*(fs/2). Plot its
        frequency response, showing the passband and stopband constraints in gray.

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> N, Wn = signal.cheb1ord(0.2, 0.3, 3, 40)
        >>> b, a = signal.cheby1(N, 3, Wn, 'low')
        >>> w, h = signal.freqz(b, a)
        >>> plt.semilogx(w / np.pi, 20 * np.log10(abs(h)))
        >>> plt.title('Chebyshev I lowpass filter fit to constraints')
        >>> plt.xlabel('Normalized frequency')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.grid(which='both', axis='both')
        >>> plt.fill([.01, 0.2, 0.2, .01], [-3, -3, -99, -99], '0.9', lw=0) # stop
        >>> plt.fill([0.3, 0.3,   2,   2], [ 9, -40, -40,  9], '0.9', lw=0) # pass
        >>> plt.axis([0.08, 1, -60, 3])
        >>> plt.show()

    cheb2ap(N, rs)
        Return (z,p,k) for Nth-order Chebyshev type II analog lowpass filter.

        The returned filter prototype has attenuation of at least ``rs`` decibels
        in the stopband.

        The filter's angular (e.g. rad/s) cutoff frequency is normalized to 1,
        defined as the point at which the attenuation first reaches ``rs``.

        See Also
        --------
        cheby2 : Filter design function using this prototype

    cheb2ord(wp, ws, gpass, gstop, analog=False, fs=None)
        Chebyshev type II filter order selection.

        Return the order of the lowest order digital or analog Chebyshev Type II
        filter that loses no more than `gpass` dB in the passband and has at least
        `gstop` dB attenuation in the stopband.

        Parameters
        ----------
        wp, ws : float
            Passband and stopband edge frequencies.

            For digital filters, these are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`wp` and `ws` are thus in
            half-cycles / sample.)  For example:

                - Lowpass:   wp = 0.2,          ws = 0.3
                - Highpass:  wp = 0.3,          ws = 0.2
                - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
                - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]

            For analog filters, `wp` and `ws` are angular frequencies (e.g., rad/s).
        gpass : float
            The maximum loss in the passband (dB).
        gstop : float
            The minimum attenuation in the stopband (dB).
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        ord : int
            The lowest order for a Chebyshev type II filter that meets specs.
        wn : ndarray or float
            The Chebyshev natural frequency (the "3dB frequency") for use with
            `cheby2` to give filter results. If `fs` is specified,
            this is in the same units, and `fs` must also be passed to `cheby2`.

        See Also
        --------
        cheby2 : Filter design using order and critical points
        buttord : Find order and critical points from passband and stopband spec
        cheb1ord, ellipord
        iirfilter : General filter design using order and critical frequencies
        iirdesign : General filter design using passband and stopband spec

        Examples
        --------
        Design a digital bandstop filter which rejects -60 dB from 0.2*(fs/2) to
        0.5*(fs/2), while staying within 3 dB below 0.1*(fs/2) or above
        0.6*(fs/2). Plot its frequency response, showing the passband and
        stopband constraints in gray.

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> N, Wn = signal.cheb2ord([0.1, 0.6], [0.2, 0.5], 3, 60)
        >>> b, a = signal.cheby2(N, 60, Wn, 'stop')
        >>> w, h = signal.freqz(b, a)
        >>> plt.semilogx(w / np.pi, 20 * np.log10(abs(h)))
        >>> plt.title('Chebyshev II bandstop filter fit to constraints')
        >>> plt.xlabel('Normalized frequency')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.grid(which='both', axis='both')
        >>> plt.fill([.01, .1, .1, .01], [-3,  -3, -99, -99], '0.9', lw=0) # stop
        >>> plt.fill([.2,  .2, .5,  .5], [ 9, -60, -60,   9], '0.9', lw=0) # pass
        >>> plt.fill([.6,  .6,  2,   2], [-99, -3,  -3, -99], '0.9', lw=0) # stop
        >>> plt.axis([0.06, 1, -80, 3])
        >>> plt.show()

    cheby1(N, rp, Wn, btype='low', analog=False, output='ba', fs=None)
        Chebyshev type I digital and analog filter design.

        Design an Nth-order digital or analog Chebyshev type I filter and
        return the filter coefficients.

        Parameters
        ----------
        N : int
            The order of the filter.
        rp : float
            The maximum ripple allowed below unity gain in the passband.
            Specified in decibels, as a positive number.
        Wn : array_like
            A scalar or length-2 sequence giving the critical frequencies.
            For Type I filters, this is the point in the transition band at which
            the gain first drops below -`rp`.

            For digital filters, `Wn` are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`Wn` is thus in
            half-cycles / sample.)

            For analog filters, `Wn` is an angular frequency (e.g., rad/s).
        btype : {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optional
            The type of filter.  Default is 'lowpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        output : {'ba', 'zpk', 'sos'}, optional
            Type of output:  numerator/denominator ('ba'), pole-zero ('zpk'), or
            second-order sections ('sos'). Default is 'ba' for backwards
            compatibility, but 'sos' should be used for general-purpose filtering.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        cheb1ord, cheb1ap

        Notes
        -----
        The Chebyshev type I filter maximizes the rate of cutoff between the
        frequency response's passband and stopband, at the expense of ripple in
        the passband and increased ringing in the step response.

        Type I filters roll off faster than Type II (`cheby2`), but Type II
        filters do not have any ripple in the passband.

        The equiripple passband has N maxima or minima (for example, a
        5th-order filter has 3 maxima and 2 minima). Consequently, the DC gain is
        unity for odd-order filters, or -rp dB for even-order filters.

        The ``'sos'`` output parameter was added in 0.16.0.

        Examples
        --------
        Design an analog filter and plot its frequency response, showing the
        critical points:

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.cheby1(4, 5, 100, 'low', analog=True)
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Chebyshev Type I frequency response (rp=5)')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(100, color='green') # cutoff frequency
        >>> plt.axhline(-5, color='green') # rp
        >>> plt.show()

        Generate a signal made up of 10 Hz and 20 Hz, sampled at 1 kHz

        >>> t = np.linspace(0, 1, 1000, False)  # 1 second
        >>> sig = np.sin(2*np.pi*10*t) + np.sin(2*np.pi*20*t)
        >>> fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
        >>> ax1.plot(t, sig)
        >>> ax1.set_title('10 Hz and 20 Hz sinusoids')
        >>> ax1.axis([0, 1, -2, 2])

        Design a digital high-pass filter at 15 Hz to remove the 10 Hz tone, and
        apply it to the signal. (It's recommended to use second-order sections
        format when filtering, to avoid numerical error with transfer function
        (``ba``) format):

        >>> sos = signal.cheby1(10, 1, 15, 'hp', fs=1000, output='sos')
        >>> filtered = signal.sosfilt(sos, sig)
        >>> ax2.plot(t, filtered)
        >>> ax2.set_title('After 15 Hz high-pass filter')
        >>> ax2.axis([0, 1, -2, 2])
        >>> ax2.set_xlabel('Time [seconds]')
        >>> plt.tight_layout()
        >>> plt.show()

    cheby2(N, rs, Wn, btype='low', analog=False, output='ba', fs=None)
        Chebyshev type II digital and analog filter design.

        Design an Nth-order digital or analog Chebyshev type II filter and
        return the filter coefficients.

        Parameters
        ----------
        N : int
            The order of the filter.
        rs : float
            The minimum attenuation required in the stop band.
            Specified in decibels, as a positive number.
        Wn : array_like
            A scalar or length-2 sequence giving the critical frequencies.
            For Type II filters, this is the point in the transition band at which
            the gain first reaches -`rs`.

            For digital filters, `Wn` are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`Wn` is thus in
            half-cycles / sample.)

            For analog filters, `Wn` is an angular frequency (e.g., rad/s).
        btype : {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optional
            The type of filter.  Default is 'lowpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        output : {'ba', 'zpk', 'sos'}, optional
            Type of output:  numerator/denominator ('ba'), pole-zero ('zpk'), or
            second-order sections ('sos'). Default is 'ba' for backwards
            compatibility, but 'sos' should be used for general-purpose filtering.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        cheb2ord, cheb2ap

        Notes
        -----
        The Chebyshev type II filter maximizes the rate of cutoff between the
        frequency response's passband and stopband, at the expense of ripple in
        the stopband and increased ringing in the step response.

        Type II filters do not roll off as fast as Type I (`cheby1`).

        The ``'sos'`` output parameter was added in 0.16.0.

        Examples
        --------
        Design an analog filter and plot its frequency response, showing the
        critical points:

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.cheby2(4, 40, 100, 'low', analog=True)
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Chebyshev Type II frequency response (rs=40)')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(100, color='green') # cutoff frequency
        >>> plt.axhline(-40, color='green') # rs
        >>> plt.show()

        Generate a signal made up of 10 Hz and 20 Hz, sampled at 1 kHz

        >>> t = np.linspace(0, 1, 1000, False)  # 1 second
        >>> sig = np.sin(2*np.pi*10*t) + np.sin(2*np.pi*20*t)
        >>> fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
        >>> ax1.plot(t, sig)
        >>> ax1.set_title('10 Hz and 20 Hz sinusoids')
        >>> ax1.axis([0, 1, -2, 2])

        Design a digital high-pass filter at 17 Hz to remove the 10 Hz tone, and
        apply it to the signal. (It's recommended to use second-order sections
        format when filtering, to avoid numerical error with transfer function
        (``ba``) format):

        >>> sos = signal.cheby2(12, 20, 17, 'hp', fs=1000, output='sos')
        >>> filtered = signal.sosfilt(sos, sig)
        >>> ax2.plot(t, filtered)
        >>> ax2.set_title('After 17 Hz high-pass filter')
        >>> ax2.axis([0, 1, -2, 2])
        >>> ax2.set_xlabel('Time [seconds]')
        >>> plt.show()

    check_COLA(window, nperseg, noverlap, tol=1e-10)
        Check whether the Constant OverLap Add (COLA) constraint is met.

        Parameters
        ----------
        window : str or tuple or array_like
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg.
        nperseg : int
            Length of each segment.
        noverlap : int
            Number of points to overlap between segments.
        tol : float, optional
            The allowed variance of a bin's weighted sum from the median bin
            sum.

        Returns
        -------
        verdict : bool
            `True` if chosen combination satisfies COLA within `tol`,
            `False` otherwise

        See Also
        --------
        check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
        stft: Short Time Fourier Transform
        istft: Inverse Short Time Fourier Transform

        Notes
        -----
        In order to enable inversion of an STFT via the inverse STFT in
        `istft`, it is sufficient that the signal windowing obeys the constraint of
        "Constant OverLap Add" (COLA). This ensures that every point in the input
        data is equally weighted, thereby avoiding aliasing and allowing full
        reconstruction.

        Some examples of windows that satisfy COLA:
            - Rectangular window at overlap of 0, 1/2, 2/3, 3/4, ...
            - Bartlett window at overlap of 1/2, 3/4, 5/6, ...
            - Hann window at 1/2, 2/3, 3/4, ...
            - Any Blackman family window at 2/3 overlap
            - Any window with ``noverlap = nperseg-1``

        A very comprehensive list of other windows may be found in [2]_,
        wherein the COLA condition is satisfied when the "Amplitude
        Flatness" is unity.

        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Julius O. Smith III, "Spectral Audio Signal Processing", W3K
               Publishing, 2011,ISBN 978-0-9745607-3-1.
        .. [2] G. Heinzel, A. Ruediger and R. Schilling, "Spectrum and
               spectral density estimation by the Discrete Fourier transform
               (DFT), including a comprehensive list of window functions and
               some new at-top windows", 2002,
               http://hdl.handle.net/11858/00-001M-0000-0013-557A-5

        Examples
        --------
        >>> from scipy import signal

        Confirm COLA condition for rectangular window of 75% (3/4) overlap:

        >>> signal.check_COLA(signal.windows.boxcar(100), 100, 75)
        True

        COLA is not true for 25% (1/4) overlap, though:

        >>> signal.check_COLA(signal.windows.boxcar(100), 100, 25)
        False

        "Symmetrical" Hann window (for filter design) is not COLA:

        >>> signal.check_COLA(signal.windows.hann(120, sym=True), 120, 60)
        False

        "Periodic" or "DFT-even" Hann window (for FFT analysis) is COLA for
        overlap of 1/2, 2/3, 3/4, etc.:

        >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 60)
        True

        >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 80)
        True

        >>> signal.check_COLA(signal.windows.hann(120, sym=False), 120, 90)
        True

    check_NOLA(window, nperseg, noverlap, tol=1e-10)
        Check whether the Nonzero Overlap Add (NOLA) constraint is met.

        Parameters
        ----------
        window : str or tuple or array_like
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg.
        nperseg : int
            Length of each segment.
        noverlap : int
            Number of points to overlap between segments.
        tol : float, optional
            The allowed variance of a bin's weighted sum from the median bin
            sum.

        Returns
        -------
        verdict : bool
            `True` if chosen combination satisfies the NOLA constraint within
            `tol`, `False` otherwise

        See Also
        --------
        check_COLA: Check whether the Constant OverLap Add (COLA) constraint is met
        stft: Short Time Fourier Transform
        istft: Inverse Short Time Fourier Transform

        Notes
        -----
        In order to enable inversion of an STFT via the inverse STFT in
        `istft`, the signal windowing must obey the constraint of "nonzero
        overlap add" (NOLA):

        .. math:: \sum_{t}w^{2}[n-tH] \ne 0

        for all :math:`n`, where :math:`w` is the window function, :math:`t` is the
        frame index, and :math:`H` is the hop size (:math:`H` = `nperseg` -
        `noverlap`).

        This ensures that the normalization factors in the denominator of the
        overlap-add inversion equation are not zero. Only very pathological windows
        will fail the NOLA constraint.

        .. versionadded:: 1.2.0

        References
        ----------
        .. [1] Julius O. Smith III, "Spectral Audio Signal Processing", W3K
               Publishing, 2011,ISBN 978-0-9745607-3-1.
        .. [2] G. Heinzel, A. Ruediger and R. Schilling, "Spectrum and
               spectral density estimation by the Discrete Fourier transform
               (DFT), including a comprehensive list of window functions and
               some new at-top windows", 2002,
               http://hdl.handle.net/11858/00-001M-0000-0013-557A-5

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal

        Confirm NOLA condition for rectangular window of 75% (3/4) overlap:

        >>> signal.check_NOLA(signal.windows.boxcar(100), 100, 75)
        True

        NOLA is also true for 25% (1/4) overlap:

        >>> signal.check_NOLA(signal.windows.boxcar(100), 100, 25)
        True

        "Symmetrical" Hann window (for filter design) is also NOLA:

        >>> signal.check_NOLA(signal.windows.hann(120, sym=True), 120, 60)
        True

        As long as there is overlap, it takes quite a pathological window to fail
        NOLA:

        >>> w = np.ones(64, dtype="float")
        >>> w[::2] = 0
        >>> signal.check_NOLA(w, 64, 32)
        False

        If there is not enough overlap, a window with zeros at the ends will not
        work:

        >>> signal.check_NOLA(signal.windows.hann(64), 64, 0)
        False
        >>> signal.check_NOLA(signal.windows.hann(64), 64, 1)
        False
        >>> signal.check_NOLA(signal.windows.hann(64), 64, 2)
        True

    chirp(t, f0, t1, f1, method='linear', phi=0, vertex_zero=True)
        Frequency-swept cosine generator.

        In the following, 'Hz' should be interpreted as 'cycles per unit';
        there is no requirement here that the unit is one second.  The
        important distinction is that the units of rotation are cycles, not
        radians. Likewise, `t` could be a measurement of space instead of time.

        Parameters
        ----------
        t : array_like
            Times at which to evaluate the waveform.
        f0 : float
            Frequency (e.g. Hz) at time t=0.
        t1 : float
            Time at which `f1` is specified.
        f1 : float
            Frequency (e.g. Hz) of the waveform at time `t1`.
        method : {'linear', 'quadratic', 'logarithmic', 'hyperbolic'}, optional
            Kind of frequency sweep.  If not given, `linear` is assumed.  See
            Notes below for more details.
        phi : float, optional
            Phase offset, in degrees. Default is 0.
        vertex_zero : bool, optional
            This parameter is only used when `method` is 'quadratic'.
            It determines whether the vertex of the parabola that is the graph
            of the frequency is at t=0 or t=t1.

        Returns
        -------
        y : ndarray
            A numpy array containing the signal evaluated at `t` with the
            requested time-varying frequency.  More precisely, the function
            returns ``cos(phase + (pi/180)*phi)`` where `phase` is the integral
            (from 0 to `t`) of ``2*pi*f(t)``. ``f(t)`` is defined below.

        See Also
        --------
        sweep_poly

        Notes
        -----
        There are four options for the `method`.  The following formulas give
        the instantaneous frequency (in Hz) of the signal generated by
        `chirp()`.  For convenience, the shorter names shown below may also be
        used.

        linear, lin, li:

            ``f(t) = f0 + (f1 - f0) * t / t1``

        quadratic, quad, q:

            The graph of the frequency f(t) is a parabola through (0, f0) and
            (t1, f1).  By default, the vertex of the parabola is at (0, f0).
            If `vertex_zero` is False, then the vertex is at (t1, f1).  The
            formula is:

            if vertex_zero is True:

                ``f(t) = f0 + (f1 - f0) * t**2 / t1**2``

            else:

                ``f(t) = f1 - (f1 - f0) * (t1 - t)**2 / t1**2``

            To use a more general quadratic function, or an arbitrary
            polynomial, use the function `scipy.signal.sweep_poly`.

        logarithmic, log, lo:

            ``f(t) = f0 * (f1/f0)**(t/t1)``

            f0 and f1 must be nonzero and have the same sign.

            This signal is also known as a geometric or exponential chirp.

        hyperbolic, hyp:

            ``f(t) = f0*f1*t1 / ((f0 - f1)*t + f1*t1)``

            f0 and f1 must be nonzero.

        Examples
        --------
        The following will be used in the examples:

        >>> import numpy as np
        >>> from scipy.signal import chirp, spectrogram
        >>> import matplotlib.pyplot as plt

        For the first example, we'll plot the waveform for a linear chirp
        from 6 Hz to 1 Hz over 10 seconds:

        >>> t = np.linspace(0, 10, 1500)
        >>> w = chirp(t, f0=6, f1=1, t1=10, method='linear')
        >>> plt.plot(t, w)
        >>> plt.title("Linear Chirp, f(0)=6, f(10)=1")
        >>> plt.xlabel('t (sec)')
        >>> plt.show()

        For the remaining examples, we'll use higher frequency ranges,
        and demonstrate the result using `scipy.signal.spectrogram`.
        We'll use a 4 second interval sampled at 7200 Hz.

        >>> fs = 7200
        >>> T = 4
        >>> t = np.arange(0, int(T*fs)) / fs

        We'll use this function to plot the spectrogram in each example.

        >>> def plot_spectrogram(title, w, fs):
        ...     ff, tt, Sxx = spectrogram(w, fs=fs, nperseg=256, nfft=576)
        ...     fig, ax = plt.subplots()
        ...     ax.pcolormesh(tt, ff[:145], Sxx[:145], cmap='gray_r',
        ...                   shading='gouraud')
        ...     ax.set_title(title)
        ...     ax.set_xlabel('t (sec)')
        ...     ax.set_ylabel('Frequency (Hz)')
        ...     ax.grid(True)
        ...

        Quadratic chirp from 1500 Hz to 250 Hz
        (vertex of the parabolic curve of the frequency is at t=0):

        >>> w = chirp(t, f0=1500, f1=250, t1=T, method='quadratic')
        >>> plot_spectrogram(f'Quadratic Chirp, f(0)=1500, f({T})=250', w, fs)
        >>> plt.show()

        Quadratic chirp from 1500 Hz to 250 Hz
        (vertex of the parabolic curve of the frequency is at t=T):

        >>> w = chirp(t, f0=1500, f1=250, t1=T, method='quadratic',
        ...           vertex_zero=False)
        >>> plot_spectrogram(f'Quadratic Chirp, f(0)=1500, f({T})=250\n' +
        ...                  '(vertex_zero=False)', w, fs)
        >>> plt.show()

        Logarithmic chirp from 1500 Hz to 250 Hz:

        >>> w = chirp(t, f0=1500, f1=250, t1=T, method='logarithmic')
        >>> plot_spectrogram(f'Logarithmic Chirp, f(0)=1500, f({T})=250', w, fs)
        >>> plt.show()

        Hyperbolic chirp from 1500 Hz to 250 Hz:

        >>> w = chirp(t, f0=1500, f1=250, t1=T, method='hyperbolic')
        >>> plot_spectrogram(f'Hyperbolic Chirp, f(0)=1500, f({T})=250', w, fs)
        >>> plt.show()

    choose_conv_method(in1, in2, mode='full', measure=False)
        Find the fastest convolution/correlation method.

        This primarily exists to be called during the ``method='auto'`` option in
        `convolve` and `correlate`. It can also be used to determine the value of
        ``method`` for many different convolutions of the same dtype/shape.
        In addition, it supports timing the convolution to adapt the value of
        ``method`` to a particular set of inputs and/or hardware.

        Parameters
        ----------
        in1 : array_like
            The first argument passed into the convolution function.
        in2 : array_like
            The second argument passed into the convolution function.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear convolution
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        measure : bool, optional
            If True, run and time the convolution of `in1` and `in2` with both
            methods and return the fastest. If False (default), predict the fastest
            method using precomputed values.

        Returns
        -------
        method : str
            A string indicating which convolution method is fastest, either
            'direct' or 'fft'
        times : dict, optional
            A dictionary containing the times (in seconds) needed for each method.
            This value is only returned if ``measure=True``.

        See Also
        --------
        convolve
        correlate

        Notes
        -----
        Generally, this method is 99% accurate for 2D signals and 85% accurate
        for 1D signals for randomly chosen input sizes. For precision, use
        ``measure=True`` to find the fastest method by timing the convolution.
        This can be used to avoid the minimal overhead of finding the fastest
        ``method`` later, or to adapt the value of ``method`` to a particular set
        of inputs.

        Experiments were run on an Amazon EC2 r5a.2xlarge machine to test this
        function. These experiments measured the ratio between the time required
        when using ``method='auto'`` and the time required for the fastest method
        (i.e., ``ratio = time_auto / min(time_fft, time_direct)``). In these
        experiments, we found:

        * There is a 95% chance of this ratio being less than 1.5 for 1D signals
          and a 99% chance of being less than 2.5 for 2D signals.
        * The ratio was always less than 2.5/5 for 1D/2D signals respectively.
        * This function is most inaccurate for 1D convolutions that take between 1
          and 10 milliseconds with ``method='direct'``. A good proxy for this
          (at least in our experiments) is ``1e6 <= in1.size * in2.size <= 1e7``.

        The 2D results almost certainly generalize to 3D/4D/etc because the
        implementation is the same (the 1D implementation is different).

        All the numbers above are specific to the EC2 machine. However, we did find
        that this function generalizes fairly decently across hardware. The speed
        tests were of similar quality (and even slightly better) than the same
        tests performed on the machine to tune this function's numbers (a mid-2014
        15-inch MacBook Pro with 16GB RAM and a 2.5GHz Intel i7 processor).

        There are cases when `fftconvolve` supports the inputs but this function
        returns `direct` (e.g., to protect against floating point integer
        precision).

        .. versionadded:: 0.19

        Examples
        --------
        Estimate the fastest method for a given input:

        >>> import numpy as np
        >>> from scipy import signal
        >>> rng = np.random.default_rng()
        >>> img = rng.random((32, 32))
        >>> filter = rng.random((8, 8))
        >>> method = signal.choose_conv_method(img, filter, mode='same')
        >>> method
        'fft'

        This can then be applied to other arrays of the same dtype and shape:

        >>> img2 = rng.random((32, 32))
        >>> filter2 = rng.random((8, 8))
        >>> corr2 = signal.correlate(img2, filter2, mode='same', method=method)
        >>> conv2 = signal.convolve(img2, filter2, mode='same', method=method)

        The output of this function (``method``) works with `correlate` and
        `convolve`.

    cmplx_sort(p)

    coherence(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, detrend='constant', axis=-1)
        Estimate the magnitude squared coherence estimate, Cxy, of
        discrete-time signals X and Y using Welch's method.

        ``Cxy = abs(Pxy)**2/(Pxx*Pyy)``, where `Pxx` and `Pyy` are power
        spectral density estimates of X and Y, and `Pxy` is the cross
        spectral density estimate of X and Y.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        y : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` and `y` time series. Defaults
            to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg. Defaults
            to a Hann window.
        nperseg : int, optional
            Length of each segment. Defaults to None, but if window is str or
            tuple, is set to 256, and if window is array_like, is set to the
            length of the window.
        noverlap: int, optional
            Number of points to overlap between segments. If `None`,
            ``noverlap = nperseg // 2``. Defaults to `None`.
        nfft : int, optional
            Length of the FFT used, if a zero padded FFT is desired. If
            `None`, the FFT length is `nperseg`. Defaults to `None`.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to 'constant'.
        axis : int, optional
            Axis along which the coherence is computed for both inputs; the
            default is over the last axis (i.e. ``axis=-1``).

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        Cxy : ndarray
            Magnitude squared coherence of x and y.

        See Also
        --------
        periodogram: Simple, optionally modified periodogram
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data
        welch: Power spectral density by Welch's method.
        csd: Cross spectral density by Welch's method.

        Notes
        -----
        An appropriate amount of overlap will depend on the choice of window
        and on your requirements. For the default Hann window an overlap of
        50% is a reasonable trade off between accurately estimating the
        signal power, while not over counting any of the data. Narrower
        windows may require a larger overlap.

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] P. Welch, "The use of the fast Fourier transform for the
               estimation of power spectra: A method based on time averaging
               over short, modified periodograms", IEEE Trans. Audio
               Electroacoust. vol. 15, pp. 70-73, 1967.
        .. [2] Stoica, Petre, and Randolph Moses, "Spectral Analysis of
               Signals" Prentice Hall, 2005

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate two test signals with some common features.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 20
        >>> freq = 1234.0
        >>> noise_power = 0.001 * fs / 2
        >>> time = np.arange(N) / fs
        >>> b, a = signal.butter(2, 0.25, 'low')
        >>> x = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
        >>> y = signal.lfilter(b, a, x)
        >>> x += amp*np.sin(2*np.pi*freq*time)
        >>> y += rng.normal(scale=0.1*np.sqrt(noise_power), size=time.shape)

        Compute and plot the coherence.

        >>> f, Cxy = signal.coherence(x, y, fs, nperseg=1024)
        >>> plt.semilogy(f, Cxy)
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('Coherence')
        >>> plt.show()

    cont2discrete(system, dt, method='zoh', alpha=None)
        Transform a continuous to a discrete state-space system.

        Parameters
        ----------
        system : a tuple describing the system or an instance of `lti`
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1: (instance of `lti`)
                * 2: (num, den)
                * 3: (zeros, poles, gain)
                * 4: (A, B, C, D)

        dt : float
            The discretization time step.
        method : str, optional
            Which method to use:

                * gbt: generalized bilinear transformation
                * bilinear: Tustin's approximation ("gbt" with alpha=0.5)
                * euler: Euler (or forward differencing) method ("gbt" with alpha=0)
                * backward_diff: Backwards differencing ("gbt" with alpha=1.0)
                * zoh: zero-order hold (default)
                * foh: first-order hold (*versionadded: 1.3.0*)
                * impulse: equivalent impulse response (*versionadded: 1.3.0*)

        alpha : float within [0, 1], optional
            The generalized bilinear transformation weighting parameter, which
            should only be specified with method="gbt", and is ignored otherwise

        Returns
        -------
        sysd : tuple containing the discrete system
            Based on the input type, the output will be of the form

            * (num, den, dt)   for transfer function input
            * (zeros, poles, gain, dt)   for zeros-poles-gain input
            * (A, B, C, D, dt) for state-space system input

        Notes
        -----
        By default, the routine uses a Zero-Order Hold (zoh) method to perform
        the transformation. Alternatively, a generalized bilinear transformation
        may be used, which includes the common Tustin's bilinear approximation,
        an Euler's method technique, or a backwards differencing technique.

        The Zero-Order Hold (zoh) method is based on [1]_, the generalized bilinear
        approximation is based on [2]_ and [3]_, the First-Order Hold (foh) method
        is based on [4]_.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Discretization#Discretization_of_linear_state_space_models

        .. [2] http://techteach.no/publications/discretetime_signals_systems/discrete.pdf

        .. [3] G. Zhang, X. Chen, and T. Chen, Digital redesign via the generalized
            bilinear transformation, Int. J. Control, vol. 82, no. 4, pp. 741-754,
            2009.
            (https://www.mypolyuweb.hk/~magzhang/Research/ZCC09_IJC.pdf)

        .. [4] G. F. Franklin, J. D. Powell, and M. L. Workman, Digital control
            of dynamic systems, 3rd ed. Menlo Park, Calif: Addison-Wesley,
            pp. 204-206, 1998.

        Examples
        --------
        We can transform a continuous state-space system to a discrete one:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import cont2discrete, lti, dlti, dstep

        Define a continuous state-space system.

        >>> A = np.array([[0, 1],[-10., -3]])
        >>> B = np.array([[0],[10.]])
        >>> C = np.array([[1., 0]])
        >>> D = np.array([[0.]])
        >>> l_system = lti(A, B, C, D)
        >>> t, x = l_system.step(T=np.linspace(0, 5, 100))
        >>> fig, ax = plt.subplots()
        >>> ax.plot(t, x, label='Continuous', linewidth=3)

        Transform it to a discrete state-space system using several methods.

        >>> dt = 0.1
        >>> for method in ['zoh', 'bilinear', 'euler', 'backward_diff', 'foh', 'impulse']:
        ...    d_system = cont2discrete((A, B, C, D), dt, method=method)
        ...    s, x_d = dstep(d_system)
        ...    ax.step(s, np.squeeze(x_d), label=method, where='post')
        >>> ax.axis([t[0], t[-1], x[0], 1.4])
        >>> ax.legend(loc='best')
        >>> fig.tight_layout()
        >>> plt.show()

    convolve(in1, in2, mode='full', method='auto')
        Convolve two N-dimensional arrays.

        Convolve `in1` and `in2`, with the output size determined by the
        `mode` argument.

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear convolution
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        method : str {'auto', 'direct', 'fft'}, optional
            A string indicating which method to use to calculate the convolution.

            ``direct``
               The convolution is determined directly from sums, the definition of
               convolution.
            ``fft``
               The Fourier Transform is used to perform the convolution by calling
               `fftconvolve`.
            ``auto``
               Automatically chooses direct or Fourier method based on an estimate
               of which is faster (default).  See Notes for more detail.

               .. versionadded:: 0.19.0

        Returns
        -------
        convolve : array
            An N-dimensional array containing a subset of the discrete linear
            convolution of `in1` with `in2`.

        Warns
        -----
        RuntimeWarning
            Use of the FFT convolution on input containing NAN or INF will lead
            to the entire output being NAN or INF. Use method='direct' when your
            input contains NAN or INF values.

        See Also
        --------
        numpy.polymul : performs polynomial multiplication (same operation, but
                        also accepts poly1d objects)
        choose_conv_method : chooses the fastest appropriate convolution method
        fftconvolve : Always uses the FFT method.
        oaconvolve : Uses the overlap-add method to do convolution, which is
                     generally faster when the input arrays are large and
                     significantly different in size.

        Notes
        -----
        By default, `convolve` and `correlate` use ``method='auto'``, which calls
        `choose_conv_method` to choose the fastest method using pre-computed
        values (`choose_conv_method` can also measure real-world timing with a
        keyword argument). Because `fftconvolve` relies on floating point numbers,
        there are certain constraints that may force `method=direct` (more detail
        in `choose_conv_method` docstring).

        Examples
        --------
        Smooth a square pulse using a Hann window:

        >>> import numpy as np
        >>> from scipy import signal
        >>> sig = np.repeat([0., 1., 0.], 100)
        >>> win = signal.windows.hann(50)
        >>> filtered = signal.convolve(sig, win, mode='same') / sum(win)

        >>> import matplotlib.pyplot as plt
        >>> fig, (ax_orig, ax_win, ax_filt) = plt.subplots(3, 1, sharex=True)
        >>> ax_orig.plot(sig)
        >>> ax_orig.set_title('Original pulse')
        >>> ax_orig.margins(0, 0.1)
        >>> ax_win.plot(win)
        >>> ax_win.set_title('Filter impulse response')
        >>> ax_win.margins(0, 0.1)
        >>> ax_filt.plot(filtered)
        >>> ax_filt.set_title('Filtered signal')
        >>> ax_filt.margins(0, 0.1)
        >>> fig.tight_layout()
        >>> fig.show()

    convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0)
        Convolve two 2-dimensional arrays.

        Convolve `in1` and `in2` with output size determined by `mode`, and
        boundary conditions determined by `boundary` and `fillvalue`.

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear convolution
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        boundary : str {'fill', 'wrap', 'symm'}, optional
            A flag indicating how to handle boundaries:

            ``fill``
               pad input arrays with fillvalue. (default)
            ``wrap``
               circular boundary conditions.
            ``symm``
               symmetrical boundary conditions.

        fillvalue : scalar, optional
            Value to fill pad input arrays with. Default is 0.

        Returns
        -------
        out : ndarray
            A 2-dimensional array containing a subset of the discrete linear
            convolution of `in1` with `in2`.

        Examples
        --------
        Compute the gradient of an image by 2D convolution with a complex Scharr
        operator.  (Horizontal operator is real, vertical is imaginary.)  Use
        symmetric boundary condition to avoid creating edges at the image
        boundaries.

        >>> import numpy as np
        >>> from scipy import signal
        >>> from scipy import datasets
        >>> ascent = datasets.ascent()
        >>> scharr = np.array([[ -3-3j, 0-10j,  +3 -3j],
        ...                    [-10+0j, 0+ 0j, +10 +0j],
        ...                    [ -3+3j, 0+10j,  +3 +3j]]) # Gx + j*Gy
        >>> grad = signal.convolve2d(ascent, scharr, boundary='symm', mode='same')

        >>> import matplotlib.pyplot as plt
        >>> fig, (ax_orig, ax_mag, ax_ang) = plt.subplots(3, 1, figsize=(6, 15))
        >>> ax_orig.imshow(ascent, cmap='gray')
        >>> ax_orig.set_title('Original')
        >>> ax_orig.set_axis_off()
        >>> ax_mag.imshow(np.absolute(grad), cmap='gray')
        >>> ax_mag.set_title('Gradient magnitude')
        >>> ax_mag.set_axis_off()
        >>> ax_ang.imshow(np.angle(grad), cmap='hsv') # hsv is cyclic, like angles
        >>> ax_ang.set_title('Gradient orientation')
        >>> ax_ang.set_axis_off()
        >>> fig.show()

    correlate(in1, in2, mode='full', method='auto')
        Cross-correlate two N-dimensional arrays.

        Cross-correlate `in1` and `in2`, with the output size determined by the
        `mode` argument.

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear cross-correlation
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        method : str {'auto', 'direct', 'fft'}, optional
            A string indicating which method to use to calculate the correlation.

            ``direct``
               The correlation is determined directly from sums, the definition of
               correlation.
            ``fft``
               The Fast Fourier Transform is used to perform the correlation more
               quickly (only available for numerical arrays.)
            ``auto``
               Automatically chooses direct or Fourier method based on an estimate
               of which is faster (default).  See `convolve` Notes for more detail.

               .. versionadded:: 0.19.0

        Returns
        -------
        correlate : array
            An N-dimensional array containing a subset of the discrete linear
            cross-correlation of `in1` with `in2`.

        See Also
        --------
        choose_conv_method : contains more documentation on `method`.
        correlation_lags : calculates the lag / displacement indices array for 1D
            cross-correlation.

        Notes
        -----
        The correlation z of two d-dimensional arrays x and y is defined as::

            z[...,k,...] = sum[..., i_l, ...] x[..., i_l,...] * conj(y[..., i_l - k,...])

        This way, if x and y are 1-D arrays and ``z = correlate(x, y, 'full')``
        then

        .. math::

              z[k] = (x * y)(k - N + 1)
                   = \sum_{l=0}^{||x||-1}x_l y_{l-k+N-1}^{*}

        for :math:`k = 0, 1, ..., ||x|| + ||y|| - 2`

        where :math:`||x||` is the length of ``x``, :math:`N = \max(||x||,||y||)`,
        and :math:`y_m` is 0 when m is outside the range of y.

        ``method='fft'`` only works for numerical arrays as it relies on
        `fftconvolve`. In certain cases (i.e., arrays of objects or when
        rounding integers can lose precision), ``method='direct'`` is always used.

        When using "same" mode with even-length inputs, the outputs of `correlate`
        and `correlate2d` differ: There is a 1-index offset between them.

        Examples
        --------
        Implement a matched filter using cross-correlation, to recover a signal
        that has passed through a noisy channel.

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        >>> sig = np.repeat([0., 1., 1., 0., 1., 0., 0., 1.], 128)
        >>> sig_noise = sig + rng.standard_normal(len(sig))
        >>> corr = signal.correlate(sig_noise, np.ones(128), mode='same') / 128

        >>> clock = np.arange(64, len(sig), 128)
        >>> fig, (ax_orig, ax_noise, ax_corr) = plt.subplots(3, 1, sharex=True)
        >>> ax_orig.plot(sig)
        >>> ax_orig.plot(clock, sig[clock], 'ro')
        >>> ax_orig.set_title('Original signal')
        >>> ax_noise.plot(sig_noise)
        >>> ax_noise.set_title('Signal with noise')
        >>> ax_corr.plot(corr)
        >>> ax_corr.plot(clock, corr[clock], 'ro')
        >>> ax_corr.axhline(0.5, ls=':')
        >>> ax_corr.set_title('Cross-correlated with rectangular pulse')
        >>> ax_orig.margins(0, 0.1)
        >>> fig.tight_layout()
        >>> plt.show()

        Compute the cross-correlation of a noisy signal with the original signal.

        >>> x = np.arange(128) / 128
        >>> sig = np.sin(2 * np.pi * x)
        >>> sig_noise = sig + rng.standard_normal(len(sig))
        >>> corr = signal.correlate(sig_noise, sig)
        >>> lags = signal.correlation_lags(len(sig), len(sig_noise))
        >>> corr /= np.max(corr)

        >>> fig, (ax_orig, ax_noise, ax_corr) = plt.subplots(3, 1, figsize=(4.8, 4.8))
        >>> ax_orig.plot(sig)
        >>> ax_orig.set_title('Original signal')
        >>> ax_orig.set_xlabel('Sample Number')
        >>> ax_noise.plot(sig_noise)
        >>> ax_noise.set_title('Signal with noise')
        >>> ax_noise.set_xlabel('Sample Number')
        >>> ax_corr.plot(lags, corr)
        >>> ax_corr.set_title('Cross-correlated signal')
        >>> ax_corr.set_xlabel('Lag')
        >>> ax_orig.margins(0, 0.1)
        >>> ax_noise.margins(0, 0.1)
        >>> ax_corr.margins(0, 0.1)
        >>> fig.tight_layout()
        >>> plt.show()

    correlate2d(in1, in2, mode='full', boundary='fill', fillvalue=0)
        Cross-correlate two 2-dimensional arrays.

        Cross correlate `in1` and `in2` with output size determined by `mode`, and
        boundary conditions determined by `boundary` and `fillvalue`.

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear cross-correlation
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        boundary : str {'fill', 'wrap', 'symm'}, optional
            A flag indicating how to handle boundaries:

            ``fill``
               pad input arrays with fillvalue. (default)
            ``wrap``
               circular boundary conditions.
            ``symm``
               symmetrical boundary conditions.

        fillvalue : scalar, optional
            Value to fill pad input arrays with. Default is 0.

        Returns
        -------
        correlate2d : ndarray
            A 2-dimensional array containing a subset of the discrete linear
            cross-correlation of `in1` with `in2`.

        Notes
        -----
        When using "same" mode with even-length inputs, the outputs of `correlate`
        and `correlate2d` differ: There is a 1-index offset between them.

        Examples
        --------
        Use 2D cross-correlation to find the location of a template in a noisy
        image:

        >>> import numpy as np
        >>> from scipy import signal, datasets, ndimage
        >>> rng = np.random.default_rng()
        >>> face = datasets.face(gray=True) - datasets.face(gray=True).mean()
        >>> face = ndimage.zoom(face[30:500, 400:950], 0.5)  # extract the face
        >>> template = np.copy(face[135:165, 140:175])  # right eye
        >>> template -= template.mean()
        >>> face = face + rng.standard_normal(face.shape) * 50  # add noise
        >>> corr = signal.correlate2d(face, template, boundary='symm', mode='same')
        >>> y, x = np.unravel_index(np.argmax(corr), corr.shape)  # find the match

        >>> import matplotlib.pyplot as plt
        >>> fig, (ax_orig, ax_template, ax_corr) = plt.subplots(3, 1,
        ...                                                     figsize=(6, 15))
        >>> ax_orig.imshow(face, cmap='gray')
        >>> ax_orig.set_title('Original')
        >>> ax_orig.set_axis_off()
        >>> ax_template.imshow(template, cmap='gray')
        >>> ax_template.set_title('Template')
        >>> ax_template.set_axis_off()
        >>> ax_corr.imshow(corr, cmap='gray')
        >>> ax_corr.set_title('Cross-correlation')
        >>> ax_corr.set_axis_off()
        >>> ax_orig.plot(x, y, 'ro')
        >>> fig.show()

    correlation_lags(in1_len, in2_len, mode='full')
        Calculates the lag / displacement indices array for 1D cross-correlation.

        Parameters
        ----------
        in1_len : int
            First input size.
        in2_len : int
            Second input size.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output.
            See the documentation `correlate` for more information.

        Returns
        -------
        lags : array
            Returns an array containing cross-correlation lag/displacement indices.
            Indices can be indexed with the np.argmax of the correlation to return
            the lag/displacement.

        See Also
        --------
        correlate : Compute the N-dimensional cross-correlation.

        Notes
        -----
        Cross-correlation for continuous functions :math:`f` and :math:`g` is
        defined as:

        .. math::

            \left ( f\star g \right )\left ( \tau \right )
            \triangleq \int_{t_0}^{t_0 +T}
            \overline{f\left ( t \right )}g\left ( t+\tau \right )dt

        Where :math:`\tau` is defined as the displacement, also known as the lag.

        Cross correlation for discrete functions :math:`f` and :math:`g` is
        defined as:

        .. math::
            \left ( f\star g \right )\left [ n \right ]
            \triangleq \sum_{-\infty}^{\infty}
            \overline{f\left [ m \right ]}g\left [ m+n \right ]

        Where :math:`n` is the lag.

        Examples
        --------
        Cross-correlation of a signal with its time-delayed self.

        >>> import numpy as np
        >>> from scipy import signal
        >>> rng = np.random.default_rng()
        >>> x = rng.standard_normal(1000)
        >>> y = np.concatenate([rng.standard_normal(100), x])
        >>> correlation = signal.correlate(x, y, mode="full")
        >>> lags = signal.correlation_lags(x.size, y.size, mode="full")
        >>> lag = lags[np.argmax(correlation)]

    csd(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1, average='mean')
        Estimate the cross power spectral density, Pxy, using Welch's method.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        y : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` and `y` time series. Defaults
            to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg. Defaults
            to a Hann window.
        nperseg : int, optional
            Length of each segment. Defaults to None, but if window is str or
            tuple, is set to 256, and if window is array_like, is set to the
            length of the window.
        noverlap: int, optional
            Number of points to overlap between segments. If `None`,
            ``noverlap = nperseg // 2``. Defaults to `None`.
        nfft : int, optional
            Length of the FFT used, if a zero padded FFT is desired. If
            `None`, the FFT length is `nperseg`. Defaults to `None`.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to 'constant'.
        return_onesided : bool, optional
            If `True`, return a one-sided spectrum for real data. If
            `False` return a two-sided spectrum. Defaults to `True`, but for
            complex data, a two-sided spectrum is always returned.
        scaling : { 'density', 'spectrum' }, optional
            Selects between computing the cross spectral density ('density')
            where `Pxy` has units of V**2/Hz and computing the cross spectrum
            ('spectrum') where `Pxy` has units of V**2, if `x` and `y` are
            measured in V and `fs` is measured in Hz. Defaults to 'density'
        axis : int, optional
            Axis along which the CSD is computed for both inputs; the
            default is over the last axis (i.e. ``axis=-1``).
        average : { 'mean', 'median' }, optional
            Method to use when averaging periodograms. If the spectrum is
            complex, the average is computed separately for the real and
            imaginary parts. Defaults to 'mean'.

            .. versionadded:: 1.2.0

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        Pxy : ndarray
            Cross spectral density or cross power spectrum of x,y.

        See Also
        --------
        periodogram: Simple, optionally modified periodogram
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data
        welch: Power spectral density by Welch's method. [Equivalent to
               csd(x,x)]
        coherence: Magnitude squared coherence by Welch's method.

        Notes
        -----
        By convention, Pxy is computed with the conjugate FFT of X
        multiplied by the FFT of Y.

        If the input series differ in length, the shorter series will be
        zero-padded to match.

        An appropriate amount of overlap will depend on the choice of window
        and on your requirements. For the default Hann window an overlap of
        50% is a reasonable trade off between accurately estimating the
        signal power, while not over counting any of the data. Narrower
        windows may require a larger overlap.

        Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
        for a discussion of the scalings of a spectral density and an (amplitude) spectrum.

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] P. Welch, "The use of the fast Fourier transform for the
               estimation of power spectra: A method based on time averaging
               over short, modified periodograms", IEEE Trans. Audio
               Electroacoust. vol. 15, pp. 70-73, 1967.
        .. [2] Rabiner, Lawrence R., and B. Gold. "Theory and Application of
               Digital Signal Processing" Prentice-Hall, pp. 414-419, 1975

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate two test signals with some common features.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 20
        >>> freq = 1234.0
        >>> noise_power = 0.001 * fs / 2
        >>> time = np.arange(N) / fs
        >>> b, a = signal.butter(2, 0.25, 'low')
        >>> x = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
        >>> y = signal.lfilter(b, a, x)
        >>> x += amp*np.sin(2*np.pi*freq*time)
        >>> y += rng.normal(scale=0.1*np.sqrt(noise_power), size=time.shape)

        Compute and plot the magnitude of the cross spectral density.

        >>> f, Pxy = signal.csd(x, y, fs, nperseg=1024)
        >>> plt.semilogy(f, np.abs(Pxy))
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('CSD [V**2/Hz]')
        >>> plt.show()

    cspline1d(signal, lamb=0.0)
        Compute cubic spline coefficients for rank-1 array.

        Find the cubic spline coefficients for a 1-D signal assuming
        mirror-symmetric boundary conditions. To obtain the signal back from the
        spline representation mirror-symmetric-convolve these coefficients with a
        length 3 FIR window [1.0, 4.0, 1.0]/ 6.0 .

        Parameters
        ----------
        signal : ndarray
            A rank-1 array representing samples of a signal.
        lamb : float, optional
            Smoothing coefficient, default is 0.0.

        Returns
        -------
        c : ndarray
            Cubic spline coefficients.

        See Also
        --------
        cspline1d_eval : Evaluate a cubic spline at the new set of points.

        Examples
        --------
        We can filter a signal to reduce and smooth out high-frequency noise with
        a cubic spline:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import cspline1d, cspline1d_eval
        >>> rng = np.random.default_rng()
        >>> sig = np.repeat([0., 1., 0.], 100)
        >>> sig += rng.standard_normal(len(sig))*0.05  # add noise
        >>> time = np.linspace(0, len(sig))
        >>> filtered = cspline1d_eval(cspline1d(sig), time)
        >>> plt.plot(sig, label="signal")
        >>> plt.plot(time, filtered, label="filtered")
        >>> plt.legend()
        >>> plt.show()

    cspline1d_eval(cj, newx, dx=1.0, x0=0)
        Evaluate a cubic spline at the new set of points.

        `dx` is the old sample-spacing while `x0` was the old origin. In
        other-words the old-sample points (knot-points) for which the `cj`
        represent spline coefficients were at equally-spaced points of:

          oldx = x0 + j*dx  j=0...N-1, with N=len(cj)

        Edges are handled using mirror-symmetric boundary conditions.

        Parameters
        ----------
        cj : ndarray
            cublic spline coefficients
        newx : ndarray
            New set of points.
        dx : float, optional
            Old sample-spacing, the default value is 1.0.
        x0 : int, optional
            Old origin, the default value is 0.

        Returns
        -------
        res : ndarray
            Evaluated a cubic spline points.

        See Also
        --------
        cspline1d : Compute cubic spline coefficients for rank-1 array.

        Examples
        --------
        We can filter a signal to reduce and smooth out high-frequency noise with
        a cubic spline:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import cspline1d, cspline1d_eval
        >>> rng = np.random.default_rng()
        >>> sig = np.repeat([0., 1., 0.], 100)
        >>> sig += rng.standard_normal(len(sig))*0.05  # add noise
        >>> time = np.linspace(0, len(sig))
        >>> filtered = cspline1d_eval(cspline1d(sig), time)
        >>> plt.plot(sig, label="signal")
        >>> plt.plot(time, filtered, label="filtered")
        >>> plt.legend()
        >>> plt.show()

    cspline2d(...)
        out = cspline2d(input, lambda=0.0, precision=-1.0)

        Coefficients for 2-D cubic (3rd order) B-spline.

        Return the third-order B-spline coefficients over a regularly spaced
        input grid for the two-dimensional input image.

        Parameters
        ----------
        input : ndarray
            The input signal.
        lambda : float
            Specifies the amount of smoothing in the transfer function.
        precision : float
            Specifies the precision for computing the infinite sum needed to apply mirror-
            symmetric boundary conditions.

        Returns
        -------
        output : ndarray
            The filtered signal.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-signal-bsplines>`.

    cwt(data, wavelet, widths, dtype=None, **kwargs)
        Continuous wavelet transform.

        .. deprecated:: 1.12.0

            scipy.signal.cwt is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        Performs a continuous wavelet transform on `data`,
        using the `wavelet` function. A CWT performs a convolution
        with `data` using the `wavelet` function, which is characterized
        by a width parameter and length parameter. The `wavelet` function
        is allowed to be complex.

        Parameters
        ----------
        data : (N,) ndarray
            data on which to perform the transform.
        wavelet : function
            Wavelet function, which should take 2 arguments.
            The first argument is the number of points that the returned vector
            will have (len(wavelet(length,width)) == length).
            The second is a width parameter, defining the size of the wavelet
            (e.g. standard deviation of a gaussian). See `ricker`, which
            satisfies these requirements.
        widths : (M,) sequence
            Widths to use for transform.
        dtype : data-type, optional
            The desired data type of output. Defaults to ``float64`` if the
            output of `wavelet` is real and ``complex128`` if it is complex.

            .. versionadded:: 1.4.0

        kwargs
            Keyword arguments passed to wavelet function.

            .. versionadded:: 1.4.0

        Returns
        -------
        cwt: (M, N) ndarray
            Will have shape of (len(widths), len(data)).

        Notes
        -----

        .. versionadded:: 1.4.0

        For non-symmetric, complex-valued wavelets, the input signal is convolved
        with the time-reversed complex-conjugate of the wavelet data [1].

        ::

            length = min(10 * width[ii], len(data))
            cwt[ii,:] = signal.convolve(data, np.conj(wavelet(length, width[ii],
                                            **kwargs))[::-1], mode='same')

        References
        ----------
        .. [1] S. Mallat, "A Wavelet Tour of Signal Processing (3rd Edition)",
            Academic Press, 2009.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> t = np.linspace(-1, 1, 200, endpoint=False)
        >>> sig  = np.cos(2 * np.pi * 7 * t) + signal.gausspulse(t - 0.4, fc=2)
        >>> widths = np.arange(1, 31)
        >>> cwtmatr = signal.cwt(sig, signal.ricker, widths)

        .. note:: For cwt matrix plotting it is advisable to flip the y-axis

        >>> cwtmatr_yflip = np.flipud(cwtmatr)
        >>> plt.imshow(cwtmatr_yflip, extent=[-1, 1, 1, 31], cmap='PRGn', aspect='auto',
        ...            vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max())
        >>> plt.show()

    czt(x, m=None, w=None, a=(1+0j), *, axis=-1)
        Compute the frequency response around a spiral in the Z plane.

        Parameters
        ----------
        x : array
            The signal to transform.
        m : int, optional
            The number of output points desired.  Default is the length of the
            input data.
        w : complex, optional
            The ratio between points in each step.  This must be precise or the
            accumulated error will degrade the tail of the output sequence.
            Defaults to equally spaced points around the entire unit circle.
        a : complex, optional
            The starting point in the complex plane.  Default is 1+0j.
        axis : int, optional
            Axis over which to compute the FFT. If not given, the last axis is
            used.

        Returns
        -------
        out : ndarray
            An array of the same dimensions as `x`, but with the length of the
            transformed axis set to `m`.

        See Also
        --------
        CZT : Class that creates a callable chirp z-transform function.
        zoom_fft : Convenience function for partial FFT calculations.

        Notes
        -----
        The defaults are chosen such that ``signal.czt(x)`` is equivalent to
        ``fft.fft(x)`` and, if ``m > len(x)``, that ``signal.czt(x, m)`` is
        equivalent to ``fft.fft(x, m)``.

        If the transform needs to be repeated, use `CZT` to construct a
        specialized transform function which can be reused without
        recomputing constants.

        An example application is in system identification, repeatedly evaluating
        small slices of the z-transform of a system, around where a pole is
        expected to exist, to refine the estimate of the pole's true location. [1]_

        References
        ----------
        .. [1] Steve Alan Shilling, "A study of the chirp z-transform and its
               applications", pg 20 (1970)
               https://krex.k-state.edu/dspace/bitstream/handle/2097/7844/LD2668R41972S43.pdf

        Examples
        --------
        Generate a sinusoid:

        >>> import numpy as np
        >>> f1, f2, fs = 8, 10, 200  # Hz
        >>> t = np.linspace(0, 1, fs, endpoint=False)
        >>> x = np.sin(2*np.pi*t*f2)
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(t, x)
        >>> plt.axis([0, 1, -1.1, 1.1])
        >>> plt.show()

        Its discrete Fourier transform has all of its energy in a single frequency
        bin:

        >>> from scipy.fft import rfft, rfftfreq
        >>> from scipy.signal import czt, czt_points
        >>> plt.plot(rfftfreq(fs, 1/fs), abs(rfft(x)))
        >>> plt.margins(0, 0.1)
        >>> plt.show()

        However, if the sinusoid is logarithmically-decaying:

        >>> x = np.exp(-t*f1) * np.sin(2*np.pi*t*f2)
        >>> plt.plot(t, x)
        >>> plt.axis([0, 1, -1.1, 1.1])
        >>> plt.show()

        the DFT will have spectral leakage:

        >>> plt.plot(rfftfreq(fs, 1/fs), abs(rfft(x)))
        >>> plt.margins(0, 0.1)
        >>> plt.show()

        While the DFT always samples the z-transform around the unit circle, the
        chirp z-transform allows us to sample the Z-transform along any
        logarithmic spiral, such as a circle with radius smaller than unity:

        >>> M = fs // 2  # Just positive frequencies, like rfft
        >>> a = np.exp(-f1/fs)  # Starting point of the circle, radius < 1
        >>> w = np.exp(-1j*np.pi/M)  # "Step size" of circle
        >>> points = czt_points(M + 1, w, a)  # M + 1 to include Nyquist
        >>> plt.plot(points.real, points.imag, '.')
        >>> plt.gca().add_patch(plt.Circle((0,0), radius=1, fill=False, alpha=.3))
        >>> plt.axis('equal'); plt.axis([-1.05, 1.05, -0.05, 1.05])
        >>> plt.show()

        With the correct radius, this transforms the decaying sinusoid (and others
        with the same decay rate) without spectral leakage:

        >>> z_vals = czt(x, M + 1, w, a)  # Include Nyquist for comparison to rfft
        >>> freqs = np.angle(points)*fs/(2*np.pi)  # angle = omega, radius = sigma
        >>> plt.plot(freqs, abs(z_vals))
        >>> plt.margins(0, 0.1)
        >>> plt.show()

    czt_points(m, w=None, a=(1+0j))
        Return the points at which the chirp z-transform is computed.

        Parameters
        ----------
        m : int
            The number of points desired.
        w : complex, optional
            The ratio between points in each step.
            Defaults to equally spaced points around the entire unit circle.
        a : complex, optional
            The starting point in the complex plane.  Default is 1+0j.

        Returns
        -------
        out : ndarray
            The points in the Z plane at which `CZT` samples the z-transform,
            when called with arguments `m`, `w`, and `a`, as complex numbers.

        See Also
        --------
        CZT : Class that creates a callable chirp z-transform function.
        czt : Convenience function for quickly calculating CZT.

        Examples
        --------
        Plot the points of a 16-point FFT:

        >>> import numpy as np
        >>> from scipy.signal import czt_points
        >>> points = czt_points(16)
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(points.real, points.imag, 'o')
        >>> plt.gca().add_patch(plt.Circle((0,0), radius=1, fill=False, alpha=.3))
        >>> plt.axis('equal')
        >>> plt.show()

        and a 91-point logarithmic spiral that crosses the unit circle:

        >>> m, w, a = 91, 0.995*np.exp(-1j*np.pi*.05), 0.8*np.exp(1j*np.pi/6)
        >>> points = czt_points(m, w, a)
        >>> plt.plot(points.real, points.imag, 'o')
        >>> plt.gca().add_patch(plt.Circle((0,0), radius=1, fill=False, alpha=.3))
        >>> plt.axis('equal')
        >>> plt.show()

    daub(p)
        The coefficients for the FIR low-pass filter producing Daubechies wavelets.

        .. deprecated:: 1.12.0

            scipy.signal.daub is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        p>=1 gives the order of the zero at f=1/2.
        There are 2p filter coefficients.

        Parameters
        ----------
        p : int
            Order of the zero at f=1/2, can have values from 1 to 34.

        Returns
        -------
        daub : ndarray
            Return

    dbode(system, w=None, n=100)
        Calculate Bode magnitude and phase data of a discrete-time system.

        Parameters
        ----------
        system : an instance of the LTI class or a tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `dlti`)
                * 2 (num, den, dt)
                * 3 (zeros, poles, gain, dt)
                * 4 (A, B, C, D, dt)

        w : array_like, optional
            Array of frequencies (in radians/sample). Magnitude and phase data is
            calculated for every value in this array. If not given a reasonable
            set will be calculated.
        n : int, optional
            Number of frequency points to compute if `w` is not given. The `n`
            frequencies are logarithmically spaced in an interval chosen to
            include the influence of the poles and zeros of the system.

        Returns
        -------
        w : 1D ndarray
            Frequency array [rad/time_unit]
        mag : 1D ndarray
            Magnitude array [dB]
        phase : 1D ndarray
            Phase array [deg]

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``z^2 + 3z + 5`` would be represented as ``[1, 3, 5]``).

        .. versionadded:: 0.18.0

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        Construct the transfer function :math:`H(z) = \frac{1}{z^2 + 2z + 3}` with
        a sampling time of 0.05 seconds:

        >>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05)

        Equivalent: sys.bode()

        >>> w, mag, phase = signal.dbode(sys)

        >>> plt.figure()
        >>> plt.semilogx(w, mag)    # Bode magnitude plot
        >>> plt.figure()
        >>> plt.semilogx(w, phase)  # Bode phase plot
        >>> plt.show()

    decimate(x, q, n=None, ftype='iir', axis=-1, zero_phase=True)
        Downsample the signal after applying an anti-aliasing filter.

        By default, an order 8 Chebyshev type I filter is used. A 30 point FIR
        filter with Hamming window is used if `ftype` is 'fir'.

        Parameters
        ----------
        x : array_like
            The signal to be downsampled, as an N-dimensional array.
        q : int
            The downsampling factor. When using IIR downsampling, it is recommended
            to call `decimate` multiple times for downsampling factors higher than
            13.
        n : int, optional
            The order of the filter (1 less than the length for 'fir'). Defaults to
            8 for 'iir' and 20 times the downsampling factor for 'fir'.
        ftype : str {'iir', 'fir'} or ``dlti`` instance, optional
            If 'iir' or 'fir', specifies the type of lowpass filter. If an instance
            of an `dlti` object, uses that object to filter before downsampling.
        axis : int, optional
            The axis along which to decimate.
        zero_phase : bool, optional
            Prevent phase shift by filtering with `filtfilt` instead of `lfilter`
            when using an IIR filter, and shifting the outputs back by the filter's
            group delay when using an FIR filter. The default value of ``True`` is
            recommended, since a phase shift is generally not desired.

            .. versionadded:: 0.18.0

        Returns
        -------
        y : ndarray
            The down-sampled signal.

        See Also
        --------
        resample : Resample up or down using the FFT method.
        resample_poly : Resample using polyphase filtering and an FIR filter.

        Notes
        -----
        The ``zero_phase`` keyword was added in 0.18.0.
        The possibility to use instances of ``dlti`` as ``ftype`` was added in
        0.18.0.

        Examples
        --------

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        Define wave parameters.

        >>> wave_duration = 3
        >>> sample_rate = 100
        >>> freq = 2
        >>> q = 5

        Calculate number of samples.

        >>> samples = wave_duration*sample_rate
        >>> samples_decimated = int(samples/q)

        Create cosine wave.

        >>> x = np.linspace(0, wave_duration, samples, endpoint=False)
        >>> y = np.cos(x*np.pi*freq*2)

        Decimate cosine wave.

        >>> ydem = signal.decimate(y, q)
        >>> xnew = np.linspace(0, wave_duration, samples_decimated, endpoint=False)

        Plot original and decimated waves.

        >>> plt.plot(x, y, '.-', xnew, ydem, 'o-')
        >>> plt.xlabel('Time, Seconds')
        >>> plt.legend(['data', 'decimated'], loc='best')
        >>> plt.show()

    deconvolve(signal, divisor)
        Deconvolves ``divisor`` out of ``signal`` using inverse filtering.

        Returns the quotient and remainder such that
        ``signal = convolve(divisor, quotient) + remainder``

        Parameters
        ----------
        signal : (N,) array_like
            Signal data, typically a recorded signal
        divisor : (N,) array_like
            Divisor data, typically an impulse response or filter that was
            applied to the original signal

        Returns
        -------
        quotient : ndarray
            Quotient, typically the recovered original signal
        remainder : ndarray
            Remainder

        See Also
        --------
        numpy.polydiv : performs polynomial division (same operation, but
                        also accepts poly1d objects)

        Examples
        --------
        Deconvolve a signal that's been filtered:

        >>> from scipy import signal
        >>> original = [0, 1, 0, 0, 1, 1, 0, 0]
        >>> impulse_response = [2, 1]
        >>> recorded = signal.convolve(impulse_response, original)
        >>> recorded
        array([0, 2, 1, 0, 2, 3, 1, 0, 0])
        >>> recovered, remainder = signal.deconvolve(recorded, impulse_response)
        >>> recovered
        array([ 0.,  1.,  0.,  0.,  1.,  1.,  0.,  0.])

    detrend(data: 'np.ndarray', axis: 'int' = -1, type: "Literal['linear', 'constant']" = 'linear', bp: 'ArrayLike | int' = 0, overwrite_data: 'bool' = False) -> 'np.ndarray'
        Remove linear or constant trend along axis from data.

        Parameters
        ----------
        data : array_like
            The input data.
        axis : int, optional
            The axis along which to detrend the data. By default this is the
            last axis (-1).
        type : {'linear', 'constant'}, optional
            The type of detrending. If ``type == 'linear'`` (default),
            the result of a linear least-squares fit to `data` is subtracted
            from `data`.
            If ``type == 'constant'``, only the mean of `data` is subtracted.
        bp : array_like of ints, optional
            A sequence of break points. If given, an individual linear fit is
            performed for each part of `data` between two break points.
            Break points are specified as indices into `data`. This parameter
            only has an effect when ``type == 'linear'``.
        overwrite_data : bool, optional
            If True, perform in place detrending and avoid a copy. Default is False

        Returns
        -------
        ret : ndarray
            The detrended input data.

        Notes
        -----
        Detrending can be interpreted as substracting a least squares fit polyonimial:
        Setting the parameter `type` to 'constant' corresponds to fitting a zeroth degree
        polynomial, 'linear' to a first degree polynomial. Consult the example below.

        See Also
        --------
        numpy.polynomial.polynomial.Polynomial.fit: Create least squares fit polynomial.


        Examples
        --------
        The following example detrends the function :math:`x(t) = \sin(\pi t) + 1/4`:

        >>> import matplotlib.pyplot as plt
        >>> import numpy as np
        >>> from scipy.signal import detrend
        ...
        >>> t = np.linspace(-0.5, 0.5, 21)
        >>> x = np.sin(np.pi*t) + 1/4
        ...
        >>> x_d_const = detrend(x, type='constant')
        >>> x_d_linear = detrend(x, type='linear')
        ...
        >>> fig1, ax1 = plt.subplots()
        >>> ax1.set_title(r"Detrending $x(t)=\sin(\pi t) + 1/4$")
        >>> ax1.set(xlabel="t", ylabel="$x(t)$", xlim=(t[0], t[-1]))
        >>> ax1.axhline(y=0, color='black', linewidth=.5)
        >>> ax1.axvline(x=0, color='black', linewidth=.5)
        >>> ax1.plot(t, x, 'C0.-',  label="No detrending")
        >>> ax1.plot(t, x_d_const, 'C1x-', label="type='constant'")
        >>> ax1.plot(t, x_d_linear, 'C2+-', label="type='linear'")
        >>> ax1.legend()
        >>> plt.show()

        Alternatively, NumPy's `~numpy.polynomial.polynomial.Polynomial` can be used for
        detrending as well:

        >>> pp0 = np.polynomial.Polynomial.fit(t, x, deg=0)  # fit degree 0 polynomial
        >>> np.allclose(x_d_const, x - pp0(t))  # compare with constant detrend
        True
        >>> pp1 = np.polynomial.Polynomial.fit(t, x, deg=1)  # fit degree 1 polynomial
        >>> np.allclose(x_d_linear, x - pp1(t))  # compare with linear detrend
        True

        Note that `~numpy.polynomial.polynomial.Polynomial` also allows fitting higher
        degree polynomials. Consult its documentation on how to extract the polynomial
        coefficients.

    dfreqresp(system, w=None, n=10000, whole=False)
        Calculate the frequency response of a discrete-time system.

        Parameters
        ----------
        system : an instance of the `dlti` class or a tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `dlti`)
                * 2 (numerator, denominator, dt)
                * 3 (zeros, poles, gain, dt)
                * 4 (A, B, C, D, dt)

        w : array_like, optional
            Array of frequencies (in radians/sample). Magnitude and phase data is
            calculated for every value in this array. If not given a reasonable
            set will be calculated.
        n : int, optional
            Number of frequency points to compute if `w` is not given. The `n`
            frequencies are logarithmically spaced in an interval chosen to
            include the influence of the poles and zeros of the system.
        whole : bool, optional
            Normally, if 'w' is not given, frequencies are computed from 0 to the
            Nyquist frequency, pi radians/sample (upper-half of unit-circle). If
            `whole` is True, compute frequencies from 0 to 2*pi radians/sample.

        Returns
        -------
        w : 1D ndarray
            Frequency array [radians/sample]
        H : 1D ndarray
            Array of complex magnitude values

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``z^2 + 3z + 5`` would be represented as ``[1, 3, 5]``).

        .. versionadded:: 0.18.0

        Examples
        --------
        Generating the Nyquist plot of a transfer function

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        Construct the transfer function
        :math:`H(z) = \frac{1}{z^2 + 2z + 3}` with a sampling time of 0.05
        seconds:

        >>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05)

        >>> w, H = signal.dfreqresp(sys)

        >>> plt.figure()
        >>> plt.plot(H.real, H.imag, "b")
        >>> plt.plot(H.real, -H.imag, "r")
        >>> plt.show()

    dimpulse(system, x0=None, t=None, n=None)
        Impulse response of discrete-time system.

        Parameters
        ----------
        system : tuple of array_like or instance of `dlti`
            A tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1: (instance of `dlti`)
                * 3: (num, den, dt)
                * 4: (zeros, poles, gain, dt)
                * 5: (A, B, C, D, dt)

        x0 : array_like, optional
            Initial state-vector.  Defaults to zero.
        t : array_like, optional
            Time points.  Computed if not given.
        n : int, optional
            The number of time points to compute (if `t` is not given).

        Returns
        -------
        tout : ndarray
            Time values for the output, as a 1-D array.
        yout : tuple of ndarray
            Impulse response of system.  Each element of the tuple represents
            the output of the system based on an impulse in each input.

        See Also
        --------
        impulse, dstep, dlsim, cont2discrete

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> butter = signal.dlti(*signal.butter(3, 0.5))
        >>> t, y = signal.dimpulse(butter, n=25)
        >>> plt.step(t, np.squeeze(y))
        >>> plt.grid()
        >>> plt.xlabel('n [samples]')
        >>> plt.ylabel('Amplitude')

    dlsim(system, u, t=None, x0=None)
        Simulate output of a discrete-time linear system.

        Parameters
        ----------
        system : tuple of array_like or instance of `dlti`
            A tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1: (instance of `dlti`)
                * 3: (num, den, dt)
                * 4: (zeros, poles, gain, dt)
                * 5: (A, B, C, D, dt)

        u : array_like
            An input array describing the input at each time `t` (interpolation is
            assumed between given times).  If there are multiple inputs, then each
            column of the rank-2 array represents an input.
        t : array_like, optional
            The time steps at which the input is defined.  If `t` is given, it
            must be the same length as `u`, and the final value in `t` determines
            the number of steps returned in the output.
        x0 : array_like, optional
            The initial conditions on the state vector (zero by default).

        Returns
        -------
        tout : ndarray
            Time values for the output, as a 1-D array.
        yout : ndarray
            System response, as a 1-D array.
        xout : ndarray, optional
            Time-evolution of the state-vector.  Only generated if the input is a
            `StateSpace` system.

        See Also
        --------
        lsim, dstep, dimpulse, cont2discrete

        Examples
        --------
        A simple integrator transfer function with a discrete time step of 1.0
        could be implemented as:

        >>> import numpy as np
        >>> from scipy import signal
        >>> tf = ([1.0,], [1.0, -1.0], 1.0)
        >>> t_in = [0.0, 1.0, 2.0, 3.0]
        >>> u = np.asarray([0.0, 0.0, 1.0, 1.0])
        >>> t_out, y = signal.dlsim(tf, u, t=t_in)
        >>> y.T
        array([[ 0.,  0.,  0.,  1.]])

    dstep(system, x0=None, t=None, n=None)
        Step response of discrete-time system.

        Parameters
        ----------
        system : tuple of array_like
            A tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1: (instance of `dlti`)
                * 3: (num, den, dt)
                * 4: (zeros, poles, gain, dt)
                * 5: (A, B, C, D, dt)

        x0 : array_like, optional
            Initial state-vector.  Defaults to zero.
        t : array_like, optional
            Time points.  Computed if not given.
        n : int, optional
            The number of time points to compute (if `t` is not given).

        Returns
        -------
        tout : ndarray
            Output time points, as a 1-D array.
        yout : tuple of ndarray
            Step response of system.  Each element of the tuple represents
            the output of the system based on a step response to each input.

        See Also
        --------
        step, dimpulse, dlsim, cont2discrete

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> butter = signal.dlti(*signal.butter(3, 0.5))
        >>> t, y = signal.dstep(butter, n=25)
        >>> plt.step(t, np.squeeze(y))
        >>> plt.grid()
        >>> plt.xlabel('n [samples]')
        >>> plt.ylabel('Amplitude')

    ellip(N, rp, rs, Wn, btype='low', analog=False, output='ba', fs=None)
        Elliptic (Cauer) digital and analog filter design.

        Design an Nth-order digital or analog elliptic filter and return
        the filter coefficients.

        Parameters
        ----------
        N : int
            The order of the filter.
        rp : float
            The maximum ripple allowed below unity gain in the passband.
            Specified in decibels, as a positive number.
        rs : float
            The minimum attenuation required in the stop band.
            Specified in decibels, as a positive number.
        Wn : array_like
            A scalar or length-2 sequence giving the critical frequencies.
            For elliptic filters, this is the point in the transition band at
            which the gain first drops below -`rp`.

            For digital filters, `Wn` are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`Wn` is thus in
            half-cycles / sample.)

            For analog filters, `Wn` is an angular frequency (e.g., rad/s).
        btype : {'lowpass', 'highpass', 'bandpass', 'bandstop'}, optional
            The type of filter. Default is 'lowpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        output : {'ba', 'zpk', 'sos'}, optional
            Type of output:  numerator/denominator ('ba'), pole-zero ('zpk'), or
            second-order sections ('sos'). Default is 'ba' for backwards
            compatibility, but 'sos' should be used for general-purpose filtering.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        ellipord, ellipap

        Notes
        -----
        Also known as Cauer or Zolotarev filters, the elliptical filter maximizes
        the rate of transition between the frequency response's passband and
        stopband, at the expense of ripple in both, and increased ringing in the
        step response.

        As `rp` approaches 0, the elliptical filter becomes a Chebyshev
        type II filter (`cheby2`). As `rs` approaches 0, it becomes a Chebyshev
        type I filter (`cheby1`). As both approach 0, it becomes a Butterworth
        filter (`butter`).

        The equiripple passband has N maxima or minima (for example, a
        5th-order filter has 3 maxima and 2 minima). Consequently, the DC gain is
        unity for odd-order filters, or -rp dB for even-order filters.

        The ``'sos'`` output parameter was added in 0.16.0.

        Examples
        --------
        Design an analog filter and plot its frequency response, showing the
        critical points:

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.ellip(4, 5, 40, 100, 'low', analog=True)
        >>> w, h = signal.freqs(b, a)
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Elliptic filter frequency response (rp=5, rs=40)')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(100, color='green') # cutoff frequency
        >>> plt.axhline(-40, color='green') # rs
        >>> plt.axhline(-5, color='green') # rp
        >>> plt.show()

        Generate a signal made up of 10 Hz and 20 Hz, sampled at 1 kHz

        >>> t = np.linspace(0, 1, 1000, False)  # 1 second
        >>> sig = np.sin(2*np.pi*10*t) + np.sin(2*np.pi*20*t)
        >>> fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
        >>> ax1.plot(t, sig)
        >>> ax1.set_title('10 Hz and 20 Hz sinusoids')
        >>> ax1.axis([0, 1, -2, 2])

        Design a digital high-pass filter at 17 Hz to remove the 10 Hz tone, and
        apply it to the signal. (It's recommended to use second-order sections
        format when filtering, to avoid numerical error with transfer function
        (``ba``) format):

        >>> sos = signal.ellip(8, 1, 100, 17, 'hp', fs=1000, output='sos')
        >>> filtered = signal.sosfilt(sos, sig)
        >>> ax2.plot(t, filtered)
        >>> ax2.set_title('After 17 Hz high-pass filter')
        >>> ax2.axis([0, 1, -2, 2])
        >>> ax2.set_xlabel('Time [seconds]')
        >>> plt.tight_layout()
        >>> plt.show()

    ellipap(N, rp, rs)
        Return (z,p,k) of Nth-order elliptic analog lowpass filter.

        The filter is a normalized prototype that has `rp` decibels of ripple
        in the passband and a stopband `rs` decibels down.

        The filter's angular (e.g., rad/s) cutoff frequency is normalized to 1,
        defined as the point at which the gain first drops below ``-rp``.

        See Also
        --------
        ellip : Filter design function using this prototype

        References
        ----------
        .. [1] Lutovac, Tosic, and Evans, "Filter Design for Signal Processing",
               Chapters 5 and 12.

        .. [2] Orfanidis, "Lecture Notes on Elliptic Filter Design",
               https://www.ece.rutgers.edu/~orfanidi/ece521/notes.pdf

    ellipord(wp, ws, gpass, gstop, analog=False, fs=None)
        Elliptic (Cauer) filter order selection.

        Return the order of the lowest order digital or analog elliptic filter
        that loses no more than `gpass` dB in the passband and has at least
        `gstop` dB attenuation in the stopband.

        Parameters
        ----------
        wp, ws : float
            Passband and stopband edge frequencies.

            For digital filters, these are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`wp` and `ws` are thus in
            half-cycles / sample.) For example:

                - Lowpass:   wp = 0.2,          ws = 0.3
                - Highpass:  wp = 0.3,          ws = 0.2
                - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
                - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]

            For analog filters, `wp` and `ws` are angular frequencies (e.g., rad/s).
        gpass : float
            The maximum loss in the passband (dB).
        gstop : float
            The minimum attenuation in the stopband (dB).
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        ord : int
            The lowest order for an Elliptic (Cauer) filter that meets specs.
        wn : ndarray or float
            The Chebyshev natural frequency (the "3dB frequency") for use with
            `ellip` to give filter results. If `fs` is specified,
            this is in the same units, and `fs` must also be passed to `ellip`.

        See Also
        --------
        ellip : Filter design using order and critical points
        buttord : Find order and critical points from passband and stopband spec
        cheb1ord, cheb2ord
        iirfilter : General filter design using order and critical frequencies
        iirdesign : General filter design using passband and stopband spec

        Examples
        --------
        Design an analog highpass filter such that the passband is within 3 dB
        above 30 rad/s, while rejecting -60 dB at 10 rad/s. Plot its
        frequency response, showing the passband and stopband constraints in gray.

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> N, Wn = signal.ellipord(30, 10, 3, 60, True)
        >>> b, a = signal.ellip(N, 3, 60, Wn, 'high', True)
        >>> w, h = signal.freqs(b, a, np.logspace(0, 3, 500))
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.title('Elliptical highpass filter fit to constraints')
        >>> plt.xlabel('Frequency [radians / second]')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.grid(which='both', axis='both')
        >>> plt.fill([.1, 10,  10,  .1], [1e4, 1e4, -60, -60], '0.9', lw=0) # stop
        >>> plt.fill([30, 30, 1e9, 1e9], [-99,  -3,  -3, -99], '0.9', lw=0) # pass
        >>> plt.axis([1, 300, -80, 3])
        >>> plt.show()

    fftconvolve(in1, in2, mode='full', axes=None)
        Convolve two N-dimensional arrays using FFT.

        Convolve `in1` and `in2` using the fast Fourier transform method, with
        the output size determined by the `mode` argument.

        This is generally much faster than `convolve` for large arrays (n > ~500),
        but can be slower when only a few output values are needed, and can only
        output float arrays (int or object array inputs will be cast to float).

        As of v0.19, `convolve` automatically chooses this method or the direct
        method based on an estimation of which is faster.

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear convolution
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        axes : int or array_like of ints or None, optional
            Axes over which to compute the convolution.
            The default is over all axes.

        Returns
        -------
        out : array
            An N-dimensional array containing a subset of the discrete linear
            convolution of `in1` with `in2`.

        See Also
        --------
        convolve : Uses the direct convolution or FFT convolution algorithm
                   depending on which is faster.
        oaconvolve : Uses the overlap-add method to do convolution, which is
                     generally faster when the input arrays are large and
                     significantly different in size.

        Examples
        --------
        Autocorrelation of white noise is an impulse.

        >>> import numpy as np
        >>> from scipy import signal
        >>> rng = np.random.default_rng()
        >>> sig = rng.standard_normal(1000)
        >>> autocorr = signal.fftconvolve(sig, sig[::-1], mode='full')

        >>> import matplotlib.pyplot as plt
        >>> fig, (ax_orig, ax_mag) = plt.subplots(2, 1)
        >>> ax_orig.plot(sig)
        >>> ax_orig.set_title('White noise')
        >>> ax_mag.plot(np.arange(-len(sig)+1,len(sig)), autocorr)
        >>> ax_mag.set_title('Autocorrelation')
        >>> fig.tight_layout()
        >>> fig.show()

        Gaussian blur implemented using FFT convolution.  Notice the dark borders
        around the image, due to the zero-padding beyond its boundaries.
        The `convolve2d` function allows for other types of image boundaries,
        but is far slower.

        >>> from scipy import datasets
        >>> face = datasets.face(gray=True)
        >>> kernel = np.outer(signal.windows.gaussian(70, 8),
        ...                   signal.windows.gaussian(70, 8))
        >>> blurred = signal.fftconvolve(face, kernel, mode='same')

        >>> fig, (ax_orig, ax_kernel, ax_blurred) = plt.subplots(3, 1,
        ...                                                      figsize=(6, 15))
        >>> ax_orig.imshow(face, cmap='gray')
        >>> ax_orig.set_title('Original')
        >>> ax_orig.set_axis_off()
        >>> ax_kernel.imshow(kernel, cmap='gray')
        >>> ax_kernel.set_title('Gaussian kernel')
        >>> ax_kernel.set_axis_off()
        >>> ax_blurred.imshow(blurred, cmap='gray')
        >>> ax_blurred.set_title('Blurred')
        >>> ax_blurred.set_axis_off()
        >>> fig.show()

    filtfilt(b, a, x, axis=-1, padtype='odd', padlen=None, method='pad', irlen=None)
        Apply a digital filter forward and backward to a signal.

        This function applies a linear digital filter twice, once forward and
        once backwards.  The combined filter has zero phase and a filter order
        twice that of the original.

        The function provides options for handling the edges of the signal.

        The function `sosfiltfilt` (and filter design using ``output='sos'``)
        should be preferred over `filtfilt` for most filtering tasks, as
        second-order sections have fewer numerical problems.

        Parameters
        ----------
        b : (N,) array_like
            The numerator coefficient vector of the filter.
        a : (N,) array_like
            The denominator coefficient vector of the filter.  If ``a[0]``
            is not 1, then both `a` and `b` are normalized by ``a[0]``.
        x : array_like
            The array of data to be filtered.
        axis : int, optional
            The axis of `x` to which the filter is applied.
            Default is -1.
        padtype : str or None, optional
            Must be 'odd', 'even', 'constant', or None.  This determines the
            type of extension to use for the padded signal to which the filter
            is applied.  If `padtype` is None, no padding is used.  The default
            is 'odd'.
        padlen : int or None, optional
            The number of elements by which to extend `x` at both ends of
            `axis` before applying the filter.  This value must be less than
            ``x.shape[axis] - 1``.  ``padlen=0`` implies no padding.
            The default value is ``3 * max(len(a), len(b))``.
        method : str, optional
            Determines the method for handling the edges of the signal, either
            "pad" or "gust".  When `method` is "pad", the signal is padded; the
            type of padding is determined by `padtype` and `padlen`, and `irlen`
            is ignored.  When `method` is "gust", Gustafsson's method is used,
            and `padtype` and `padlen` are ignored.
        irlen : int or None, optional
            When `method` is "gust", `irlen` specifies the length of the
            impulse response of the filter.  If `irlen` is None, no part
            of the impulse response is ignored.  For a long signal, specifying
            `irlen` can significantly improve the performance of the filter.

        Returns
        -------
        y : ndarray
            The filtered output with the same shape as `x`.

        See Also
        --------
        sosfiltfilt, lfilter_zi, lfilter, lfiltic, savgol_filter, sosfilt

        Notes
        -----
        When `method` is "pad", the function pads the data along the given axis
        in one of three ways: odd, even or constant.  The odd and even extensions
        have the corresponding symmetry about the end point of the data.  The
        constant extension extends the data with the values at the end points. On
        both the forward and backward passes, the initial condition of the
        filter is found by using `lfilter_zi` and scaling it by the end point of
        the extended data.

        When `method` is "gust", Gustafsson's method [1]_ is used.  Initial
        conditions are chosen for the forward and backward passes so that the
        forward-backward filter gives the same result as the backward-forward
        filter.

        The option to use Gustaffson's method was added in scipy version 0.16.0.

        References
        ----------
        .. [1] F. Gustaffson, "Determining the initial states in forward-backward
               filtering", Transactions on Signal Processing, Vol. 46, pp. 988-992,
               1996.

        Examples
        --------
        The examples will use several functions from `scipy.signal`.

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        First we create a one second signal that is the sum of two pure sine
        waves, with frequencies 5 Hz and 250 Hz, sampled at 2000 Hz.

        >>> t = np.linspace(0, 1.0, 2001)
        >>> xlow = np.sin(2 * np.pi * 5 * t)
        >>> xhigh = np.sin(2 * np.pi * 250 * t)
        >>> x = xlow + xhigh

        Now create a lowpass Butterworth filter with a cutoff of 0.125 times
        the Nyquist frequency, or 125 Hz, and apply it to ``x`` with `filtfilt`.
        The result should be approximately ``xlow``, with no phase shift.

        >>> b, a = signal.butter(8, 0.125)
        >>> y = signal.filtfilt(b, a, x, padlen=150)
        >>> np.abs(y - xlow).max()
        9.1086182074789912e-06

        We get a fairly clean result for this artificial example because
        the odd extension is exact, and with the moderately long padding,
        the filter's transients have dissipated by the time the actual data
        is reached.  In general, transient effects at the edges are
        unavoidable.

        The following example demonstrates the option ``method="gust"``.

        First, create a filter.

        >>> b, a = signal.ellip(4, 0.01, 120, 0.125)  # Filter to be applied.

        `sig` is a random input signal to be filtered.

        >>> rng = np.random.default_rng()
        >>> n = 60
        >>> sig = rng.standard_normal(n)**3 + 3*rng.standard_normal(n).cumsum()

        Apply `filtfilt` to `sig`, once using the Gustafsson method, and
        once using padding, and plot the results for comparison.

        >>> fgust = signal.filtfilt(b, a, sig, method="gust")
        >>> fpad = signal.filtfilt(b, a, sig, padlen=50)
        >>> plt.plot(sig, 'k-', label='input')
        >>> plt.plot(fgust, 'b-', linewidth=4, label='gust')
        >>> plt.plot(fpad, 'c-', linewidth=1.5, label='pad')
        >>> plt.legend(loc='best')
        >>> plt.show()

        The `irlen` argument can be used to improve the performance
        of Gustafsson's method.

        Estimate the impulse response length of the filter.

        >>> z, p, k = signal.tf2zpk(b, a)
        >>> eps = 1e-9
        >>> r = np.max(np.abs(p))
        >>> approx_impulse_len = int(np.ceil(np.log(eps) / np.log(r)))
        >>> approx_impulse_len
        137

        Apply the filter to a longer signal, with and without the `irlen`
        argument.  The difference between `y1` and `y2` is small.  For long
        signals, using `irlen` gives a significant performance improvement.

        >>> x = rng.standard_normal(4000)
        >>> y1 = signal.filtfilt(b, a, x, method='gust')
        >>> y2 = signal.filtfilt(b, a, x, method='gust', irlen=approx_impulse_len)
        >>> print(np.max(np.abs(y1 - y2)))
        2.875334415008979e-10

    find_peaks(x, height=None, threshold=None, distance=None, prominence=None, width=None, wlen=None, rel_height=0.5, plateau_size=None)
        Find peaks inside a signal based on peak properties.

        This function takes a 1-D array and finds all local maxima by
        simple comparison of neighboring values. Optionally, a subset of these
        peaks can be selected by specifying conditions for a peak's properties.

        Parameters
        ----------
        x : sequence
            A signal with peaks.
        height : number or ndarray or sequence, optional
            Required height of peaks. Either a number, ``None``, an array matching
            `x` or a 2-element sequence of the former. The first element is
            always interpreted as the  minimal and the second, if supplied, as the
            maximal required height.
        threshold : number or ndarray or sequence, optional
            Required threshold of peaks, the vertical distance to its neighboring
            samples. Either a number, ``None``, an array matching `x` or a
            2-element sequence of the former. The first element is always
            interpreted as the  minimal and the second, if supplied, as the maximal
            required threshold.
        distance : number, optional
            Required minimal horizontal distance (>= 1) in samples between
            neighbouring peaks. Smaller peaks are removed first until the condition
            is fulfilled for all remaining peaks.
        prominence : number or ndarray or sequence, optional
            Required prominence of peaks. Either a number, ``None``, an array
            matching `x` or a 2-element sequence of the former. The first
            element is always interpreted as the  minimal and the second, if
            supplied, as the maximal required prominence.
        width : number or ndarray or sequence, optional
            Required width of peaks in samples. Either a number, ``None``, an array
            matching `x` or a 2-element sequence of the former. The first
            element is always interpreted as the  minimal and the second, if
            supplied, as the maximal required width.
        wlen : int, optional
            Used for calculation of the peaks prominences, thus it is only used if
            one of the arguments `prominence` or `width` is given. See argument
            `wlen` in `peak_prominences` for a full description of its effects.
        rel_height : float, optional
            Used for calculation of the peaks width, thus it is only used if `width`
            is given. See argument  `rel_height` in `peak_widths` for a full
            description of its effects.
        plateau_size : number or ndarray or sequence, optional
            Required size of the flat top of peaks in samples. Either a number,
            ``None``, an array matching `x` or a 2-element sequence of the former.
            The first element is always interpreted as the minimal and the second,
            if supplied as the maximal required plateau size.

            .. versionadded:: 1.2.0

        Returns
        -------
        peaks : ndarray
            Indices of peaks in `x` that satisfy all given conditions.
        properties : dict
            A dictionary containing properties of the returned peaks which were
            calculated as intermediate results during evaluation of the specified
            conditions:

            * 'peak_heights'
                  If `height` is given, the height of each peak in `x`.
            * 'left_thresholds', 'right_thresholds'
                  If `threshold` is given, these keys contain a peaks vertical
                  distance to its neighbouring samples.
            * 'prominences', 'right_bases', 'left_bases'
                  If `prominence` is given, these keys are accessible. See
                  `peak_prominences` for a description of their content.
            * 'width_heights', 'left_ips', 'right_ips'
                  If `width` is given, these keys are accessible. See `peak_widths`
                  for a description of their content.
            * 'plateau_sizes', left_edges', 'right_edges'
                  If `plateau_size` is given, these keys are accessible and contain
                  the indices of a peak's edges (edges are still part of the
                  plateau) and the calculated plateau sizes.

                  .. versionadded:: 1.2.0

            To calculate and return properties without excluding peaks, provide the
            open interval ``(None, None)`` as a value to the appropriate argument
            (excluding `distance`).

        Warns
        -----
        PeakPropertyWarning
            Raised if a peak's properties have unexpected values (see
            `peak_prominences` and `peak_widths`).

        Warnings
        --------
        This function may return unexpected results for data containing NaNs. To
        avoid this, NaNs should either be removed or replaced.

        See Also
        --------
        find_peaks_cwt
            Find peaks using the wavelet transformation.
        peak_prominences
            Directly calculate the prominence of peaks.
        peak_widths
            Directly calculate the width of peaks.

        Notes
        -----
        In the context of this function, a peak or local maximum is defined as any
        sample whose two direct neighbours have a smaller amplitude. For flat peaks
        (more than one sample of equal amplitude wide) the index of the middle
        sample is returned (rounded down in case the number of samples is even).
        For noisy signals the peak locations can be off because the noise might
        change the position of local maxima. In those cases consider smoothing the
        signal before searching for peaks or use other peak finding and fitting
        methods (like `find_peaks_cwt`).

        Some additional comments on specifying conditions:

        * Almost all conditions (excluding `distance`) can be given as half-open or
          closed intervals, e.g., ``1`` or ``(1, None)`` defines the half-open
          interval :math:`[1, \infty]` while ``(None, 1)`` defines the interval
          :math:`[-\infty, 1]`. The open interval ``(None, None)`` can be specified
          as well, which returns the matching properties without exclusion of peaks.
        * The border is always included in the interval used to select valid peaks.
        * For several conditions the interval borders can be specified with
          arrays matching `x` in shape which enables dynamic constrains based on
          the sample position.
        * The conditions are evaluated in the following order: `plateau_size`,
          `height`, `threshold`, `distance`, `prominence`, `width`. In most cases
          this order is the fastest one because faster operations are applied first
          to reduce the number of peaks that need to be evaluated later.
        * While indices in `peaks` are guaranteed to be at least `distance` samples
          apart, edges of flat peaks may be closer than the allowed `distance`.
        * Use `wlen` to reduce the time it takes to evaluate the conditions for
          `prominence` or `width` if `x` is large or has many local maxima
          (see `peak_prominences`).

        .. versionadded:: 1.1.0

        Examples
        --------
        To demonstrate this function's usage we use a signal `x` supplied with
        SciPy (see `scipy.datasets.electrocardiogram`). Let's find all peaks (local
        maxima) in `x` whose amplitude lies above 0.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.datasets import electrocardiogram
        >>> from scipy.signal import find_peaks
        >>> x = electrocardiogram()[2000:4000]
        >>> peaks, _ = find_peaks(x, height=0)
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.plot(np.zeros_like(x), "--", color="gray")
        >>> plt.show()

        We can select peaks below 0 with ``height=(None, 0)`` or use arrays matching
        `x` in size to reflect a changing condition for different parts of the
        signal.

        >>> border = np.sin(np.linspace(0, 3 * np.pi, x.size))
        >>> peaks, _ = find_peaks(x, height=(-border, border))
        >>> plt.plot(x)
        >>> plt.plot(-border, "--", color="gray")
        >>> plt.plot(border, ":", color="gray")
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.show()

        Another useful condition for periodic signals can be given with the
        `distance` argument. In this case, we can easily select the positions of
        QRS complexes within the electrocardiogram (ECG) by demanding a distance of
        at least 150 samples.

        >>> peaks, _ = find_peaks(x, distance=150)
        >>> np.diff(peaks)
        array([186, 180, 177, 171, 177, 169, 167, 164, 158, 162, 172])
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.show()

        Especially for noisy signals peaks can be easily grouped by their
        prominence (see `peak_prominences`). E.g., we can select all peaks except
        for the mentioned QRS complexes by limiting the allowed prominence to 0.6.

        >>> peaks, properties = find_peaks(x, prominence=(None, 0.6))
        >>> properties["prominences"].max()
        0.5049999999999999
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.show()

        And, finally, let's examine a different section of the ECG which contains
        beat forms of different shape. To select only the atypical heart beats, we
        combine two conditions: a minimal prominence of 1 and width of at least 20
        samples.

        >>> x = electrocardiogram()[17000:18000]
        >>> peaks, properties = find_peaks(x, prominence=1, width=20)
        >>> properties["prominences"], properties["widths"]
        (array([1.495, 2.3  ]), array([36.93773946, 39.32723577]))
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.vlines(x=peaks, ymin=x[peaks] - properties["prominences"],
        ...            ymax = x[peaks], color = "C1")
        >>> plt.hlines(y=properties["width_heights"], xmin=properties["left_ips"],
        ...            xmax=properties["right_ips"], color = "C1")
        >>> plt.show()

    find_peaks_cwt(vector, widths, wavelet=None, max_distances=None, gap_thresh=None, min_length=None, min_snr=1, noise_perc=10, window_size=None)
        Find peaks in a 1-D array with wavelet transformation.

        The general approach is to smooth `vector` by convolving it with
        `wavelet(width)` for each width in `widths`. Relative maxima which
        appear at enough length scales, and with sufficiently high SNR, are
        accepted.

        Parameters
        ----------
        vector : ndarray
            1-D array in which to find the peaks.
        widths : float or sequence
            Single width or 1-D array-like of widths to use for calculating
            the CWT matrix. In general,
            this range should cover the expected width of peaks of interest.
        wavelet : callable, optional
            Should take two parameters and return a 1-D array to convolve
            with `vector`. The first parameter determines the number of points
            of the returned wavelet array, the second parameter is the scale
            (`width`) of the wavelet. Should be normalized and symmetric.
            Default is the ricker wavelet.
        max_distances : ndarray, optional
            At each row, a ridge line is only connected if the relative max at
            row[n] is within ``max_distances[n]`` from the relative max at
            ``row[n+1]``.  Default value is ``widths/4``.
        gap_thresh : float, optional
            If a relative maximum is not found within `max_distances`,
            there will be a gap. A ridge line is discontinued if there are more
            than `gap_thresh` points without connecting a new relative maximum.
            Default is the first value of the widths array i.e. widths[0].
        min_length : int, optional
            Minimum length a ridge line needs to be acceptable.
            Default is ``cwt.shape[0] / 4``, ie 1/4-th the number of widths.
        min_snr : float, optional
            Minimum SNR ratio. Default 1. The signal is the maximum CWT coefficient
            on the largest ridge line. The noise is `noise_perc` th percentile of
            datapoints contained within the same ridge line.
        noise_perc : float, optional
            When calculating the noise floor, percentile of data points
            examined below which to consider noise. Calculated using
            `stats.scoreatpercentile`.  Default is 10.
        window_size : int, optional
            Size of window to use to calculate noise floor.
            Default is ``cwt.shape[1] / 20``.

        Returns
        -------
        peaks_indices : ndarray
            Indices of the locations in the `vector` where peaks were found.
            The list is sorted.

        See Also
        --------
        cwt
            Continuous wavelet transform.
        find_peaks
            Find peaks inside a signal based on peak properties.

        Notes
        -----
        This approach was designed for finding sharp peaks among noisy data,
        however with proper parameter selection it should function well for
        different peak shapes.

        The algorithm is as follows:
         1. Perform a continuous wavelet transform on `vector`, for the supplied
            `widths`. This is a convolution of `vector` with `wavelet(width)` for
            each width in `widths`. See `cwt`.
         2. Identify "ridge lines" in the cwt matrix. These are relative maxima
            at each row, connected across adjacent rows. See identify_ridge_lines
         3. Filter the ridge_lines using filter_ridge_lines.

        .. versionadded:: 0.11.0

        References
        ----------
        .. [1] Bioinformatics (2006) 22 (17): 2059-2065.
           :doi:`10.1093/bioinformatics/btl355`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> xs = np.arange(0, np.pi, 0.05)
        >>> data = np.sin(xs)
        >>> peakind = signal.find_peaks_cwt(data, np.arange(1,10))
        >>> peakind, xs[peakind], data[peakind]
        ([32], array([ 1.6]), array([ 0.9995736]))

    findfreqs(num, den, N, kind='ba')
        Find array of frequencies for computing the response of an analog filter.

        Parameters
        ----------
        num, den : array_like, 1-D
            The polynomial coefficients of the numerator and denominator of the
            transfer function of the filter or LTI system, where the coefficients
            are ordered from highest to lowest degree. Or, the roots  of the
            transfer function numerator and denominator (i.e., zeroes and poles).
        N : int
            The length of the array to be computed.
        kind : str {'ba', 'zp'}, optional
            Specifies whether the numerator and denominator are specified by their
            polynomial coefficients ('ba'), or their roots ('zp').

        Returns
        -------
        w : (N,) ndarray
            A 1-D array of frequencies, logarithmically spaced.

        Examples
        --------
        Find a set of nine frequencies that span the "interesting part" of the
        frequency response for the filter with the transfer function

            H(s) = s / (s^2 + 8s + 25)

        >>> from scipy import signal
        >>> signal.findfreqs([1, 0], [1, 8, 25], N=9)
        array([  1.00000000e-02,   3.16227766e-02,   1.00000000e-01,
                 3.16227766e-01,   1.00000000e+00,   3.16227766e+00,
                 1.00000000e+01,   3.16227766e+01,   1.00000000e+02])

    firls(numtaps, bands, desired, *, weight=None, fs=None)
        FIR filter design using least-squares error minimization.

        Calculate the filter coefficients for the linear-phase finite
        impulse response (FIR) filter which has the best approximation
        to the desired frequency response described by `bands` and
        `desired` in the least squares sense (i.e., the integral of the
        weighted mean-squared error within the specified bands is
        minimized).

        Parameters
        ----------
        numtaps : int
            The number of taps in the FIR filter. `numtaps` must be odd.
        bands : array_like
            A monotonic nondecreasing sequence containing the band edges in
            Hz. All elements must be non-negative and less than or equal to
            the Nyquist frequency given by `nyq`. The bands are specified as
            frequency pairs, thus, if using a 1D array, its length must be
            even, e.g., `np.array([0, 1, 2, 3, 4, 5])`. Alternatively, the
            bands can be specified as an nx2 sized 2D array, where n is the
            number of bands, e.g, `np.array([[0, 1], [2, 3], [4, 5]])`.
        desired : array_like
            A sequence the same size as `bands` containing the desired gain
            at the start and end point of each band.
        weight : array_like, optional
            A relative weighting to give to each band region when solving
            the least squares problem. `weight` has to be half the size of
            `bands`.
        fs : float, optional
            The sampling frequency of the signal. Each frequency in `bands`
            must be between 0 and ``fs/2`` (inclusive). Default is 2.

        Returns
        -------
        coeffs : ndarray
            Coefficients of the optimal (in a least squares sense) FIR filter.

        See Also
        --------
        firwin
        firwin2
        minimum_phase
        remez

        Notes
        -----
        This implementation follows the algorithm given in [1]_.
        As noted there, least squares design has multiple advantages:

            1. Optimal in a least-squares sense.
            2. Simple, non-iterative method.
            3. The general solution can obtained by solving a linear
               system of equations.
            4. Allows the use of a frequency dependent weighting function.

        This function constructs a Type I linear phase FIR filter, which
        contains an odd number of `coeffs` satisfying for :math:`n < numtaps`:

        .. math:: coeffs(n) = coeffs(numtaps - 1 - n)

        The odd number of coefficients and filter symmetry avoid boundary
        conditions that could otherwise occur at the Nyquist and 0 frequencies
        (e.g., for Type II, III, or IV variants).

        .. versionadded:: 0.18

        References
        ----------
        .. [1] Ivan Selesnick, Linear-Phase Fir Filter Design By Least Squares.
               OpenStax CNX. Aug 9, 2005.
               http://cnx.org/contents/eb1ecb35-03a9-4610-ba87-41cd771c95f2@7

        Examples
        --------
        We want to construct a band-pass filter. Note that the behavior in the
        frequency ranges between our stop bands and pass bands is unspecified,
        and thus may overshoot depending on the parameters of our filter:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> fig, axs = plt.subplots(2)
        >>> fs = 10.0  # Hz
        >>> desired = (0, 0, 1, 1, 0, 0)
        >>> for bi, bands in enumerate(((0, 1, 2, 3, 4, 5), (0, 1, 2, 4, 4.5, 5))):
        ...     fir_firls = signal.firls(73, bands, desired, fs=fs)
        ...     fir_remez = signal.remez(73, bands, desired[::2], fs=fs)
        ...     fir_firwin2 = signal.firwin2(73, bands, desired, fs=fs)
        ...     hs = list()
        ...     ax = axs[bi]
        ...     for fir in (fir_firls, fir_remez, fir_firwin2):
        ...         freq, response = signal.freqz(fir)
        ...         hs.append(ax.semilogy(0.5*fs*freq/np.pi, np.abs(response))[0])
        ...     for band, gains in zip(zip(bands[::2], bands[1::2]),
        ...                            zip(desired[::2], desired[1::2])):
        ...         ax.semilogy(band, np.maximum(gains, 1e-7), 'k--', linewidth=2)
        ...     if bi == 0:
        ...         ax.legend(hs, ('firls', 'remez', 'firwin2'),
        ...                   loc='lower center', frameon=False)
        ...     else:
        ...         ax.set_xlabel('Frequency (Hz)')
        ...     ax.grid(True)
        ...     ax.set(title='Band-pass %d-%d Hz' % bands[2:4], ylabel='Magnitude')
        ...
        >>> fig.tight_layout()
        >>> plt.show()

    firwin(numtaps, cutoff, *, width=None, window='hamming', pass_zero=True, scale=True, fs=None)
        FIR filter design using the window method.

        This function computes the coefficients of a finite impulse response
        filter. The filter will have linear phase; it will be Type I if
        `numtaps` is odd and Type II if `numtaps` is even.

        Type II filters always have zero response at the Nyquist frequency, so a
        ValueError exception is raised if firwin is called with `numtaps` even and
        having a passband whose right end is at the Nyquist frequency.

        Parameters
        ----------
        numtaps : int
            Length of the filter (number of coefficients, i.e. the filter
            order + 1).  `numtaps` must be odd if a passband includes the
            Nyquist frequency.
        cutoff : float or 1-D array_like
            Cutoff frequency of filter (expressed in the same units as `fs`)
            OR an array of cutoff frequencies (that is, band edges). In the
            latter case, the frequencies in `cutoff` should be positive and
            monotonically increasing between 0 and `fs/2`. The values 0 and
            `fs/2` must not be included in `cutoff`.
        width : float or None, optional
            If `width` is not None, then assume it is the approximate width
            of the transition region (expressed in the same units as `fs`)
            for use in Kaiser FIR filter design. In this case, the `window`
            argument is ignored.
        window : string or tuple of string and parameter values, optional
            Desired window to use. See `scipy.signal.get_window` for a list
            of windows and required parameters.
        pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
            If True, the gain at the frequency 0 (i.e., the "DC gain") is 1.
            If False, the DC gain is 0. Can also be a string argument for the
            desired filter type (equivalent to ``btype`` in IIR design functions).

            .. versionadded:: 1.3.0
               Support for string arguments.
        scale : bool, optional
            Set to True to scale the coefficients so that the frequency
            response is exactly unity at a certain frequency.
            That frequency is either:

            - 0 (DC) if the first passband starts at 0 (i.e. pass_zero
              is True)
            - `fs/2` (the Nyquist frequency) if the first passband ends at
              `fs/2` (i.e the filter is a single band highpass filter);
              center of first passband otherwise

        fs : float, optional
            The sampling frequency of the signal. Each frequency in `cutoff`
            must be between 0 and ``fs/2``.  Default is 2.

        Returns
        -------
        h : (numtaps,) ndarray
            Coefficients of length `numtaps` FIR filter.

        Raises
        ------
        ValueError
            If any value in `cutoff` is less than or equal to 0 or greater
            than or equal to ``fs/2``, if the values in `cutoff` are not strictly
            monotonically increasing, or if `numtaps` is even but a passband
            includes the Nyquist frequency.

        See Also
        --------
        firwin2
        firls
        minimum_phase
        remez

        Examples
        --------
        Low-pass from 0 to f:

        >>> from scipy import signal
        >>> numtaps = 3
        >>> f = 0.1
        >>> signal.firwin(numtaps, f)
        array([ 0.06799017,  0.86401967,  0.06799017])

        Use a specific window function:

        >>> signal.firwin(numtaps, f, window='nuttall')
        array([  3.56607041e-04,   9.99286786e-01,   3.56607041e-04])

        High-pass ('stop' from 0 to f):

        >>> signal.firwin(numtaps, f, pass_zero=False)
        array([-0.00859313,  0.98281375, -0.00859313])

        Band-pass:

        >>> f1, f2 = 0.1, 0.2
        >>> signal.firwin(numtaps, [f1, f2], pass_zero=False)
        array([ 0.06301614,  0.88770441,  0.06301614])

        Band-stop:

        >>> signal.firwin(numtaps, [f1, f2])
        array([-0.00801395,  1.0160279 , -0.00801395])

        Multi-band (passbands are [0, f1], [f2, f3] and [f4, 1]):

        >>> f3, f4 = 0.3, 0.4
        >>> signal.firwin(numtaps, [f1, f2, f3, f4])
        array([-0.01376344,  1.02752689, -0.01376344])

        Multi-band (passbands are [f1, f2] and [f3,f4]):

        >>> signal.firwin(numtaps, [f1, f2, f3, f4], pass_zero=False)
        array([ 0.04890915,  0.91284326,  0.04890915])

    firwin2(numtaps, freq, gain, *, nfreqs=None, window='hamming', antisymmetric=False, fs=None)
        FIR filter design using the window method.

        From the given frequencies `freq` and corresponding gains `gain`,
        this function constructs an FIR filter with linear phase and
        (approximately) the given frequency response.

        Parameters
        ----------
        numtaps : int
            The number of taps in the FIR filter.  `numtaps` must be less than
            `nfreqs`.
        freq : array_like, 1-D
            The frequency sampling points. Typically 0.0 to 1.0 with 1.0 being
            Nyquist.  The Nyquist frequency is half `fs`.
            The values in `freq` must be nondecreasing. A value can be repeated
            once to implement a discontinuity. The first value in `freq` must
            be 0, and the last value must be ``fs/2``. Values 0 and ``fs/2`` must
            not be repeated.
        gain : array_like
            The filter gains at the frequency sampling points. Certain
            constraints to gain values, depending on the filter type, are applied,
            see Notes for details.
        nfreqs : int, optional
            The size of the interpolation mesh used to construct the filter.
            For most efficient behavior, this should be a power of 2 plus 1
            (e.g, 129, 257, etc). The default is one more than the smallest
            power of 2 that is not less than `numtaps`. `nfreqs` must be greater
            than `numtaps`.
        window : string or (string, float) or float, or None, optional
            Window function to use. Default is "hamming". See
            `scipy.signal.get_window` for the complete list of possible values.
            If None, no window function is applied.
        antisymmetric : bool, optional
            Whether resulting impulse response is symmetric/antisymmetric.
            See Notes for more details.
        fs : float, optional
            The sampling frequency of the signal. Each frequency in `cutoff`
            must be between 0 and ``fs/2``. Default is 2.

        Returns
        -------
        taps : ndarray
            The filter coefficients of the FIR filter, as a 1-D array of length
            `numtaps`.

        See Also
        --------
        firls
        firwin
        minimum_phase
        remez

        Notes
        -----
        From the given set of frequencies and gains, the desired response is
        constructed in the frequency domain. The inverse FFT is applied to the
        desired response to create the associated convolution kernel, and the
        first `numtaps` coefficients of this kernel, scaled by `window`, are
        returned.

        The FIR filter will have linear phase. The type of filter is determined by
        the value of 'numtaps` and `antisymmetric` flag.
        There are four possible combinations:

           - odd  `numtaps`, `antisymmetric` is False, type I filter is produced
           - even `numtaps`, `antisymmetric` is False, type II filter is produced
           - odd  `numtaps`, `antisymmetric` is True, type III filter is produced
           - even `numtaps`, `antisymmetric` is True, type IV filter is produced

        Magnitude response of all but type I filters are subjects to following
        constraints:

           - type II  -- zero at the Nyquist frequency
           - type III -- zero at zero and Nyquist frequencies
           - type IV  -- zero at zero frequency

        .. versionadded:: 0.9.0

        References
        ----------
        .. [1] Oppenheim, A. V. and Schafer, R. W., "Discrete-Time Signal
           Processing", Prentice-Hall, Englewood Cliffs, New Jersey (1989).
           (See, for example, Section 7.4.)

        .. [2] Smith, Steven W., "The Scientist and Engineer's Guide to Digital
           Signal Processing", Ch. 17. http://www.dspguide.com/ch17/1.htm

        Examples
        --------
        A lowpass FIR filter with a response that is 1 on [0.0, 0.5], and
        that decreases linearly on [0.5, 1.0] from 1 to 0:

        >>> from scipy import signal
        >>> taps = signal.firwin2(150, [0.0, 0.5, 1.0], [1.0, 1.0, 0.0])
        >>> print(taps[72:78])
        [-0.02286961 -0.06362756  0.57310236  0.57310236 -0.06362756 -0.02286961]

    freqresp(system, w=None, n=10000)
        Calculate the frequency response of a continuous-time system.

        Parameters
        ----------
        system : an instance of the `lti` class or a tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `lti`)
                * 2 (num, den)
                * 3 (zeros, poles, gain)
                * 4 (A, B, C, D)

        w : array_like, optional
            Array of frequencies (in rad/s). Magnitude and phase data is
            calculated for every value in this array. If not given, a reasonable
            set will be calculated.
        n : int, optional
            Number of frequency points to compute if `w` is not given. The `n`
            frequencies are logarithmically spaced in an interval chosen to
            include the influence of the poles and zeros of the system.

        Returns
        -------
        w : 1D ndarray
            Frequency array [rad/s]
        H : 1D ndarray
            Array of complex magnitude values

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``).

        Examples
        --------
        Generating the Nyquist plot of a transfer function

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        Construct the transfer function :math:`H(s) = \frac{5}{(s-1)^3}`:

        >>> s1 = signal.ZerosPolesGain([], [1, 1, 1], [5])

        >>> w, H = signal.freqresp(s1)

        >>> plt.figure()
        >>> plt.plot(H.real, H.imag, "b")
        >>> plt.plot(H.real, -H.imag, "r")
        >>> plt.show()

    freqs(b, a, worN=200, plot=None)
        Compute frequency response of analog filter.

        Given the M-order numerator `b` and N-order denominator `a` of an analog
        filter, compute its frequency response::

                 b[0]*(jw)**M + b[1]*(jw)**(M-1) + ... + b[M]
         H(w) = ----------------------------------------------
                 a[0]*(jw)**N + a[1]*(jw)**(N-1) + ... + a[N]

        Parameters
        ----------
        b : array_like
            Numerator of a linear filter.
        a : array_like
            Denominator of a linear filter.
        worN : {None, int, array_like}, optional
            If None, then compute at 200 frequencies around the interesting parts
            of the response curve (determined by pole-zero locations). If a single
            integer, then compute at that many frequencies. Otherwise, compute the
            response at the angular frequencies (e.g., rad/s) given in `worN`.
        plot : callable, optional
            A callable that takes two arguments. If given, the return parameters
            `w` and `h` are passed to plot. Useful for plotting the frequency
            response inside `freqs`.

        Returns
        -------
        w : ndarray
            The angular frequencies at which `h` was computed.
        h : ndarray
            The frequency response.

        See Also
        --------
        freqz : Compute the frequency response of a digital filter.

        Notes
        -----
        Using Matplotlib's "plot" function as the callable for `plot` produces
        unexpected results, this plots the real part of the complex transfer
        function, not the magnitude. Try ``lambda w, h: plot(w, abs(h))``.

        Examples
        --------
        >>> from scipy.signal import freqs, iirfilter
        >>> import numpy as np

        >>> b, a = iirfilter(4, [1, 10], 1, 60, analog=True, ftype='cheby1')

        >>> w, h = freqs(b, a, worN=np.logspace(-1, 2, 1000))

        >>> import matplotlib.pyplot as plt
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.xlabel('Frequency')
        >>> plt.ylabel('Amplitude response [dB]')
        >>> plt.grid(True)
        >>> plt.show()

    freqs_zpk(z, p, k, worN=200)
        Compute frequency response of analog filter.

        Given the zeros `z`, poles `p`, and gain `k` of a filter, compute its
        frequency response::

                    (jw-z[0]) * (jw-z[1]) * ... * (jw-z[-1])
         H(w) = k * ----------------------------------------
                    (jw-p[0]) * (jw-p[1]) * ... * (jw-p[-1])

        Parameters
        ----------
        z : array_like
            Zeroes of a linear filter
        p : array_like
            Poles of a linear filter
        k : scalar
            Gain of a linear filter
        worN : {None, int, array_like}, optional
            If None, then compute at 200 frequencies around the interesting parts
            of the response curve (determined by pole-zero locations). If a single
            integer, then compute at that many frequencies. Otherwise, compute the
            response at the angular frequencies (e.g., rad/s) given in `worN`.

        Returns
        -------
        w : ndarray
            The angular frequencies at which `h` was computed.
        h : ndarray
            The frequency response.

        See Also
        --------
        freqs : Compute the frequency response of an analog filter in TF form
        freqz : Compute the frequency response of a digital filter in TF form
        freqz_zpk : Compute the frequency response of a digital filter in ZPK form

        Notes
        -----
        .. versionadded:: 0.19.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import freqs_zpk, iirfilter

        >>> z, p, k = iirfilter(4, [1, 10], 1, 60, analog=True, ftype='cheby1',
        ...                     output='zpk')

        >>> w, h = freqs_zpk(z, p, k, worN=np.logspace(-1, 2, 1000))

        >>> import matplotlib.pyplot as plt
        >>> plt.semilogx(w, 20 * np.log10(abs(h)))
        >>> plt.xlabel('Frequency')
        >>> plt.ylabel('Amplitude response [dB]')
        >>> plt.grid(True)
        >>> plt.show()

    freqz(b, a=1, worN=512, whole=False, plot=None, fs=6.283185307179586, include_nyquist=False)
        Compute the frequency response of a digital filter.

        Given the M-order numerator `b` and N-order denominator `a` of a digital
        filter, compute its frequency response::

                     jw                 -jw              -jwM
            jw    B(e  )    b[0] + b[1]e    + ... + b[M]e
         H(e  ) = ------ = -----------------------------------
                     jw                 -jw              -jwN
                  A(e  )    a[0] + a[1]e    + ... + a[N]e

        Parameters
        ----------
        b : array_like
            Numerator of a linear filter. If `b` has dimension greater than 1,
            it is assumed that the coefficients are stored in the first dimension,
            and ``b.shape[1:]``, ``a.shape[1:]``, and the shape of the frequencies
            array must be compatible for broadcasting.
        a : array_like
            Denominator of a linear filter. If `b` has dimension greater than 1,
            it is assumed that the coefficients are stored in the first dimension,
            and ``b.shape[1:]``, ``a.shape[1:]``, and the shape of the frequencies
            array must be compatible for broadcasting.
        worN : {None, int, array_like}, optional
            If a single integer, then compute at that many frequencies (default is
            N=512). This is a convenient alternative to::

                np.linspace(0, fs if whole else fs/2, N, endpoint=include_nyquist)

            Using a number that is fast for FFT computations can result in
            faster computations (see Notes).

            If an array_like, compute the response at the frequencies given.
            These are in the same units as `fs`.
        whole : bool, optional
            Normally, frequencies are computed from 0 to the Nyquist frequency,
            fs/2 (upper-half of unit-circle). If `whole` is True, compute
            frequencies from 0 to fs. Ignored if worN is array_like.
        plot : callable
            A callable that takes two arguments. If given, the return parameters
            `w` and `h` are passed to plot. Useful for plotting the frequency
            response inside `freqz`.
        fs : float, optional
            The sampling frequency of the digital system. Defaults to 2*pi
            radians/sample (so w is from 0 to pi).

            .. versionadded:: 1.2.0
        include_nyquist : bool, optional
            If `whole` is False and `worN` is an integer, setting `include_nyquist`
            to True will include the last frequency (Nyquist frequency) and is
            otherwise ignored.

            .. versionadded:: 1.5.0

        Returns
        -------
        w : ndarray
            The frequencies at which `h` was computed, in the same units as `fs`.
            By default, `w` is normalized to the range [0, pi) (radians/sample).
        h : ndarray
            The frequency response, as complex numbers.

        See Also
        --------
        freqz_zpk
        sosfreqz

        Notes
        -----
        Using Matplotlib's :func:`matplotlib.pyplot.plot` function as the callable
        for `plot` produces unexpected results, as this plots the real part of the
        complex transfer function, not the magnitude.
        Try ``lambda w, h: plot(w, np.abs(h))``.

        A direct computation via (R)FFT is used to compute the frequency response
        when the following conditions are met:

        1. An integer value is given for `worN`.
        2. `worN` is fast to compute via FFT (i.e.,
           `next_fast_len(worN) <scipy.fft.next_fast_len>` equals `worN`).
        3. The denominator coefficients are a single value (``a.shape[0] == 1``).
        4. `worN` is at least as long as the numerator coefficients
           (``worN >= b.shape[0]``).
        5. If ``b.ndim > 1``, then ``b.shape[-1] == 1``.

        For long FIR filters, the FFT approach can have lower error and be much
        faster than the equivalent direct polynomial calculation.

        Examples
        --------
        >>> from scipy import signal
        >>> import numpy as np
        >>> b = signal.firwin(80, 0.5, window=('kaiser', 8))
        >>> w, h = signal.freqz(b)

        >>> import matplotlib.pyplot as plt
        >>> fig, ax1 = plt.subplots()
        >>> ax1.set_title('Digital filter frequency response')

        >>> ax1.plot(w, 20 * np.log10(abs(h)), 'b')
        >>> ax1.set_ylabel('Amplitude [dB]', color='b')
        >>> ax1.set_xlabel('Frequency [rad/sample]')

        >>> ax2 = ax1.twinx()
        >>> angles = np.unwrap(np.angle(h))
        >>> ax2.plot(w, angles, 'g')
        >>> ax2.set_ylabel('Angle (radians)', color='g')
        >>> ax2.grid(True)
        >>> ax2.axis('tight')
        >>> plt.show()

        Broadcasting Examples

        Suppose we have two FIR filters whose coefficients are stored in the
        rows of an array with shape (2, 25). For this demonstration, we'll
        use random data:

        >>> rng = np.random.default_rng()
        >>> b = rng.random((2, 25))

        To compute the frequency response for these two filters with one call
        to `freqz`, we must pass in ``b.T``, because `freqz` expects the first
        axis to hold the coefficients. We must then extend the shape with a
        trivial dimension of length 1 to allow broadcasting with the array
        of frequencies.  That is, we pass in ``b.T[..., np.newaxis]``, which has
        shape (25, 2, 1):

        >>> w, h = signal.freqz(b.T[..., np.newaxis], worN=1024)
        >>> w.shape
        (1024,)
        >>> h.shape
        (2, 1024)

        Now, suppose we have two transfer functions, with the same numerator
        coefficients ``b = [0.5, 0.5]``. The coefficients for the two denominators
        are stored in the first dimension of the 2-D array  `a`::

            a = [   1      1  ]
                [ -0.25, -0.5 ]

        >>> b = np.array([0.5, 0.5])
        >>> a = np.array([[1, 1], [-0.25, -0.5]])

        Only `a` is more than 1-D. To make it compatible for
        broadcasting with the frequencies, we extend it with a trivial dimension
        in the call to `freqz`:

        >>> w, h = signal.freqz(b, a[..., np.newaxis], worN=1024)
        >>> w.shape
        (1024,)
        >>> h.shape
        (2, 1024)

    freqz_zpk(z, p, k, worN=512, whole=False, fs=6.283185307179586)
        Compute the frequency response of a digital filter in ZPK form.

        Given the Zeros, Poles and Gain of a digital filter, compute its frequency
        response:

        :math:`H(z)=k \prod_i (z - Z[i]) / \prod_j (z - P[j])`

        where :math:`k` is the `gain`, :math:`Z` are the `zeros` and :math:`P` are
        the `poles`.

        Parameters
        ----------
        z : array_like
            Zeroes of a linear filter
        p : array_like
            Poles of a linear filter
        k : scalar
            Gain of a linear filter
        worN : {None, int, array_like}, optional
            If a single integer, then compute at that many frequencies (default is
            N=512).

            If an array_like, compute the response at the frequencies given.
            These are in the same units as `fs`.
        whole : bool, optional
            Normally, frequencies are computed from 0 to the Nyquist frequency,
            fs/2 (upper-half of unit-circle). If `whole` is True, compute
            frequencies from 0 to fs. Ignored if w is array_like.
        fs : float, optional
            The sampling frequency of the digital system. Defaults to 2*pi
            radians/sample (so w is from 0 to pi).

            .. versionadded:: 1.2.0

        Returns
        -------
        w : ndarray
            The frequencies at which `h` was computed, in the same units as `fs`.
            By default, `w` is normalized to the range [0, pi) (radians/sample).
        h : ndarray
            The frequency response, as complex numbers.

        See Also
        --------
        freqs : Compute the frequency response of an analog filter in TF form
        freqs_zpk : Compute the frequency response of an analog filter in ZPK form
        freqz : Compute the frequency response of a digital filter in TF form

        Notes
        -----
        .. versionadded:: 0.19.0

        Examples
        --------
        Design a 4th-order digital Butterworth filter with cut-off of 100 Hz in a
        system with sample rate of 1000 Hz, and plot the frequency response:

        >>> import numpy as np
        >>> from scipy import signal
        >>> z, p, k = signal.butter(4, 100, output='zpk', fs=1000)
        >>> w, h = signal.freqz_zpk(z, p, k, fs=1000)

        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> ax1 = fig.add_subplot(1, 1, 1)
        >>> ax1.set_title('Digital filter frequency response')

        >>> ax1.plot(w, 20 * np.log10(abs(h)), 'b')
        >>> ax1.set_ylabel('Amplitude [dB]', color='b')
        >>> ax1.set_xlabel('Frequency [Hz]')
        >>> ax1.grid(True)

        >>> ax2 = ax1.twinx()
        >>> angles = np.unwrap(np.angle(h))
        >>> ax2.plot(w, angles, 'g')
        >>> ax2.set_ylabel('Angle [radians]', color='g')

        >>> plt.axis('tight')
        >>> plt.show()

    gammatone(freq, ftype, order=None, numtaps=None, fs=None)
        Gammatone filter design.

        This function computes the coefficients of an FIR or IIR gammatone
        digital filter [1]_.

        Parameters
        ----------
        freq : float
            Center frequency of the filter (expressed in the same units
            as `fs`).
        ftype : {'fir', 'iir'}
            The type of filter the function generates. If 'fir', the function
            will generate an Nth order FIR gammatone filter. If 'iir', the
            function will generate an 8th order digital IIR filter, modeled as
            as 4th order gammatone filter.
        order : int, optional
            The order of the filter. Only used when ``ftype='fir'``.
            Default is 4 to model the human auditory system. Must be between
            0 and 24.
        numtaps : int, optional
            Length of the filter. Only used when ``ftype='fir'``.
            Default is ``fs*0.015`` if `fs` is greater than 1000,
            15 if `fs` is less than or equal to 1000.
        fs : float, optional
            The sampling frequency of the signal. `freq` must be between
            0 and ``fs/2``. Default is 2.

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (``b``) and denominator (``a``) polynomials of the filter.

        Raises
        ------
        ValueError
            If `freq` is less than or equal to 0 or greater than or equal to
            ``fs/2``, if `ftype` is not 'fir' or 'iir', if `order` is less than
            or equal to 0 or greater than 24 when ``ftype='fir'``

        See Also
        --------
        firwin
        iirfilter

        References
        ----------
        .. [1] Slaney, Malcolm, "An Efficient Implementation of the
            Patterson-Holdsworth Auditory Filter Bank", Apple Computer
            Technical Report 35, 1993, pp.3-8, 34-39.

        Examples
        --------
        16-sample 4th order FIR Gammatone filter centered at 440 Hz

        >>> from scipy import signal
        >>> signal.gammatone(440, 'fir', numtaps=16, fs=16000)
        (array([ 0.00000000e+00,  2.22196719e-07,  1.64942101e-06,  4.99298227e-06,
            1.01993969e-05,  1.63125770e-05,  2.14648940e-05,  2.29947263e-05,
            1.76776931e-05,  2.04980537e-06, -2.72062858e-05, -7.28455299e-05,
           -1.36651076e-04, -2.19066855e-04, -3.18905076e-04, -4.33156712e-04]),
           [1.0])

        IIR Gammatone filter centered at 440 Hz

        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> b, a = signal.gammatone(440, 'iir', fs=16000)
        >>> w, h = signal.freqz(b, a)
        >>> plt.plot(w / ((2 * np.pi) / 16000), 20 * np.log10(abs(h)))
        >>> plt.xscale('log')
        >>> plt.title('Gammatone filter frequency response')
        >>> plt.xlabel('Frequency')
        >>> plt.ylabel('Amplitude [dB]')
        >>> plt.margins(0, 0.1)
        >>> plt.grid(which='both', axis='both')
        >>> plt.axvline(440, color='green') # cutoff frequency
        >>> plt.show()

    gauss_spline(x, n)
        Gaussian approximation to B-spline basis function of order n.

        Parameters
        ----------
        x : array_like
            a knot vector
        n : int
            The order of the spline. Must be non-negative, i.e., n >= 0

        Returns
        -------
        res : ndarray
            B-spline basis function values approximated by a zero-mean Gaussian
            function.

        Notes
        -----
        The B-spline basis function can be approximated well by a zero-mean
        Gaussian function with standard-deviation equal to :math:`\sigma=(n+1)/12`
        for large `n` :

        .. math::  \frac{1}{\sqrt {2\pi\sigma^2}}exp(-\frac{x^2}{2\sigma})

        References
        ----------
        .. [1] Bouma H., Vilanova A., Bescos J.O., ter Haar Romeny B.M., Gerritsen
           F.A. (2007) Fast and Accurate Gaussian Derivatives Based on B-Splines. In:
           Sgallari F., Murli A., Paragios N. (eds) Scale Space and Variational
           Methods in Computer Vision. SSVM 2007. Lecture Notes in Computer
           Science, vol 4485. Springer, Berlin, Heidelberg
        .. [2] http://folk.uio.no/inf3330/scripting/doc/python/SciPy/tutorial/old/node24.html

        Examples
        --------
        We can calculate B-Spline basis functions approximated by a gaussian
        distribution:

        >>> import numpy as np
        >>> from scipy.signal import gauss_spline
        >>> knots = np.array([-1.0, 0.0, -1.0])
        >>> gauss_spline(knots, 3)
        array([0.15418033, 0.6909883, 0.15418033])  # may vary

    gausspulse(t, fc=1000, bw=0.5, bwr=-6, tpr=-60, retquad=False, retenv=False)
        Return a Gaussian modulated sinusoid:

            ``exp(-a t^2) exp(1j*2*pi*fc*t).``

        If `retquad` is True, then return the real and imaginary parts
        (in-phase and quadrature).
        If `retenv` is True, then return the envelope (unmodulated signal).
        Otherwise, return the real part of the modulated sinusoid.

        Parameters
        ----------
        t : ndarray or the string 'cutoff'
            Input array.
        fc : float, optional
            Center frequency (e.g. Hz).  Default is 1000.
        bw : float, optional
            Fractional bandwidth in frequency domain of pulse (e.g. Hz).
            Default is 0.5.
        bwr : float, optional
            Reference level at which fractional bandwidth is calculated (dB).
            Default is -6.
        tpr : float, optional
            If `t` is 'cutoff', then the function returns the cutoff
            time for when the pulse amplitude falls below `tpr` (in dB).
            Default is -60.
        retquad : bool, optional
            If True, return the quadrature (imaginary) as well as the real part
            of the signal.  Default is False.
        retenv : bool, optional
            If True, return the envelope of the signal.  Default is False.

        Returns
        -------
        yI : ndarray
            Real part of signal.  Always returned.
        yQ : ndarray
            Imaginary part of signal.  Only returned if `retquad` is True.
        yenv : ndarray
            Envelope of signal.  Only returned if `retenv` is True.

        See Also
        --------
        scipy.signal.morlet

        Examples
        --------
        Plot real component, imaginary component, and envelope for a 5 Hz pulse,
        sampled at 100 Hz for 2 seconds:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> t = np.linspace(-1, 1, 2 * 100, endpoint=False)
        >>> i, q, e = signal.gausspulse(t, fc=5, retquad=True, retenv=True)
        >>> plt.plot(t, i, t, q, t, e, '--')

    get_window(window, Nx, fftbins=True)
        Return a window of a given length and type.

        Parameters
        ----------
        window : string, float, or tuple
            The type of window to create. See below for more details.
        Nx : int
            The number of samples in the window.
        fftbins : bool, optional
            If True (default), create a "periodic" window, ready to use with
            `ifftshift` and be multiplied by the result of an FFT (see also
            :func:`~scipy.fft.fftfreq`).
            If False, create a "symmetric" window, for use in filter design.

        Returns
        -------
        get_window : ndarray
            Returns a window of length `Nx` and type `window`

        Notes
        -----
        Window types:

        - `~scipy.signal.windows.boxcar`
        - `~scipy.signal.windows.triang`
        - `~scipy.signal.windows.blackman`
        - `~scipy.signal.windows.hamming`
        - `~scipy.signal.windows.hann`
        - `~scipy.signal.windows.bartlett`
        - `~scipy.signal.windows.flattop`
        - `~scipy.signal.windows.parzen`
        - `~scipy.signal.windows.bohman`
        - `~scipy.signal.windows.blackmanharris`
        - `~scipy.signal.windows.nuttall`
        - `~scipy.signal.windows.barthann`
        - `~scipy.signal.windows.cosine`
        - `~scipy.signal.windows.exponential`
        - `~scipy.signal.windows.tukey`
        - `~scipy.signal.windows.taylor`
        - `~scipy.signal.windows.lanczos`
        - `~scipy.signal.windows.kaiser` (needs beta)
        - `~scipy.signal.windows.kaiser_bessel_derived` (needs beta)
        - `~scipy.signal.windows.gaussian` (needs standard deviation)
        - `~scipy.signal.windows.general_cosine` (needs weighting coefficients)
        - `~scipy.signal.windows.general_gaussian` (needs power, width)
        - `~scipy.signal.windows.general_hamming` (needs window coefficient)
        - `~scipy.signal.windows.dpss` (needs normalized half-bandwidth)
        - `~scipy.signal.windows.chebwin` (needs attenuation)


        If the window requires no parameters, then `window` can be a string.

        If the window requires parameters, then `window` must be a tuple
        with the first argument the string name of the window, and the next
        arguments the needed parameters.

        If `window` is a floating point number, it is interpreted as the beta
        parameter of the `~scipy.signal.windows.kaiser` window.

        Each of the window types listed above is also the name of
        a function that can be called directly to create a window of
        that type.

        Examples
        --------
        >>> from scipy import signal
        >>> signal.get_window('triang', 7)
        array([ 0.125,  0.375,  0.625,  0.875,  0.875,  0.625,  0.375])
        >>> signal.get_window(('kaiser', 4.0), 9)
        array([ 0.08848053,  0.29425961,  0.56437221,  0.82160913,  0.97885093,
                0.97885093,  0.82160913,  0.56437221,  0.29425961])
        >>> signal.get_window(('exponential', None, 1.), 9)
        array([ 0.011109  ,  0.03019738,  0.082085  ,  0.22313016,  0.60653066,
                0.60653066,  0.22313016,  0.082085  ,  0.03019738])
        >>> signal.get_window(4.0, 9)
        array([ 0.08848053,  0.29425961,  0.56437221,  0.82160913,  0.97885093,
                0.97885093,  0.82160913,  0.56437221,  0.29425961])

    group_delay(system, w=512, whole=False, fs=6.283185307179586)
        Compute the group delay of a digital filter.

        The group delay measures by how many samples amplitude envelopes of
        various spectral components of a signal are delayed by a filter.
        It is formally defined as the derivative of continuous (unwrapped) phase::

                   d        jw
         D(w) = - -- arg H(e)
                  dw

        Parameters
        ----------
        system : tuple of array_like (b, a)
            Numerator and denominator coefficients of a filter transfer function.
        w : {None, int, array_like}, optional
            If a single integer, then compute at that many frequencies (default is
            N=512).

            If an array_like, compute the delay at the frequencies given. These
            are in the same units as `fs`.
        whole : bool, optional
            Normally, frequencies are computed from 0 to the Nyquist frequency,
            fs/2 (upper-half of unit-circle). If `whole` is True, compute
            frequencies from 0 to fs. Ignored if w is array_like.
        fs : float, optional
            The sampling frequency of the digital system. Defaults to 2*pi
            radians/sample (so w is from 0 to pi).

            .. versionadded:: 1.2.0

        Returns
        -------
        w : ndarray
            The frequencies at which group delay was computed, in the same units
            as `fs`.  By default, `w` is normalized to the range [0, pi)
            (radians/sample).
        gd : ndarray
            The group delay.

        See Also
        --------
        freqz : Frequency response of a digital filter

        Notes
        -----
        The similar function in MATLAB is called `grpdelay`.

        If the transfer function :math:`H(z)` has zeros or poles on the unit
        circle, the group delay at corresponding frequencies is undefined.
        When such a case arises the warning is raised and the group delay
        is set to 0 at those frequencies.

        For the details of numerical computation of the group delay refer to [1]_ or [2]_.

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] Richard G. Lyons, "Understanding Digital Signal Processing,
               3rd edition", p. 830.
        .. [2] Julius O. Smith III, "Numerical Computation of Group Delay",
               in "Introduction to Digital Filters with Audio Applications",
               online book, 2007,
               https://ccrma.stanford.edu/~jos/fp/Numerical_Computation_Group_Delay.html

        Examples
        --------
        >>> from scipy import signal
        >>> b, a = signal.iirdesign(0.1, 0.3, 5, 50, ftype='cheby1')
        >>> w, gd = signal.group_delay((b, a))

        >>> import matplotlib.pyplot as plt
        >>> plt.title('Digital filter group delay')
        >>> plt.plot(w, gd)
        >>> plt.ylabel('Group delay [samples]')
        >>> plt.xlabel('Frequency [rad/sample]')
        >>> plt.show()

    hilbert(x, N=None, axis=-1)
        Compute the analytic signal, using the Hilbert transform.

        The transformation is done along the last axis by default.

        Parameters
        ----------
        x : array_like
            Signal data.  Must be real.
        N : int, optional
            Number of Fourier components.  Default: ``x.shape[axis]``
        axis : int, optional
            Axis along which to do the transformation.  Default: -1.

        Returns
        -------
        xa : ndarray
            Analytic signal of `x`, of each 1-D array along `axis`

        Notes
        -----
        The analytic signal ``x_a(t)`` of signal ``x(t)`` is:

        .. math:: x_a = F^{-1}(F(x) 2U) = x + i y

        where `F` is the Fourier transform, `U` the unit step function,
        and `y` the Hilbert transform of `x`. [1]_

        In other words, the negative half of the frequency spectrum is zeroed
        out, turning the real-valued signal into a complex signal.  The Hilbert
        transformed signal can be obtained from ``np.imag(hilbert(x))``, and the
        original signal from ``np.real(hilbert(x))``.

        References
        ----------
        .. [1] Wikipedia, "Analytic signal".
               https://en.wikipedia.org/wiki/Analytic_signal
        .. [2] Leon Cohen, "Time-Frequency Analysis", 1995. Chapter 2.
        .. [3] Alan V. Oppenheim, Ronald W. Schafer. Discrete-Time Signal
               Processing, Third Edition, 2009. Chapter 12.
               ISBN 13: 978-1292-02572-8

        Examples
        --------
        In this example we use the Hilbert transform to determine the amplitude
        envelope and instantaneous frequency of an amplitude-modulated signal.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import hilbert, chirp

        >>> duration = 1.0
        >>> fs = 400.0
        >>> samples = int(fs*duration)
        >>> t = np.arange(samples) / fs

        We create a chirp of which the frequency increases from 20 Hz to 100 Hz and
        apply an amplitude modulation.

        >>> signal = chirp(t, 20.0, t[-1], 100.0)
        >>> signal *= (1.0 + 0.5 * np.sin(2.0*np.pi*3.0*t) )

        The amplitude envelope is given by magnitude of the analytic signal. The
        instantaneous frequency can be obtained by differentiating the
        instantaneous phase in respect to time. The instantaneous phase corresponds
        to the phase angle of the analytic signal.

        >>> analytic_signal = hilbert(signal)
        >>> amplitude_envelope = np.abs(analytic_signal)
        >>> instantaneous_phase = np.unwrap(np.angle(analytic_signal))
        >>> instantaneous_frequency = (np.diff(instantaneous_phase) /
        ...                            (2.0*np.pi) * fs)

        >>> fig, (ax0, ax1) = plt.subplots(nrows=2)
        >>> ax0.plot(t, signal, label='signal')
        >>> ax0.plot(t, amplitude_envelope, label='envelope')
        >>> ax0.set_xlabel("time in seconds")
        >>> ax0.legend()
        >>> ax1.plot(t[1:], instantaneous_frequency)
        >>> ax1.set_xlabel("time in seconds")
        >>> ax1.set_ylim(0.0, 120.0)
        >>> fig.tight_layout()

    hilbert2(x, N=None)
        Compute the '2-D' analytic signal of `x`

        Parameters
        ----------
        x : array_like
            2-D signal data.
        N : int or tuple of two ints, optional
            Number of Fourier components. Default is ``x.shape``

        Returns
        -------
        xa : ndarray
            Analytic signal of `x` taken along axes (0,1).

        References
        ----------
        .. [1] Wikipedia, "Analytic signal",
            https://en.wikipedia.org/wiki/Analytic_signal

    iircomb(w0, Q, ftype='notch', fs=2.0, *, pass_zero=False)
        Design IIR notching or peaking digital comb filter.

        A notching comb filter consists of regularly-spaced band-stop filters with
        a narrow bandwidth (high quality factor). Each rejects a narrow frequency
        band and leaves the rest of the spectrum little changed.

        A peaking comb filter consists of regularly-spaced band-pass filters with
        a narrow bandwidth (high quality factor). Each rejects components outside
        a narrow frequency band.

        Parameters
        ----------
        w0 : float
            The fundamental frequency of the comb filter (the spacing between its
            peaks). This must evenly divide the sampling frequency. If `fs` is
            specified, this is in the same units as `fs`. By default, it is
            a normalized scalar that must satisfy  ``0 < w0 < 1``, with
            ``w0 = 1`` corresponding to half of the sampling frequency.
        Q : float
            Quality factor. Dimensionless parameter that characterizes
            notch filter -3 dB bandwidth ``bw`` relative to its center
            frequency, ``Q = w0/bw``.
        ftype : {'notch', 'peak'}
            The type of comb filter generated by the function. If 'notch', then
            the Q factor applies to the notches. If 'peak', then the Q factor
            applies to the peaks.  Default is 'notch'.
        fs : float, optional
            The sampling frequency of the signal. Default is 2.0.
        pass_zero : bool, optional
            If False (default), the notches (nulls) of the filter are centered on
            frequencies [0, w0, 2*w0, ...], and the peaks are centered on the
            midpoints [w0/2, 3*w0/2, 5*w0/2, ...].  If True, the peaks are centered
            on [0, w0, 2*w0, ...] (passing zero frequency) and vice versa.

            .. versionadded:: 1.9.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (``b``) and denominator (``a``) polynomials
            of the IIR filter.

        Raises
        ------
        ValueError
            If `w0` is less than or equal to 0 or greater than or equal to
            ``fs/2``, if `fs` is not divisible by `w0`, if `ftype`
            is not 'notch' or 'peak'

        See Also
        --------
        iirnotch
        iirpeak

        Notes
        -----
        For implementation details, see [1]_. The TF implementation of the
        comb filter is numerically stable even at higher orders due to the
        use of a single repeated pole, which won't suffer from precision loss.

        References
        ----------
        .. [1] Sophocles J. Orfanidis, "Introduction To Signal Processing",
               Prentice-Hall, 1996, ch. 11, "Digital Filter Design"

        Examples
        --------
        Design and plot notching comb filter at 20 Hz for a
        signal sampled at 200 Hz, using quality factor Q = 30

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> fs = 200.0  # Sample frequency (Hz)
        >>> f0 = 20.0  # Frequency to be removed from signal (Hz)
        >>> Q = 30.0  # Quality factor
        >>> # Design notching comb filter
        >>> b, a = signal.iircomb(f0, Q, ftype='notch', fs=fs)

        >>> # Frequency response
        >>> freq, h = signal.freqz(b, a, fs=fs)
        >>> response = abs(h)
        >>> # To avoid divide by zero when graphing
        >>> response[response == 0] = 1e-20
        >>> # Plot
        >>> fig, ax = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
        >>> ax[0].plot(freq, 20*np.log10(abs(response)), color='blue')
        >>> ax[0].set_title("Frequency Response")
        >>> ax[0].set_ylabel("Amplitude (dB)", color='blue')
        >>> ax[0].set_xlim([0, 100])
        >>> ax[0].set_ylim([-30, 10])
        >>> ax[0].grid(True)
        >>> ax[1].plot(freq, (np.angle(h)*180/np.pi+180)%360 - 180, color='green')
        >>> ax[1].set_ylabel("Angle (degrees)", color='green')
        >>> ax[1].set_xlabel("Frequency (Hz)")
        >>> ax[1].set_xlim([0, 100])
        >>> ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
        >>> ax[1].set_ylim([-90, 90])
        >>> ax[1].grid(True)
        >>> plt.show()

        Design and plot peaking comb filter at 250 Hz for a
        signal sampled at 1000 Hz, using quality factor Q = 30

        >>> fs = 1000.0  # Sample frequency (Hz)
        >>> f0 = 250.0  # Frequency to be retained (Hz)
        >>> Q = 30.0  # Quality factor
        >>> # Design peaking filter
        >>> b, a = signal.iircomb(f0, Q, ftype='peak', fs=fs, pass_zero=True)

        >>> # Frequency response
        >>> freq, h = signal.freqz(b, a, fs=fs)
        >>> response = abs(h)
        >>> # To avoid divide by zero when graphing
        >>> response[response == 0] = 1e-20
        >>> # Plot
        >>> fig, ax = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
        >>> ax[0].plot(freq, 20*np.log10(np.maximum(abs(h), 1e-5)), color='blue')
        >>> ax[0].set_title("Frequency Response")
        >>> ax[0].set_ylabel("Amplitude (dB)", color='blue')
        >>> ax[0].set_xlim([0, 500])
        >>> ax[0].set_ylim([-80, 10])
        >>> ax[0].grid(True)
        >>> ax[1].plot(freq, (np.angle(h)*180/np.pi+180)%360 - 180, color='green')
        >>> ax[1].set_ylabel("Angle (degrees)", color='green')
        >>> ax[1].set_xlabel("Frequency (Hz)")
        >>> ax[1].set_xlim([0, 500])
        >>> ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
        >>> ax[1].set_ylim([-90, 90])
        >>> ax[1].grid(True)
        >>> plt.show()

    iirdesign(wp, ws, gpass, gstop, analog=False, ftype='ellip', output='ba', fs=None)
        Complete IIR digital and analog filter design.

        Given passband and stopband frequencies and gains, construct an analog or
        digital IIR filter of minimum order for a given basic type. Return the
        output in numerator, denominator ('ba'), pole-zero ('zpk') or second order
        sections ('sos') form.

        Parameters
        ----------
        wp, ws : float or array like, shape (2,)
            Passband and stopband edge frequencies. Possible values are scalars
            (for lowpass and highpass filters) or ranges (for bandpass and bandstop
            filters).
            For digital filters, these are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. For example:

                - Lowpass:   wp = 0.2,          ws = 0.3
                - Highpass:  wp = 0.3,          ws = 0.2
                - Bandpass:  wp = [0.2, 0.5],   ws = [0.1, 0.6]
                - Bandstop:  wp = [0.1, 0.6],   ws = [0.2, 0.5]

            For analog filters, `wp` and `ws` are angular frequencies (e.g., rad/s).
            Note, that for bandpass and bandstop filters passband must lie strictly
            inside stopband or vice versa.
        gpass : float
            The maximum loss in the passband (dB).
        gstop : float
            The minimum attenuation in the stopband (dB).
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        ftype : str, optional
            The type of IIR filter to design:

                - Butterworth   : 'butter'
                - Chebyshev I   : 'cheby1'
                - Chebyshev II  : 'cheby2'
                - Cauer/elliptic: 'ellip'

        output : {'ba', 'zpk', 'sos'}, optional
            Filter form of the output:

                - second-order sections (recommended): 'sos'
                - numerator/denominator (default)    : 'ba'
                - pole-zero                          : 'zpk'

            In general the second-order sections ('sos') form  is
            recommended because inferring the coefficients for the
            numerator/denominator form ('ba') suffers from numerical
            instabilities. For reasons of backward compatibility the default
            form is the numerator/denominator form ('ba'), where the 'b'
            and the 'a' in 'ba' refer to the commonly used names of the
            coefficients used.

            Note: Using the second-order sections form ('sos') is sometimes
            associated with additional computational costs: for
            data-intense use cases it is therefore recommended to also
            investigate the numerator/denominator form ('ba').

        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        butter : Filter design using order and critical points
        cheby1, cheby2, ellip, bessel
        buttord : Find order and critical points from passband and stopband spec
        cheb1ord, cheb2ord, ellipord
        iirfilter : General filter design using order and critical frequencies

        Notes
        -----
        The ``'sos'`` output parameter was added in 0.16.0.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import matplotlib.ticker

        >>> wp = 0.2
        >>> ws = 0.3
        >>> gpass = 1
        >>> gstop = 40

        >>> system = signal.iirdesign(wp, ws, gpass, gstop)
        >>> w, h = signal.freqz(*system)

        >>> fig, ax1 = plt.subplots()
        >>> ax1.set_title('Digital filter frequency response')
        >>> ax1.plot(w, 20 * np.log10(abs(h)), 'b')
        >>> ax1.set_ylabel('Amplitude [dB]', color='b')
        >>> ax1.set_xlabel('Frequency [rad/sample]')
        >>> ax1.grid(True)
        >>> ax1.set_ylim([-120, 20])
        >>> ax2 = ax1.twinx()
        >>> angles = np.unwrap(np.angle(h))
        >>> ax2.plot(w, angles, 'g')
        >>> ax2.set_ylabel('Angle (radians)', color='g')
        >>> ax2.grid(True)
        >>> ax2.axis('tight')
        >>> ax2.set_ylim([-6, 1])
        >>> nticks = 8
        >>> ax1.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))
        >>> ax2.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))

    iirfilter(N, Wn, rp=None, rs=None, btype='band', analog=False, ftype='butter', output='ba', fs=None)
        IIR digital and analog filter design given order and critical points.

        Design an Nth-order digital or analog filter and return the filter
        coefficients.

        Parameters
        ----------
        N : int
            The order of the filter.
        Wn : array_like
            A scalar or length-2 sequence giving the critical frequencies.

            For digital filters, `Wn` are in the same units as `fs`. By default,
            `fs` is 2 half-cycles/sample, so these are normalized from 0 to 1,
            where 1 is the Nyquist frequency. (`Wn` is thus in
            half-cycles / sample.)

            For analog filters, `Wn` is an angular frequency (e.g., rad/s).

            When Wn is a length-2 sequence, ``Wn[0]`` must be less than ``Wn[1]``.
        rp : float, optional
            For Chebyshev and elliptic filters, provides the maximum ripple
            in the passband. (dB)
        rs : float, optional
            For Chebyshev and elliptic filters, provides the minimum attenuation
            in the stop band. (dB)
        btype : {'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
            The type of filter.  Default is 'bandpass'.
        analog : bool, optional
            When True, return an analog filter, otherwise a digital filter is
            returned.
        ftype : str, optional
            The type of IIR filter to design:

                - Butterworth   : 'butter'
                - Chebyshev I   : 'cheby1'
                - Chebyshev II  : 'cheby2'
                - Cauer/elliptic: 'ellip'
                - Bessel/Thomson: 'bessel'

        output : {'ba', 'zpk', 'sos'}, optional
            Filter form of the output:

                - second-order sections (recommended): 'sos'
                - numerator/denominator (default)    : 'ba'
                - pole-zero                          : 'zpk'

            In general the second-order sections ('sos') form  is
            recommended because inferring the coefficients for the
            numerator/denominator form ('ba') suffers from numerical
            instabilities. For reasons of backward compatibility the default
            form is the numerator/denominator form ('ba'), where the 'b'
            and the 'a' in 'ba' refer to the commonly used names of the
            coefficients used.

            Note: Using the second-order sections form ('sos') is sometimes
            associated with additional computational costs: for
            data-intense use cases it is therefore recommended to also
            investigate the numerator/denominator form ('ba').

        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (`b`) and denominator (`a`) polynomials of the IIR filter.
            Only returned if ``output='ba'``.
        z, p, k : ndarray, ndarray, float
            Zeros, poles, and system gain of the IIR filter transfer
            function.  Only returned if ``output='zpk'``.
        sos : ndarray
            Second-order sections representation of the IIR filter.
            Only returned if ``output='sos'``.

        See Also
        --------
        butter : Filter design using order and critical points
        cheby1, cheby2, ellip, bessel
        buttord : Find order and critical points from passband and stopband spec
        cheb1ord, cheb2ord, ellipord
        iirdesign : General filter design using passband and stopband spec

        Notes
        -----
        The ``'sos'`` output parameter was added in 0.16.0.

        Examples
        --------
        Generate a 17th-order Chebyshev II analog bandpass filter from 50 Hz to
        200 Hz and plot the frequency response:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> b, a = signal.iirfilter(17, [2*np.pi*50, 2*np.pi*200], rs=60,
        ...                         btype='band', analog=True, ftype='cheby2')
        >>> w, h = signal.freqs(b, a, 1000)
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(1, 1, 1)
        >>> ax.semilogx(w / (2*np.pi), 20 * np.log10(np.maximum(abs(h), 1e-5)))
        >>> ax.set_title('Chebyshev Type II bandpass frequency response')
        >>> ax.set_xlabel('Frequency [Hz]')
        >>> ax.set_ylabel('Amplitude [dB]')
        >>> ax.axis((10, 1000, -100, 10))
        >>> ax.grid(which='both', axis='both')
        >>> plt.show()

        Create a digital filter with the same properties, in a system with
        sampling rate of 2000 Hz, and plot the frequency response. (Second-order
        sections implementation is required to ensure stability of a filter of
        this order):

        >>> sos = signal.iirfilter(17, [50, 200], rs=60, btype='band',
        ...                        analog=False, ftype='cheby2', fs=2000,
        ...                        output='sos')
        >>> w, h = signal.sosfreqz(sos, 2000, fs=2000)
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(1, 1, 1)
        >>> ax.semilogx(w, 20 * np.log10(np.maximum(abs(h), 1e-5)))
        >>> ax.set_title('Chebyshev Type II bandpass frequency response')
        >>> ax.set_xlabel('Frequency [Hz]')
        >>> ax.set_ylabel('Amplitude [dB]')
        >>> ax.axis((10, 1000, -100, 10))
        >>> ax.grid(which='both', axis='both')
        >>> plt.show()

    iirnotch(w0, Q, fs=2.0)
        Design second-order IIR notch digital filter.

        A notch filter is a band-stop filter with a narrow bandwidth
        (high quality factor). It rejects a narrow frequency band and
        leaves the rest of the spectrum little changed.

        Parameters
        ----------
        w0 : float
            Frequency to remove from a signal. If `fs` is specified, this is in
            the same units as `fs`. By default, it is a normalized scalar that must
            satisfy  ``0 < w0 < 1``, with ``w0 = 1`` corresponding to half of the
            sampling frequency.
        Q : float
            Quality factor. Dimensionless parameter that characterizes
            notch filter -3 dB bandwidth ``bw`` relative to its center
            frequency, ``Q = w0/bw``.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (``b``) and denominator (``a``) polynomials
            of the IIR filter.

        See Also
        --------
        iirpeak

        Notes
        -----
        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Sophocles J. Orfanidis, "Introduction To Signal Processing",
               Prentice-Hall, 1996

        Examples
        --------
        Design and plot filter to remove the 60 Hz component from a
        signal sampled at 200 Hz, using a quality factor Q = 30

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> fs = 200.0  # Sample frequency (Hz)
        >>> f0 = 60.0  # Frequency to be removed from signal (Hz)
        >>> Q = 30.0  # Quality factor
        >>> # Design notch filter
        >>> b, a = signal.iirnotch(f0, Q, fs)

        >>> # Frequency response
        >>> freq, h = signal.freqz(b, a, fs=fs)
        >>> # Plot
        >>> fig, ax = plt.subplots(2, 1, figsize=(8, 6))
        >>> ax[0].plot(freq, 20*np.log10(abs(h)), color='blue')
        >>> ax[0].set_title("Frequency Response")
        >>> ax[0].set_ylabel("Amplitude (dB)", color='blue')
        >>> ax[0].set_xlim([0, 100])
        >>> ax[0].set_ylim([-25, 10])
        >>> ax[0].grid(True)
        >>> ax[1].plot(freq, np.unwrap(np.angle(h))*180/np.pi, color='green')
        >>> ax[1].set_ylabel("Angle (degrees)", color='green')
        >>> ax[1].set_xlabel("Frequency (Hz)")
        >>> ax[1].set_xlim([0, 100])
        >>> ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
        >>> ax[1].set_ylim([-90, 90])
        >>> ax[1].grid(True)
        >>> plt.show()

    iirpeak(w0, Q, fs=2.0)
        Design second-order IIR peak (resonant) digital filter.

        A peak filter is a band-pass filter with a narrow bandwidth
        (high quality factor). It rejects components outside a narrow
        frequency band.

        Parameters
        ----------
        w0 : float
            Frequency to be retained in a signal. If `fs` is specified, this is in
            the same units as `fs`. By default, it is a normalized scalar that must
            satisfy  ``0 < w0 < 1``, with ``w0 = 1`` corresponding to half of the
            sampling frequency.
        Q : float
            Quality factor. Dimensionless parameter that characterizes
            peak filter -3 dB bandwidth ``bw`` relative to its center
            frequency, ``Q = w0/bw``.
        fs : float, optional
            The sampling frequency of the digital system.

            .. versionadded:: 1.2.0

        Returns
        -------
        b, a : ndarray, ndarray
            Numerator (``b``) and denominator (``a``) polynomials
            of the IIR filter.

        See Also
        --------
        iirnotch

        Notes
        -----
        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Sophocles J. Orfanidis, "Introduction To Signal Processing",
               Prentice-Hall, 1996

        Examples
        --------
        Design and plot filter to remove the frequencies other than the 300 Hz
        component from a signal sampled at 1000 Hz, using a quality factor Q = 30

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> fs = 1000.0  # Sample frequency (Hz)
        >>> f0 = 300.0  # Frequency to be retained (Hz)
        >>> Q = 30.0  # Quality factor
        >>> # Design peak filter
        >>> b, a = signal.iirpeak(f0, Q, fs)

        >>> # Frequency response
        >>> freq, h = signal.freqz(b, a, fs=fs)
        >>> # Plot
        >>> fig, ax = plt.subplots(2, 1, figsize=(8, 6))
        >>> ax[0].plot(freq, 20*np.log10(np.maximum(abs(h), 1e-5)), color='blue')
        >>> ax[0].set_title("Frequency Response")
        >>> ax[0].set_ylabel("Amplitude (dB)", color='blue')
        >>> ax[0].set_xlim([0, 500])
        >>> ax[0].set_ylim([-50, 10])
        >>> ax[0].grid(True)
        >>> ax[1].plot(freq, np.unwrap(np.angle(h))*180/np.pi, color='green')
        >>> ax[1].set_ylabel("Angle (degrees)", color='green')
        >>> ax[1].set_xlabel("Frequency (Hz)")
        >>> ax[1].set_xlim([0, 500])
        >>> ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90])
        >>> ax[1].set_ylim([-90, 90])
        >>> ax[1].grid(True)
        >>> plt.show()

    impulse(system, X0=None, T=None, N=None)
        Impulse response of continuous-time system.

        Parameters
        ----------
        system : an instance of the LTI class or a tuple of array_like
            describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `lti`)
                * 2 (num, den)
                * 3 (zeros, poles, gain)
                * 4 (A, B, C, D)

        X0 : array_like, optional
            Initial state-vector.  Defaults to zero.
        T : array_like, optional
            Time points.  Computed if not given.
        N : int, optional
            The number of time points to compute (if `T` is not given).

        Returns
        -------
        T : ndarray
            A 1-D array of time points.
        yout : ndarray
            A 1-D array containing the impulse response of the system (except for
            singularities at zero).

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``).

        Examples
        --------
        Compute the impulse response of a second order system with a repeated
        root: ``x''(t) + 2*x'(t) + x(t) = u(t)``

        >>> from scipy import signal
        >>> system = ([1.0], [1.0, 2.0, 1.0])
        >>> t, y = signal.impulse(system)
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(t, y)

    invres(r, p, k, tol=0.001, rtype='avg')
        Compute b(s) and a(s) from partial fraction expansion.

        If `M` is the degree of numerator `b` and `N` the degree of denominator
        `a`::

                  b(s)     b[0] s**(M) + b[1] s**(M-1) + ... + b[M]
          H(s) = ------ = ------------------------------------------
                  a(s)     a[0] s**(N) + a[1] s**(N-1) + ... + a[N]

        then the partial-fraction expansion H(s) is defined as::

                   r[0]       r[1]             r[-1]
               = -------- + -------- + ... + --------- + k(s)
                 (s-p[0])   (s-p[1])         (s-p[-1])

        If there are any repeated roots (closer together than `tol`), then H(s)
        has terms like::

              r[i]      r[i+1]              r[i+n-1]
            -------- + ----------- + ... + -----------
            (s-p[i])  (s-p[i])**2          (s-p[i])**n

        This function is used for polynomials in positive powers of s or z,
        such as analog filters or digital filters in controls engineering.  For
        negative powers of z (typical for digital filters in DSP), use `invresz`.

        Parameters
        ----------
        r : array_like
            Residues corresponding to the poles. For repeated poles, the residues
            must be ordered to correspond to ascending by power fractions.
        p : array_like
            Poles. Equal poles must be adjacent.
        k : array_like
            Coefficients of the direct polynomial term.
        tol : float, optional
            The tolerance for two roots to be considered equal in terms of
            the distance between them. Default is 1e-3. See `unique_roots`
            for further details.
        rtype : {'avg', 'min', 'max'}, optional
            Method for computing a root to represent a group of identical roots.
            Default is 'avg'. See `unique_roots` for further details.

        Returns
        -------
        b : ndarray
            Numerator polynomial coefficients.
        a : ndarray
            Denominator polynomial coefficients.

        See Also
        --------
        residue, invresz, unique_roots

    invresz(r, p, k, tol=0.001, rtype='avg')
        Compute b(z) and a(z) from partial fraction expansion.

        If `M` is the degree of numerator `b` and `N` the degree of denominator
        `a`::

                    b(z)     b[0] + b[1] z**(-1) + ... + b[M] z**(-M)
            H(z) = ------ = ------------------------------------------
                    a(z)     a[0] + a[1] z**(-1) + ... + a[N] z**(-N)

        then the partial-fraction expansion H(z) is defined as::

                     r[0]                   r[-1]
             = --------------- + ... + ---------------- + k[0] + k[1]z**(-1) ...
               (1-p[0]z**(-1))         (1-p[-1]z**(-1))

        If there are any repeated roots (closer than `tol`), then the partial
        fraction expansion has terms like::

                 r[i]              r[i+1]                    r[i+n-1]
            -------------- + ------------------ + ... + ------------------
            (1-p[i]z**(-1))  (1-p[i]z**(-1))**2         (1-p[i]z**(-1))**n

        This function is used for polynomials in negative powers of z,
        such as digital filters in DSP.  For positive powers, use `invres`.

        Parameters
        ----------
        r : array_like
            Residues corresponding to the poles. For repeated poles, the residues
            must be ordered to correspond to ascending by power fractions.
        p : array_like
            Poles. Equal poles must be adjacent.
        k : array_like
            Coefficients of the direct polynomial term.
        tol : float, optional
            The tolerance for two roots to be considered equal in terms of
            the distance between them. Default is 1e-3. See `unique_roots`
            for further details.
        rtype : {'avg', 'min', 'max'}, optional
            Method for computing a root to represent a group of identical roots.
            Default is 'avg'. See `unique_roots` for further details.

        Returns
        -------
        b : ndarray
            Numerator polynomial coefficients.
        a : ndarray
            Denominator polynomial coefficients.

        See Also
        --------
        residuez, unique_roots, invres

    istft(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, input_onesided=True, boundary=True, time_axis=-1, freq_axis=-2, scaling='spectrum')
        Perform the inverse Short Time Fourier transform (legacy function).

        .. legacy:: function

            `ShortTimeFFT` is a newer STFT / ISTFT implementation with more
            features. A :ref:`comparison <tutorial_stft_legacy_stft>` between the
            implementations can be found in the :ref:`tutorial_stft` section of the
            :ref:`user_guide`.

        Parameters
        ----------
        Zxx : array_like
            STFT of the signal to be reconstructed. If a purely real array
            is passed, it will be cast to a complex data type.
        fs : float, optional
            Sampling frequency of the time series. Defaults to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg. Defaults
            to a Hann window. Must match the window used to generate the
            STFT for faithful inversion.
        nperseg : int, optional
            Number of data points corresponding to each STFT segment. This
            parameter must be specified if the number of data points per
            segment is odd, or if the STFT was padded via ``nfft >
            nperseg``. If `None`, the value depends on the shape of
            `Zxx` and `input_onesided`. If `input_onesided` is `True`,
            ``nperseg=2*(Zxx.shape[freq_axis] - 1)``. Otherwise,
            ``nperseg=Zxx.shape[freq_axis]``. Defaults to `None`.
        noverlap : int, optional
            Number of points to overlap between segments. If `None`, half
            of the segment length. Defaults to `None`. When specified, the
            COLA constraint must be met (see Notes below), and should match
            the parameter used to generate the STFT. Defaults to `None`.
        nfft : int, optional
            Number of FFT points corresponding to each STFT segment. This
            parameter must be specified if the STFT was padded via ``nfft >
            nperseg``. If `None`, the default values are the same as for
            `nperseg`, detailed above, with one exception: if
            `input_onesided` is True and
            ``nperseg==2*Zxx.shape[freq_axis] - 1``, `nfft` also takes on
            that value. This case allows the proper inversion of an
            odd-length unpadded STFT using ``nfft=None``. Defaults to
            `None`.
        input_onesided : bool, optional
            If `True`, interpret the input array as one-sided FFTs, such
            as is returned by `stft` with ``return_onesided=True`` and
            `numpy.fft.rfft`. If `False`, interpret the input as a a
            two-sided FFT. Defaults to `True`.
        boundary : bool, optional
            Specifies whether the input signal was extended at its
            boundaries by supplying a non-`None` ``boundary`` argument to
            `stft`. Defaults to `True`.
        time_axis : int, optional
            Where the time segments of the STFT is located; the default is
            the last axis (i.e. ``axis=-1``).
        freq_axis : int, optional
            Where the frequency axis of the STFT is located; the default is
            the penultimate axis (i.e. ``axis=-2``).
        scaling: {'spectrum', 'psd'}
            The default 'spectrum' scaling allows each frequency line of `Zxx` to
            be interpreted as a magnitude spectrum. The 'psd' option scales each
            line to a power spectral density - it allows to calculate the signal's
            energy by numerically integrating over ``abs(Zxx)**2``.

        Returns
        -------
        t : ndarray
            Array of output data times.
        x : ndarray
            iSTFT of `Zxx`.

        See Also
        --------
        stft: Short Time Fourier Transform
        ShortTimeFFT: Newer STFT/ISTFT implementation providing more features.
        check_COLA: Check whether the Constant OverLap Add (COLA) constraint
                    is met
        check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met

        Notes
        -----
        In order to enable inversion of an STFT via the inverse STFT with
        `istft`, the signal windowing must obey the constraint of "nonzero
        overlap add" (NOLA):

        .. math:: \sum_{t}w^{2}[n-tH] \ne 0

        This ensures that the normalization factors that appear in the denominator
        of the overlap-add reconstruction equation

        .. math:: x[n]=\frac{\sum_{t}x_{t}[n]w[n-tH]}{\sum_{t}w^{2}[n-tH]}

        are not zero. The NOLA constraint can be checked with the `check_NOLA`
        function.

        An STFT which has been modified (via masking or otherwise) is not
        guaranteed to correspond to a exactly realizible signal. This
        function implements the iSTFT via the least-squares estimation
        algorithm detailed in [2]_, which produces a signal that minimizes
        the mean squared error between the STFT of the returned signal and
        the modified STFT.


        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
               "Discrete-Time Signal Processing", Prentice Hall, 1999.
        .. [2] Daniel W. Griffin, Jae S. Lim "Signal Estimation from
               Modified Short-Time Fourier Transform", IEEE 1984,
               10.1109/TASSP.1984.1164317

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate a test signal, a 2 Vrms sine wave at 50Hz corrupted by
        0.001 V**2/Hz of white noise sampled at 1024 Hz.

        >>> fs = 1024
        >>> N = 10*fs
        >>> nperseg = 512
        >>> amp = 2 * np.sqrt(2)
        >>> noise_power = 0.001 * fs / 2
        >>> time = np.arange(N) / float(fs)
        >>> carrier = amp * np.sin(2*np.pi*50*time)
        >>> noise = rng.normal(scale=np.sqrt(noise_power),
        ...                    size=time.shape)
        >>> x = carrier + noise

        Compute the STFT, and plot its magnitude

        >>> f, t, Zxx = signal.stft(x, fs=fs, nperseg=nperseg)
        >>> plt.figure()
        >>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud')
        >>> plt.ylim([f[1], f[-1]])
        >>> plt.title('STFT Magnitude')
        >>> plt.ylabel('Frequency [Hz]')
        >>> plt.xlabel('Time [sec]')
        >>> plt.yscale('log')
        >>> plt.show()

        Zero the components that are 10% or less of the carrier magnitude,
        then convert back to a time series via inverse STFT

        >>> Zxx = np.where(np.abs(Zxx) >= amp/10, Zxx, 0)
        >>> _, xrec = signal.istft(Zxx, fs)

        Compare the cleaned signal with the original and true carrier signals.

        >>> plt.figure()
        >>> plt.plot(time, x, time, xrec, time, carrier)
        >>> plt.xlim([2, 2.1])
        >>> plt.xlabel('Time [sec]')
        >>> plt.ylabel('Signal')
        >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier'])
        >>> plt.show()

        Note that the cleaned signal does not start as abruptly as the original,
        since some of the coefficients of the transient were also removed:

        >>> plt.figure()
        >>> plt.plot(time, x, time, xrec, time, carrier)
        >>> plt.xlim([0, 0.1])
        >>> plt.xlabel('Time [sec]')
        >>> plt.ylabel('Signal')
        >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier'])
        >>> plt.show()

    kaiser_atten(numtaps, width)
        Compute the attenuation of a Kaiser FIR filter.

        Given the number of taps `N` and the transition width `width`, compute the
        attenuation `a` in dB, given by Kaiser's formula:

            a = 2.285 * (N - 1) * pi * width + 7.95

        Parameters
        ----------
        numtaps : int
            The number of taps in the FIR filter.
        width : float
            The desired width of the transition region between passband and
            stopband (or, in general, at any discontinuity) for the filter,
            expressed as a fraction of the Nyquist frequency.

        Returns
        -------
        a : float
            The attenuation of the ripple, in dB.

        See Also
        --------
        kaiserord, kaiser_beta

        Examples
        --------
        Suppose we want to design a FIR filter using the Kaiser window method
        that will have 211 taps and a transition width of 9 Hz for a signal that
        is sampled at 480 Hz. Expressed as a fraction of the Nyquist frequency,
        the width is 9/(0.5*480) = 0.0375. The approximate attenuation (in dB)
        is computed as follows:

        >>> from scipy.signal import kaiser_atten
        >>> kaiser_atten(211, 0.0375)
        64.48099630593983

    kaiser_beta(a)
        Compute the Kaiser parameter `beta`, given the attenuation `a`.

        Parameters
        ----------
        a : float
            The desired attenuation in the stopband and maximum ripple in
            the passband, in dB.  This should be a *positive* number.

        Returns
        -------
        beta : float
            The `beta` parameter to be used in the formula for a Kaiser window.

        References
        ----------
        Oppenheim, Schafer, "Discrete-Time Signal Processing", p.475-476.

        Examples
        --------
        Suppose we want to design a lowpass filter, with 65 dB attenuation
        in the stop band.  The Kaiser window parameter to be used in the
        window method is computed by ``kaiser_beta(65)``:

        >>> from scipy.signal import kaiser_beta
        >>> kaiser_beta(65)
        6.20426

    kaiserord(ripple, width)
        Determine the filter window parameters for the Kaiser window method.

        The parameters returned by this function are generally used to create
        a finite impulse response filter using the window method, with either
        `firwin` or `firwin2`.

        Parameters
        ----------
        ripple : float
            Upper bound for the deviation (in dB) of the magnitude of the
            filter's frequency response from that of the desired filter (not
            including frequencies in any transition intervals). That is, if w
            is the frequency expressed as a fraction of the Nyquist frequency,
            A(w) is the actual frequency response of the filter and D(w) is the
            desired frequency response, the design requirement is that::

                abs(A(w) - D(w))) < 10**(-ripple/20)

            for 0 <= w <= 1 and w not in a transition interval.
        width : float
            Width of transition region, normalized so that 1 corresponds to pi
            radians / sample. That is, the frequency is expressed as a fraction
            of the Nyquist frequency.

        Returns
        -------
        numtaps : int
            The length of the Kaiser window.
        beta : float
            The beta parameter for the Kaiser window.

        See Also
        --------
        kaiser_beta, kaiser_atten

        Notes
        -----
        There are several ways to obtain the Kaiser window:

        - ``signal.windows.kaiser(numtaps, beta, sym=True)``
        - ``signal.get_window(beta, numtaps)``
        - ``signal.get_window(('kaiser', beta), numtaps)``

        The empirical equations discovered by Kaiser are used.

        References
        ----------
        Oppenheim, Schafer, "Discrete-Time Signal Processing", pp.475-476.

        Examples
        --------
        We will use the Kaiser window method to design a lowpass FIR filter
        for a signal that is sampled at 1000 Hz.

        We want at least 65 dB rejection in the stop band, and in the pass
        band the gain should vary no more than 0.5%.

        We want a cutoff frequency of 175 Hz, with a transition between the
        pass band and the stop band of 24 Hz. That is, in the band [0, 163],
        the gain varies no more than 0.5%, and in the band [187, 500], the
        signal is attenuated by at least 65 dB.

        >>> import numpy as np
        >>> from scipy.signal import kaiserord, firwin, freqz
        >>> import matplotlib.pyplot as plt
        >>> fs = 1000.0
        >>> cutoff = 175
        >>> width = 24

        The Kaiser method accepts just a single parameter to control the pass
        band ripple and the stop band rejection, so we use the more restrictive
        of the two. In this case, the pass band ripple is 0.005, or 46.02 dB,
        so we will use 65 dB as the design parameter.

        Use `kaiserord` to determine the length of the filter and the
        parameter for the Kaiser window.

        >>> numtaps, beta = kaiserord(65, width/(0.5*fs))
        >>> numtaps
        167
        >>> beta
        6.20426

        Use `firwin` to create the FIR filter.

        >>> taps = firwin(numtaps, cutoff, window=('kaiser', beta),
        ...               scale=False, fs=fs)

        Compute the frequency response of the filter.  ``w`` is the array of
        frequencies, and ``h`` is the corresponding complex array of frequency
        responses.

        >>> w, h = freqz(taps, worN=8000)
        >>> w *= 0.5*fs/np.pi  # Convert w to Hz.

        Compute the deviation of the magnitude of the filter's response from
        that of the ideal lowpass filter. Values in the transition region are
        set to ``nan``, so they won't appear in the plot.

        >>> ideal = w < cutoff  # The "ideal" frequency response.
        >>> deviation = np.abs(np.abs(h) - ideal)
        >>> deviation[(w > cutoff - 0.5*width) & (w < cutoff + 0.5*width)] = np.nan

        Plot the deviation. A close look at the left end of the stop band shows
        that the requirement for 65 dB attenuation is violated in the first lobe
        by about 0.125 dB. This is not unusual for the Kaiser window method.

        >>> plt.plot(w, 20*np.log10(np.abs(deviation)))
        >>> plt.xlim(0, 0.5*fs)
        >>> plt.ylim(-90, -60)
        >>> plt.grid(alpha=0.25)
        >>> plt.axhline(-65, color='r', ls='--', alpha=0.3)
        >>> plt.xlabel('Frequency (Hz)')
        >>> plt.ylabel('Deviation from ideal (dB)')
        >>> plt.title('Lowpass Filter Frequency Response')
        >>> plt.show()

    lfilter(b, a, x, axis=-1, zi=None)
        Filter data along one-dimension with an IIR or FIR filter.

        Filter a data sequence, `x`, using a digital filter.  This works for many
        fundamental data types (including Object type).  The filter is a direct
        form II transposed implementation of the standard difference equation
        (see Notes).

        The function `sosfilt` (and filter design using ``output='sos'``) should be
        preferred over `lfilter` for most filtering tasks, as second-order sections
        have fewer numerical problems.

        Parameters
        ----------
        b : array_like
            The numerator coefficient vector in a 1-D sequence.
        a : array_like
            The denominator coefficient vector in a 1-D sequence.  If ``a[0]``
            is not 1, then both `a` and `b` are normalized by ``a[0]``.
        x : array_like
            An N-dimensional input array.
        axis : int, optional
            The axis of the input data array along which to apply the
            linear filter. The filter is applied to each subarray along
            this axis.  Default is -1.
        zi : array_like, optional
            Initial conditions for the filter delays.  It is a vector
            (or array of vectors for an N-dimensional input) of length
            ``max(len(a), len(b)) - 1``.  If `zi` is None or is not given then
            initial rest is assumed.  See `lfiltic` for more information.

        Returns
        -------
        y : array
            The output of the digital filter.
        zf : array, optional
            If `zi` is None, this is not returned, otherwise, `zf` holds the
            final filter delay values.

        See Also
        --------
        lfiltic : Construct initial conditions for `lfilter`.
        lfilter_zi : Compute initial state (steady state of step response) for
                     `lfilter`.
        filtfilt : A forward-backward filter, to obtain a filter with zero phase.
        savgol_filter : A Savitzky-Golay filter.
        sosfilt: Filter data using cascaded second-order sections.
        sosfiltfilt: A forward-backward filter using second-order sections.

        Notes
        -----
        The filter function is implemented as a direct II transposed structure.
        This means that the filter implements::

           a[0]*y[n] = b[0]*x[n] + b[1]*x[n-1] + ... + b[M]*x[n-M]
                                 - a[1]*y[n-1] - ... - a[N]*y[n-N]

        where `M` is the degree of the numerator, `N` is the degree of the
        denominator, and `n` is the sample number.  It is implemented using
        the following difference equations (assuming M = N)::

             a[0]*y[n] = b[0] * x[n]               + d[0][n-1]
               d[0][n] = b[1] * x[n] - a[1] * y[n] + d[1][n-1]
               d[1][n] = b[2] * x[n] - a[2] * y[n] + d[2][n-1]
             ...
             d[N-2][n] = b[N-1]*x[n] - a[N-1]*y[n] + d[N-1][n-1]
             d[N-1][n] = b[N] * x[n] - a[N] * y[n]

        where `d` are the state variables.

        The rational transfer function describing this filter in the
        z-transform domain is::

                                 -1              -M
                     b[0] + b[1]z  + ... + b[M] z
             Y(z) = -------------------------------- X(z)
                                 -1              -N
                     a[0] + a[1]z  + ... + a[N] z

        Examples
        --------
        Generate a noisy signal to be filtered:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> t = np.linspace(-1, 1, 201)
        >>> x = (np.sin(2*np.pi*0.75*t*(1-t) + 2.1) +
        ...      0.1*np.sin(2*np.pi*1.25*t + 1) +
        ...      0.18*np.cos(2*np.pi*3.85*t))
        >>> xn = x + rng.standard_normal(len(t)) * 0.08

        Create an order 3 lowpass butterworth filter:

        >>> b, a = signal.butter(3, 0.05)

        Apply the filter to xn.  Use lfilter_zi to choose the initial condition of
        the filter:

        >>> zi = signal.lfilter_zi(b, a)
        >>> z, _ = signal.lfilter(b, a, xn, zi=zi*xn[0])

        Apply the filter again, to have a result filtered at an order the same as
        filtfilt:

        >>> z2, _ = signal.lfilter(b, a, z, zi=zi*z[0])

        Use filtfilt to apply the filter:

        >>> y = signal.filtfilt(b, a, xn)

        Plot the original signal and the various filtered versions:

        >>> plt.figure
        >>> plt.plot(t, xn, 'b', alpha=0.75)
        >>> plt.plot(t, z, 'r--', t, z2, 'r', t, y, 'k')
        >>> plt.legend(('noisy signal', 'lfilter, once', 'lfilter, twice',
        ...             'filtfilt'), loc='best')
        >>> plt.grid(True)
        >>> plt.show()

    lfilter_zi(b, a)
        Construct initial conditions for lfilter for step response steady-state.

        Compute an initial state `zi` for the `lfilter` function that corresponds
        to the steady state of the step response.

        A typical use of this function is to set the initial state so that the
        output of the filter starts at the same value as the first element of
        the signal to be filtered.

        Parameters
        ----------
        b, a : array_like (1-D)
            The IIR filter coefficients. See `lfilter` for more
            information.

        Returns
        -------
        zi : 1-D ndarray
            The initial state for the filter.

        See Also
        --------
        lfilter, lfiltic, filtfilt

        Notes
        -----
        A linear filter with order m has a state space representation (A, B, C, D),
        for which the output y of the filter can be expressed as::

            z(n+1) = A*z(n) + B*x(n)
            y(n)   = C*z(n) + D*x(n)

        where z(n) is a vector of length m, A has shape (m, m), B has shape
        (m, 1), C has shape (1, m) and D has shape (1, 1) (assuming x(n) is
        a scalar).  lfilter_zi solves::

            zi = A*zi + B

        In other words, it finds the initial condition for which the response
        to an input of all ones is a constant.

        Given the filter coefficients `a` and `b`, the state space matrices
        for the transposed direct form II implementation of the linear filter,
        which is the implementation used by scipy.signal.lfilter, are::

            A = scipy.linalg.companion(a).T
            B = b[1:] - a[1:]*b[0]

        assuming `a[0]` is 1.0; if `a[0]` is not 1, `a` and `b` are first
        divided by a[0].

        Examples
        --------
        The following code creates a lowpass Butterworth filter. Then it
        applies that filter to an array whose values are all 1.0; the
        output is also all 1.0, as expected for a lowpass filter.  If the
        `zi` argument of `lfilter` had not been given, the output would have
        shown the transient signal.

        >>> from numpy import array, ones
        >>> from scipy.signal import lfilter, lfilter_zi, butter
        >>> b, a = butter(5, 0.25)
        >>> zi = lfilter_zi(b, a)
        >>> y, zo = lfilter(b, a, ones(10), zi=zi)
        >>> y
        array([1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])

        Another example:

        >>> x = array([0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0])
        >>> y, zf = lfilter(b, a, x, zi=zi*x[0])
        >>> y
        array([ 0.5       ,  0.5       ,  0.5       ,  0.49836039,  0.48610528,
            0.44399389,  0.35505241])

        Note that the `zi` argument to `lfilter` was computed using
        `lfilter_zi` and scaled by `x[0]`.  Then the output `y` has no
        transient until the input drops from 0.5 to 0.0.

    lfiltic(b, a, y, x=None)
        Construct initial conditions for lfilter given input and output vectors.

        Given a linear filter (b, a) and initial conditions on the output `y`
        and the input `x`, return the initial conditions on the state vector zi
        which is used by `lfilter` to generate the output given the input.

        Parameters
        ----------
        b : array_like
            Linear filter term.
        a : array_like
            Linear filter term.
        y : array_like
            Initial conditions.

            If ``N = len(a) - 1``, then ``y = {y[-1], y[-2], ..., y[-N]}``.

            If `y` is too short, it is padded with zeros.
        x : array_like, optional
            Initial conditions.

            If ``M = len(b) - 1``, then ``x = {x[-1], x[-2], ..., x[-M]}``.

            If `x` is not given, its initial conditions are assumed zero.

            If `x` is too short, it is padded with zeros.

        Returns
        -------
        zi : ndarray
            The state vector ``zi = {z_0[-1], z_1[-1], ..., z_K-1[-1]}``,
            where ``K = max(M, N)``.

        See Also
        --------
        lfilter, lfilter_zi

    lombscargle(x, y, freqs, precenter=False, normalize=False)
        lombscargle(x, y, freqs)

        Computes the Lomb-Scargle periodogram.

        The Lomb-Scargle periodogram was developed by Lomb [1]_ and further
        extended by Scargle [2]_ to find, and test the significance of weak
        periodic signals with uneven temporal sampling.

        When *normalize* is False (default) the computed periodogram
        is unnormalized, it takes the value ``(A**2) * N/4`` for a harmonic
        signal with amplitude A for sufficiently large N.

        When *normalize* is True the computed periodogram is normalized by
        the residuals of the data around a constant reference model (at zero).

        Input arrays should be 1-D and will be cast to float64.

        Parameters
        ----------
        x : array_like
            Sample times.
        y : array_like
            Measurement values.
        freqs : array_like
            Angular frequencies for output periodogram.
        precenter : bool, optional
            Pre-center measurement values by subtracting the mean.
        normalize : bool, optional
            Compute normalized periodogram.

        Returns
        -------
        pgram : array_like
            Lomb-Scargle periodogram.

        Raises
        ------
        ValueError
            If the input arrays `x` and `y` do not have the same shape.

        See Also
        --------
        istft: Inverse Short Time Fourier Transform
        check_COLA: Check whether the Constant OverLap Add (COLA) constraint is met
        welch: Power spectral density by Welch's method
        spectrogram: Spectrogram by Welch's method
        csd: Cross spectral density by Welch's method

        Notes
        -----
        This subroutine calculates the periodogram using a slightly
        modified algorithm due to Townsend [3]_ which allows the
        periodogram to be calculated using only a single pass through
        the input arrays for each frequency.

        The algorithm running time scales roughly as O(x * freqs) or O(N^2)
        for a large number of samples and frequencies.

        References
        ----------
        .. [1] N.R. Lomb "Least-squares frequency analysis of unequally spaced
               data", Astrophysics and Space Science, vol 39, pp. 447-462, 1976

        .. [2] J.D. Scargle "Studies in astronomical time series analysis. II -
               Statistical aspects of spectral analysis of unevenly spaced data",
               The Astrophysical Journal, vol 263, pp. 835-853, 1982

        .. [3] R.H.D. Townsend, "Fast calculation of the Lomb-Scargle
               periodogram using graphics processing units.", The Astrophysical
               Journal Supplement Series, vol 191, pp. 247-253, 2010

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        First define some input parameters for the signal:

        >>> A = 2.
        >>> w0 = 1.  # rad/sec
        >>> nin = 150
        >>> nout = 100000

        Randomly generate sample times:

        >>> x = rng.uniform(0, 10*np.pi, nin)

        Plot a sine wave for the selected times:

        >>> y = A * np.cos(w0*x)

        Define the array of frequencies for which to compute the periodogram:

        >>> w = np.linspace(0.01, 10, nout)

        Calculate Lomb-Scargle periodogram:

        >>> import scipy.signal as signal
        >>> pgram = signal.lombscargle(x, y, w, normalize=True)

        Now make a plot of the input data:

        >>> fig, (ax_t, ax_w) = plt.subplots(2, 1, constrained_layout=True)
        >>> ax_t.plot(x, y, 'b+')
        >>> ax_t.set_xlabel('Time [s]')

        Then plot the normalized periodogram:

        >>> ax_w.plot(w, pgram)
        >>> ax_w.set_xlabel('Angular frequency [rad/s]')
        >>> ax_w.set_ylabel('Normalized amplitude')
        >>> plt.show()

    lp2bp(b, a, wo=1.0, bw=1.0)
        Transform a lowpass filter prototype to a bandpass filter.

        Return an analog band-pass filter with center frequency `wo` and
        bandwidth `bw` from an analog low-pass filter prototype with unity
        cutoff frequency, in transfer function ('ba') representation.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        wo : float
            Desired passband center, as angular frequency (e.g., rad/s).
            Defaults to no change.
        bw : float
            Desired passband width, as angular frequency (e.g., rad/s).
            Defaults to 1.

        Returns
        -------
        b : array_like
            Numerator polynomial coefficients of the transformed band-pass filter.
        a : array_like
            Denominator polynomial coefficients of the transformed band-pass filter.

        See Also
        --------
        lp2lp, lp2hp, lp2bs, bilinear
        lp2bp_zpk

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s^2 + {\omega_0}^2}{s \cdot \mathrm{BW}}

        This is the "wideband" transformation, producing a passband with
        geometric (log frequency) symmetry about `wo`.

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> lp = signal.lti([1.0], [1.0, 1.0])
        >>> bp = signal.lti(*signal.lp2bp(lp.num, lp.den))
        >>> w, mag_lp, p_lp = lp.bode()
        >>> w, mag_bp, p_bp = bp.bode(w)

        >>> plt.plot(w, mag_lp, label='Lowpass')
        >>> plt.plot(w, mag_bp, label='Bandpass')
        >>> plt.semilogx()
        >>> plt.grid(True)
        >>> plt.xlabel('Frequency [rad/s]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.legend()

    lp2bp_zpk(z, p, k, wo=1.0, bw=1.0)
        Transform a lowpass filter prototype to a bandpass filter.

        Return an analog band-pass filter with center frequency `wo` and
        bandwidth `bw` from an analog low-pass filter prototype with unity
        cutoff frequency, using zeros, poles, and gain ('zpk') representation.

        Parameters
        ----------
        z : array_like
            Zeros of the analog filter transfer function.
        p : array_like
            Poles of the analog filter transfer function.
        k : float
            System gain of the analog filter transfer function.
        wo : float
            Desired passband center, as angular frequency (e.g., rad/s).
            Defaults to no change.
        bw : float
            Desired passband width, as angular frequency (e.g., rad/s).
            Defaults to 1.

        Returns
        -------
        z : ndarray
            Zeros of the transformed band-pass filter transfer function.
        p : ndarray
            Poles of the transformed band-pass filter transfer function.
        k : float
            System gain of the transformed band-pass filter.

        See Also
        --------
        lp2lp_zpk, lp2hp_zpk, lp2bs_zpk, bilinear
        lp2bp

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s^2 + {\omega_0}^2}{s \cdot \mathrm{BW}}

        This is the "wideband" transformation, producing a passband with
        geometric (log frequency) symmetry about `wo`.

        .. versionadded:: 1.1.0

        Examples
        --------
        Use the 'zpk' (Zero-Pole-Gain) representation of a lowpass filter to
        transform it to a bandpass filter with a center frequency wo and
        bandwidth bw.

        >>> from scipy.signal import lp2bp_zpk
        >>> z   = [ 5 + 2j ,  5 - 2j ]
        >>> p   = [ 7      ,  -16    ]
        >>> k   = 0.8
        >>> wo  = 0.62
        >>> bw  = 15
        >>> lp2bp_zpk(z, p, k, wo, bw)
        (   array([7.49955815e+01+3.00017676e+01j, 7.49955815e+01-3.00017676e+01j,
                   4.41850748e-03-1.76761126e-03j, 4.41850748e-03+1.76761126e-03j]),
            array([1.04996339e+02+0.j, -1.60167736e-03+0.j,  3.66108003e-03+0.j,
                   -2.39998398e+02+0.j]), 0.8)

    lp2bs(b, a, wo=1.0, bw=1.0)
        Transform a lowpass filter prototype to a bandstop filter.

        Return an analog band-stop filter with center frequency `wo` and
        bandwidth `bw` from an analog low-pass filter prototype with unity
        cutoff frequency, in transfer function ('ba') representation.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        wo : float
            Desired stopband center, as angular frequency (e.g., rad/s).
            Defaults to no change.
        bw : float
            Desired stopband width, as angular frequency (e.g., rad/s).
            Defaults to 1.

        Returns
        -------
        b : array_like
            Numerator polynomial coefficients of the transformed band-stop filter.
        a : array_like
            Denominator polynomial coefficients of the transformed band-stop filter.

        See Also
        --------
        lp2lp, lp2hp, lp2bp, bilinear
        lp2bs_zpk

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s \cdot \mathrm{BW}}{s^2 + {\omega_0}^2}

        This is the "wideband" transformation, producing a stopband with
        geometric (log frequency) symmetry about `wo`.

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> lp = signal.lti([1.0], [1.0, 1.5])
        >>> bs = signal.lti(*signal.lp2bs(lp.num, lp.den))
        >>> w, mag_lp, p_lp = lp.bode()
        >>> w, mag_bs, p_bs = bs.bode(w)
        >>> plt.plot(w, mag_lp, label='Lowpass')
        >>> plt.plot(w, mag_bs, label='Bandstop')
        >>> plt.semilogx()
        >>> plt.grid(True)
        >>> plt.xlabel('Frequency [rad/s]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.legend()

    lp2bs_zpk(z, p, k, wo=1.0, bw=1.0)
        Transform a lowpass filter prototype to a bandstop filter.

        Return an analog band-stop filter with center frequency `wo` and
        stopband width `bw` from an analog low-pass filter prototype with unity
        cutoff frequency, using zeros, poles, and gain ('zpk') representation.

        Parameters
        ----------
        z : array_like
            Zeros of the analog filter transfer function.
        p : array_like
            Poles of the analog filter transfer function.
        k : float
            System gain of the analog filter transfer function.
        wo : float
            Desired stopband center, as angular frequency (e.g., rad/s).
            Defaults to no change.
        bw : float
            Desired stopband width, as angular frequency (e.g., rad/s).
            Defaults to 1.

        Returns
        -------
        z : ndarray
            Zeros of the transformed band-stop filter transfer function.
        p : ndarray
            Poles of the transformed band-stop filter transfer function.
        k : float
            System gain of the transformed band-stop filter.

        See Also
        --------
        lp2lp_zpk, lp2hp_zpk, lp2bp_zpk, bilinear
        lp2bs

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s \cdot \mathrm{BW}}{s^2 + {\omega_0}^2}

        This is the "wideband" transformation, producing a stopband with
        geometric (log frequency) symmetry about `wo`.

        .. versionadded:: 1.1.0

        Examples
        --------
        Transform a low-pass filter represented in 'zpk' (Zero-Pole-Gain) form
        into a bandstop filter represented in 'zpk' form, with a center frequency wo and
        bandwidth bw.

        >>> from scipy.signal import lp2bs_zpk
        >>> z   = [             ]
        >>> p   = [ 0.7 ,    -1 ]
        >>> k   = 9
        >>> wo  = 0.5
        >>> bw  = 10
        >>> lp2bs_zpk(z, p, k, wo, bw)
        (   array([0.+0.5j, 0.+0.5j, 0.-0.5j, 0.-0.5j]),
            array([14.2681928 +0.j, -0.02506281+0.j,  0.01752149+0.j, -9.97493719+0.j]),
            -12.857142857142858)

    lp2hp(b, a, wo=1.0)
        Transform a lowpass filter prototype to a highpass filter.

        Return an analog high-pass filter with cutoff frequency `wo`
        from an analog low-pass filter prototype with unity cutoff frequency, in
        transfer function ('ba') representation.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        wo : float
            Desired cutoff, as angular frequency (e.g., rad/s).
            Defaults to no change.

        Returns
        -------
        b : array_like
            Numerator polynomial coefficients of the transformed high-pass filter.
        a : array_like
            Denominator polynomial coefficients of the transformed high-pass filter.

        See Also
        --------
        lp2lp, lp2bp, lp2bs, bilinear
        lp2hp_zpk

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{\omega_0}{s}

        This maintains symmetry of the lowpass and highpass responses on a
        logarithmic scale.

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> lp = signal.lti([1.0], [1.0, 1.0])
        >>> hp = signal.lti(*signal.lp2hp(lp.num, lp.den))
        >>> w, mag_lp, p_lp = lp.bode()
        >>> w, mag_hp, p_hp = hp.bode(w)

        >>> plt.plot(w, mag_lp, label='Lowpass')
        >>> plt.plot(w, mag_hp, label='Highpass')
        >>> plt.semilogx()
        >>> plt.grid(True)
        >>> plt.xlabel('Frequency [rad/s]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.legend()

    lp2hp_zpk(z, p, k, wo=1.0)
        Transform a lowpass filter prototype to a highpass filter.

        Return an analog high-pass filter with cutoff frequency `wo`
        from an analog low-pass filter prototype with unity cutoff frequency,
        using zeros, poles, and gain ('zpk') representation.

        Parameters
        ----------
        z : array_like
            Zeros of the analog filter transfer function.
        p : array_like
            Poles of the analog filter transfer function.
        k : float
            System gain of the analog filter transfer function.
        wo : float
            Desired cutoff, as angular frequency (e.g., rad/s).
            Defaults to no change.

        Returns
        -------
        z : ndarray
            Zeros of the transformed high-pass filter transfer function.
        p : ndarray
            Poles of the transformed high-pass filter transfer function.
        k : float
            System gain of the transformed high-pass filter.

        See Also
        --------
        lp2lp_zpk, lp2bp_zpk, lp2bs_zpk, bilinear
        lp2hp

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{\omega_0}{s}

        This maintains symmetry of the lowpass and highpass responses on a
        logarithmic scale.

        .. versionadded:: 1.1.0

        Examples
        --------
        Use the 'zpk' (Zero-Pole-Gain) representation of a lowpass filter to
        transform it to a highpass filter with a cutoff frequency wo.

        >>> from scipy.signal import lp2hp_zpk
        >>> z   = [ -2 + 3j ,  -0.5 - 0.8j ]
        >>> p   = [ -1      ,  -4          ]
        >>> k   = 10
        >>> wo  = 0.6
        >>> lp2hp_zpk(z, p, k, wo)
        (   array([-0.09230769-0.13846154j, -0.33707865+0.53932584j]),
            array([-0.6 , -0.15]),
            8.5)

    lp2lp(b, a, wo=1.0)
        Transform a lowpass filter prototype to a different frequency.

        Return an analog low-pass filter with cutoff frequency `wo`
        from an analog low-pass filter prototype with unity cutoff frequency, in
        transfer function ('ba') representation.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        wo : float
            Desired cutoff, as angular frequency (e.g. rad/s).
            Defaults to no change.

        Returns
        -------
        b : array_like
            Numerator polynomial coefficients of the transformed low-pass filter.
        a : array_like
            Denominator polynomial coefficients of the transformed low-pass filter.

        See Also
        --------
        lp2hp, lp2bp, lp2bs, bilinear
        lp2lp_zpk

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s}{\omega_0}

        Examples
        --------

        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> lp = signal.lti([1.0], [1.0, 1.0])
        >>> lp2 = signal.lti(*signal.lp2lp(lp.num, lp.den, 2))
        >>> w, mag_lp, p_lp = lp.bode()
        >>> w, mag_lp2, p_lp2 = lp2.bode(w)

        >>> plt.plot(w, mag_lp, label='Lowpass')
        >>> plt.plot(w, mag_lp2, label='Transformed Lowpass')
        >>> plt.semilogx()
        >>> plt.grid(True)
        >>> plt.xlabel('Frequency [rad/s]')
        >>> plt.ylabel('Magnitude [dB]')
        >>> plt.legend()

    lp2lp_zpk(z, p, k, wo=1.0)
        Transform a lowpass filter prototype to a different frequency.

        Return an analog low-pass filter with cutoff frequency `wo`
        from an analog low-pass filter prototype with unity cutoff frequency,
        using zeros, poles, and gain ('zpk') representation.

        Parameters
        ----------
        z : array_like
            Zeros of the analog filter transfer function.
        p : array_like
            Poles of the analog filter transfer function.
        k : float
            System gain of the analog filter transfer function.
        wo : float
            Desired cutoff, as angular frequency (e.g., rad/s).
            Defaults to no change.

        Returns
        -------
        z : ndarray
            Zeros of the transformed low-pass filter transfer function.
        p : ndarray
            Poles of the transformed low-pass filter transfer function.
        k : float
            System gain of the transformed low-pass filter.

        See Also
        --------
        lp2hp_zpk, lp2bp_zpk, lp2bs_zpk, bilinear
        lp2lp

        Notes
        -----
        This is derived from the s-plane substitution

        .. math:: s \rightarrow \frac{s}{\omega_0}

        .. versionadded:: 1.1.0

        Examples
        --------
        Use the 'zpk' (Zero-Pole-Gain) representation of a lowpass filter to
        transform it to a new 'zpk' representation associated with a cutoff frequency wo.

        >>> from scipy.signal import lp2lp_zpk
        >>> z   = [7,   2]
        >>> p   = [5,   13]
        >>> k   = 0.8
        >>> wo  = 0.4
        >>> lp2lp_zpk(z, p, k, wo)
        (   array([2.8, 0.8]), array([2. , 5.2]), 0.8)

    lsim(system, U, T, X0=None, interp=True)
        Simulate output of a continuous-time linear system.

        Parameters
        ----------
        system : an instance of the LTI class or a tuple describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

            * 1: (instance of `lti`)
            * 2: (num, den)
            * 3: (zeros, poles, gain)
            * 4: (A, B, C, D)

        U : array_like
            An input array describing the input at each time `T`
            (interpolation is assumed between given times).  If there are
            multiple inputs, then each column of the rank-2 array
            represents an input.  If U = 0 or None, a zero input is used.
        T : array_like
            The time steps at which the input is defined and at which the
            output is desired.  Must be nonnegative, increasing, and equally spaced.
        X0 : array_like, optional
            The initial conditions on the state vector (zero by default).
        interp : bool, optional
            Whether to use linear (True, the default) or zero-order-hold (False)
            interpolation for the input array.

        Returns
        -------
        T : 1D ndarray
            Time values for the output.
        yout : 1D ndarray
            System response.
        xout : ndarray
            Time evolution of the state vector.

        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``).

        Examples
        --------
        We'll use `lsim` to simulate an analog Bessel filter applied to
        a signal.

        >>> import numpy as np
        >>> from scipy.signal import bessel, lsim
        >>> import matplotlib.pyplot as plt

        Create a low-pass Bessel filter with a cutoff of 12 Hz.

        >>> b, a = bessel(N=5, Wn=2*np.pi*12, btype='lowpass', analog=True)

        Generate data to which the filter is applied.

        >>> t = np.linspace(0, 1.25, 500, endpoint=False)

        The input signal is the sum of three sinusoidal curves, with
        frequencies 4 Hz, 40 Hz, and 80 Hz.  The filter should mostly
        eliminate the 40 Hz and 80 Hz components, leaving just the 4 Hz signal.

        >>> u = (np.cos(2*np.pi*4*t) + 0.6*np.sin(2*np.pi*40*t) +
        ...      0.5*np.cos(2*np.pi*80*t))

        Simulate the filter with `lsim`.

        >>> tout, yout, xout = lsim((b, a), U=u, T=t)

        Plot the result.

        >>> plt.plot(t, u, 'r', alpha=0.5, linewidth=1, label='input')
        >>> plt.plot(tout, yout, 'k', linewidth=1.5, label='output')
        >>> plt.legend(loc='best', shadow=True, framealpha=1)
        >>> plt.grid(alpha=0.3)
        >>> plt.xlabel('t')
        >>> plt.show()

        In a second example, we simulate a double integrator ``y'' = u``, with
        a constant input ``u = 1``.  We'll use the state space representation
        of the integrator.

        >>> from scipy.signal import lti
        >>> A = np.array([[0.0, 1.0], [0.0, 0.0]])
        >>> B = np.array([[0.0], [1.0]])
        >>> C = np.array([[1.0, 0.0]])
        >>> D = 0.0
        >>> system = lti(A, B, C, D)

        `t` and `u` define the time and input signal for the system to
        be simulated.

        >>> t = np.linspace(0, 5, num=50)
        >>> u = np.ones_like(t)

        Compute the simulation, and then plot `y`.  As expected, the plot shows
        the curve ``y = 0.5*t**2``.

        >>> tout, y, x = lsim(system, u, t)
        >>> plt.plot(t, y)
        >>> plt.grid(alpha=0.3)
        >>> plt.xlabel('t')
        >>> plt.show()

    max_len_seq(nbits, state=None, length=None, taps=None)
        Maximum length sequence (MLS) generator.

        Parameters
        ----------
        nbits : int
            Number of bits to use. Length of the resulting sequence will
            be ``(2**nbits) - 1``. Note that generating long sequences
            (e.g., greater than ``nbits == 16``) can take a long time.
        state : array_like, optional
            If array, must be of length ``nbits``, and will be cast to binary
            (bool) representation. If None, a seed of ones will be used,
            producing a repeatable representation. If ``state`` is all
            zeros, an error is raised as this is invalid. Default: None.
        length : int, optional
            Number of samples to compute. If None, the entire length
            ``(2**nbits) - 1`` is computed.
        taps : array_like, optional
            Polynomial taps to use (e.g., ``[7, 6, 1]`` for an 8-bit sequence).
            If None, taps will be automatically selected (for up to
            ``nbits == 32``).

        Returns
        -------
        seq : array
            Resulting MLS sequence of 0's and 1's.
        state : array
            The final state of the shift register.

        Notes
        -----
        The algorithm for MLS generation is generically described in:

            https://en.wikipedia.org/wiki/Maximum_length_sequence

        The default values for taps are specifically taken from the first
        option listed for each value of ``nbits`` in:

            https://web.archive.org/web/20181001062252/http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm

        .. versionadded:: 0.15.0

        Examples
        --------
        MLS uses binary convention:

        >>> from scipy.signal import max_len_seq
        >>> max_len_seq(4)[0]
        array([1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0], dtype=int8)

        MLS has a white spectrum (except for DC):

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from numpy.fft import fft, ifft, fftshift, fftfreq
        >>> seq = max_len_seq(6)[0]*2-1  # +1 and -1
        >>> spec = fft(seq)
        >>> N = len(seq)
        >>> plt.plot(fftshift(fftfreq(N)), fftshift(np.abs(spec)), '.-')
        >>> plt.margins(0.1, 0.1)
        >>> plt.grid(True)
        >>> plt.show()

        Circular autocorrelation of MLS is an impulse:

        >>> acorrcirc = ifft(spec * np.conj(spec)).real
        >>> plt.figure()
        >>> plt.plot(np.arange(-N/2+1, N/2+1), fftshift(acorrcirc), '.-')
        >>> plt.margins(0.1, 0.1)
        >>> plt.grid(True)
        >>> plt.show()

        Linear autocorrelation of MLS is approximately an impulse:

        >>> acorr = np.correlate(seq, seq, 'full')
        >>> plt.figure()
        >>> plt.plot(np.arange(-N+1, N), acorr, '.-')
        >>> plt.margins(0.1, 0.1)
        >>> plt.grid(True)
        >>> plt.show()

    medfilt(volume, kernel_size=None)
        Perform a median filter on an N-dimensional array.

        Apply a median filter to the input array using a local window-size
        given by `kernel_size`. The array will automatically be zero-padded.

        Parameters
        ----------
        volume : array_like
            An N-dimensional input array.
        kernel_size : array_like, optional
            A scalar or an N-length list giving the size of the median filter
            window in each dimension.  Elements of `kernel_size` should be odd.
            If `kernel_size` is a scalar, then this scalar is used as the size in
            each dimension. Default size is 3 for each dimension.

        Returns
        -------
        out : ndarray
            An array the same size as input containing the median filtered
            result.

        Warns
        -----
        UserWarning
            If array size is smaller than kernel size along any dimension

        See Also
        --------
        scipy.ndimage.median_filter
        scipy.signal.medfilt2d

        Notes
        -----
        The more general function `scipy.ndimage.median_filter` has a more
        efficient implementation of a median filter and therefore runs much faster.

        For 2-dimensional images with ``uint8``, ``float32`` or ``float64`` dtypes,
        the specialised function `scipy.signal.medfilt2d` may be faster.

    medfilt2d(input, kernel_size=3)
        Median filter a 2-dimensional array.

        Apply a median filter to the `input` array using a local window-size
        given by `kernel_size` (must be odd). The array is zero-padded
        automatically.

        Parameters
        ----------
        input : array_like
            A 2-dimensional input array.
        kernel_size : array_like, optional
            A scalar or a list of length 2, giving the size of the
            median filter window in each dimension.  Elements of
            `kernel_size` should be odd.  If `kernel_size` is a scalar,
            then this scalar is used as the size in each dimension.
            Default is a kernel of size (3, 3).

        Returns
        -------
        out : ndarray
            An array the same size as input containing the median filtered
            result.

        See Also
        --------
        scipy.ndimage.median_filter

        Notes
        -----
        This is faster than `medfilt` when the input dtype is ``uint8``,
        ``float32``, or ``float64``; for other types, this falls back to
        `medfilt`. In some situations, `scipy.ndimage.median_filter` may be
        faster than this function.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> x = np.arange(25).reshape(5, 5)
        >>> x
        array([[ 0,  1,  2,  3,  4],
               [ 5,  6,  7,  8,  9],
               [10, 11, 12, 13, 14],
               [15, 16, 17, 18, 19],
               [20, 21, 22, 23, 24]])

        # Replaces i,j with the median out of 5*5 window

        >>> signal.medfilt2d(x, kernel_size=5)
        array([[ 0,  0,  2,  0,  0],
               [ 0,  3,  7,  4,  0],
               [ 2,  8, 12,  9,  4],
               [ 0,  8, 12,  9,  0],
               [ 0,  0, 12,  0,  0]])

        # Replaces i,j with the median out of default 3*3 window

        >>> signal.medfilt2d(x)
        array([[ 0,  1,  2,  3,  0],
               [ 1,  6,  7,  8,  4],
               [ 6, 11, 12, 13,  9],
               [11, 16, 17, 18, 14],
               [ 0, 16, 17, 18,  0]])

        # Replaces i,j with the median out of default 5*3 window

        >>> signal.medfilt2d(x, kernel_size=[5,3])
        array([[ 0,  1,  2,  3,  0],
               [ 0,  6,  7,  8,  3],
               [ 5, 11, 12, 13,  8],
               [ 5, 11, 12, 13,  8],
               [ 0, 11, 12, 13,  0]])

        # Replaces i,j with the median out of default 3*5 window

        >>> signal.medfilt2d(x, kernel_size=[3,5])
        array([[ 0,  0,  2,  1,  0],
               [ 1,  5,  7,  6,  3],
               [ 6, 10, 12, 11,  8],
               [11, 15, 17, 16, 13],
               [ 0, 15, 17, 16,  0]])

        # As seen in the examples,
        # kernel numbers must be odd and not exceed original array dim

    minimum_phase(h: numpy.ndarray, method: Literal['homomorphic', 'hilbert'] = 'homomorphic', n_fft: Optional[int] = None, *, half: bool = True) -> numpy.ndarray
        Convert a linear-phase FIR filter to minimum phase

        Parameters
        ----------
        h : array
            Linear-phase FIR filter coefficients.
        method : {'hilbert', 'homomorphic'}
            The provided methods are:

                'homomorphic' (default)
                    This method [4]_ [5]_ works best with filters with an
                    odd number of taps, and the resulting minimum phase filter
                    will have a magnitude response that approximates the square
                    root of the original filter's magnitude response using half
                    the number of taps when ``half=True`` (default), or the
                    original magnitude spectrum using the same number of taps
                    when ``half=False``.

                'hilbert'
                    This method [1]_ is designed to be used with equiripple
                    filters (e.g., from `remez`) with unity or zero gain
                    regions.

        n_fft : int
            The number of points to use for the FFT. Should be at least a
            few times larger than the signal length (see Notes).
        half : bool
            If ``True``, create a filter that is half the length of the original, with a
            magnitude spectrum that is the square root of the original. If ``False``,
            create a filter that is the same length as the original, with a magnitude
            spectrum that is designed to match the original (only supported when
            ``method='homomorphic'``).

            .. versionadded:: 1.14.0

        Returns
        -------
        h_minimum : array
            The minimum-phase version of the filter, with length
            ``(len(h) + 1) // 2`` when ``half is True`` or ``len(h)`` otherwise.

        See Also
        --------
        firwin
        firwin2
        remez

        Notes
        -----
        Both the Hilbert [1]_ or homomorphic [4]_ [5]_ methods require selection
        of an FFT length to estimate the complex cepstrum of the filter.

        In the case of the Hilbert method, the deviation from the ideal
        spectrum ``epsilon`` is related to the number of stopband zeros
        ``n_stop`` and FFT length ``n_fft`` as::

            epsilon = 2. * n_stop / n_fft

        For example, with 100 stopband zeros and a FFT length of 2048,
        ``epsilon = 0.0976``. If we conservatively assume that the number of
        stopband zeros is one less than the filter length, we can take the FFT
        length to be the next power of 2 that satisfies ``epsilon=0.01`` as::

            n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01)))

        This gives reasonable results for both the Hilbert and homomorphic
        methods, and gives the value used when ``n_fft=None``.

        Alternative implementations exist for creating minimum-phase filters,
        including zero inversion [2]_ and spectral factorization [3]_ [4]_.
        For more information, see `this DSPGuru page
        <http://dspguru.com/dsp/howtos/how-to-design-minimum-phase-fir-filters>`__.

        References
        ----------
        .. [1] N. Damera-Venkata and B. L. Evans, "Optimal design of real and
               complex minimum phase digital FIR filters," Acoustics, Speech,
               and Signal Processing, 1999. Proceedings., 1999 IEEE International
               Conference on, Phoenix, AZ, 1999, pp. 1145-1148 vol.3.
               :doi:`10.1109/ICASSP.1999.756179`
        .. [2] X. Chen and T. W. Parks, "Design of optimal minimum phase FIR
               filters by direct factorization," Signal Processing,
               vol. 10, no. 4, pp. 369-383, Jun. 1986.
        .. [3] T. Saramaki, "Finite Impulse Response Filter Design," in
               Handbook for Digital Signal Processing, chapter 4,
               New York: Wiley-Interscience, 1993.
        .. [4] J. S. Lim, Advanced Topics in Signal Processing.
               Englewood Cliffs, N.J.: Prentice Hall, 1988.
        .. [5] A. V. Oppenheim, R. W. Schafer, and J. R. Buck,
               "Discrete-Time Signal Processing," 3rd edition.
               Upper Saddle River, N.J.: Pearson, 2009.

        Examples
        --------
        Create an optimal linear-phase low-pass filter `h` with a transition band of
        [0.2, 0.3] (assuming a Nyquist frequency of 1):

        >>> import numpy as np
        >>> from scipy.signal import remez, minimum_phase, freqz, group_delay
        >>> import matplotlib.pyplot as plt
        >>> freq = [0, 0.2, 0.3, 1.0]
        >>> desired = [1, 0]
        >>> h_linear = remez(151, freq, desired, fs=2)

        Convert it to minimum phase:

        >>> h_hil = minimum_phase(h_linear, method='hilbert')
        >>> h_hom = minimum_phase(h_linear, method='homomorphic')
        >>> h_hom_full = minimum_phase(h_linear, method='homomorphic', half=False)

        Compare the impulse and frequency response of the four filters:

        >>> fig0, ax0 = plt.subplots(figsize=(6, 3), tight_layout=True)
        >>> fig1, axs = plt.subplots(3, sharex='all', figsize=(6, 6), tight_layout=True)
        >>> ax0.set_title("Impulse response")
        >>> ax0.set(xlabel='Samples', ylabel='Amplitude', xlim=(0, len(h_linear) - 1))
        >>> axs[0].set_title("Frequency Response")
        >>> axs[0].set(xlim=(0, .65), ylabel="Magnitude / dB")
        >>> axs[1].set(ylabel="Phase / rad")
        >>> axs[2].set(ylabel="Group Delay / samples", ylim=(-31, 81),
        ...             xlabel='Normalized Frequency (Nyqist frequency: 1)')
        >>> for h, lb in ((h_linear,   f'Linear ({len(h_linear)})'),
        ...               (h_hil,      f'Min-Hilbert ({len(h_hil)})'),
        ...               (h_hom,      f'Min-Homomorphic ({len(h_hom)})'),
        ...               (h_hom_full, f'Min-Homom. Full ({len(h_hom_full)})')):
        ...     w_H, H = freqz(h, fs=2)
        ...     w_gd, gd = group_delay((h, 1), fs=2)
        ...
        ...     alpha = 1.0 if lb == 'linear' else 0.5  # full opacity for 'linear' line
        ...     ax0.plot(h, '.-', alpha=alpha, label=lb)
        ...     axs[0].plot(w_H, 20 * np.log10(np.abs(H)), alpha=alpha)
        ...     axs[1].plot(w_H, np.unwrap(np.angle(H)), alpha=alpha, label=lb)
        ...     axs[2].plot(w_gd, gd, alpha=alpha)
        >>> ax0.grid(True)
        >>> ax0.legend(title='Filter Phase (Order)')
        >>> axs[1].legend(title='Filter Phase (Order)', loc='lower right')
        >>> for ax_ in axs:  # shade transition band:
        ...     ax_.axvspan(freq[1], freq[2], color='y', alpha=.25)
        ...     ax_.grid(True)
        >>> plt.show()

        The impulse response and group delay plot depict the 75 sample delay of the linear
        phase filter `h`. The phase should also be linear in the stop band--due to the small
        magnitude, numeric noise dominates there. Furthermore, the plots show that the
        minimum phase filters clearly show a reduced (negative) phase slope in the pass and
        transition band. The plots also illustrate that the filter with parameters
        ``method='homomorphic', half=False`` has same order and magnitude response as the
        linear filter `h` wheras the other minimum phase filters have only half the order
        and the square root  of the magnitude response.

    morlet(M, w=5.0, s=1.0, complete=True)
        Complex Morlet wavelet.

        .. deprecated:: 1.12.0

            scipy.signal.morlet is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        Parameters
        ----------
        M : int
            Length of the wavelet.
        w : float, optional
            Omega0. Default is 5
        s : float, optional
            Scaling factor, windowed from ``-s*2*pi`` to ``+s*2*pi``. Default is 1.
        complete : bool, optional
            Whether to use the complete or the standard version.

        Returns
        -------
        morlet : (M,) ndarray

        See Also
        --------
        morlet2 : Implementation of Morlet wavelet, compatible with `cwt`.
        scipy.signal.gausspulse

        Notes
        -----
        The standard version::

            pi**-0.25 * exp(1j*w*x) * exp(-0.5*(x**2))

        This commonly used wavelet is often referred to simply as the
        Morlet wavelet.  Note that this simplified version can cause
        admissibility problems at low values of `w`.

        The complete version::

            pi**-0.25 * (exp(1j*w*x) - exp(-0.5*(w**2))) * exp(-0.5*(x**2))

        This version has a correction
        term to improve admissibility. For `w` greater than 5, the
        correction term is negligible.

        Note that the energy of the return wavelet is not normalised
        according to `s`.

        The fundamental frequency of this wavelet in Hz is given
        by ``f = 2*s*w*r / M`` where `r` is the sampling rate.

        Note: This function was created before `cwt` and is not compatible
        with it.

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> M = 100
        >>> s = 4.0
        >>> w = 2.0
        >>> wavelet = signal.morlet(M, s, w)
        >>> plt.plot(wavelet.real, label="real")
        >>> plt.plot(wavelet.imag, label="imag")
        >>> plt.legend()
        >>> plt.show()

    morlet2(M, s, w=5)
        Complex Morlet wavelet, designed to work with `cwt`.

        .. deprecated:: 1.12.0

            scipy.signal.morlet2 is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        Returns the complete version of morlet wavelet, normalised
        according to `s`::

            exp(1j*w*x/s) * exp(-0.5*(x/s)**2) * pi**(-0.25) * sqrt(1/s)

        Parameters
        ----------
        M : int
            Length of the wavelet.
        s : float
            Width parameter of the wavelet.
        w : float, optional
            Omega0. Default is 5

        Returns
        -------
        morlet : (M,) ndarray

        See Also
        --------
        morlet : Implementation of Morlet wavelet, incompatible with `cwt`

        Notes
        -----

        .. versionadded:: 1.4.0

        This function was designed to work with `cwt`. Because `morlet2`
        returns an array of complex numbers, the `dtype` argument of `cwt`
        should be set to `complex128` for best results.

        Note the difference in implementation with `morlet`.
        The fundamental frequency of this wavelet in Hz is given by::

            f = w*fs / (2*s*np.pi)

        where ``fs`` is the sampling rate and `s` is the wavelet width parameter.
        Similarly we can get the wavelet width parameter at ``f``::

            s = w*fs / (2*f*np.pi)

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> M = 100
        >>> s = 4.0
        >>> w = 2.0
        >>> wavelet = signal.morlet2(M, s, w)
        >>> plt.plot(abs(wavelet))
        >>> plt.show()

        This example shows basic use of `morlet2` with `cwt` in time-frequency
        analysis:

        >>> t, dt = np.linspace(0, 1, 200, retstep=True)
        >>> fs = 1/dt
        >>> w = 6.
        >>> sig = np.cos(2*np.pi*(50 + 10*t)*t) + np.sin(40*np.pi*t)
        >>> freq = np.linspace(1, fs/2, 100)
        >>> widths = w*fs / (2*freq*np.pi)
        >>> cwtm = signal.cwt(sig, signal.morlet2, widths, w=w)
        >>> plt.pcolormesh(t, freq, np.abs(cwtm), cmap='viridis', shading='gouraud')
        >>> plt.show()

    normalize(b, a)
        Normalize numerator/denominator of a continuous-time transfer function.

        If values of `b` are too close to 0, they are removed. In that case, a
        BadCoefficients warning is emitted.

        Parameters
        ----------
        b: array_like
            Numerator of the transfer function. Can be a 2-D array to normalize
            multiple transfer functions.
        a: array_like
            Denominator of the transfer function. At most 1-D.

        Returns
        -------
        num: array
            The numerator of the normalized transfer function. At least a 1-D
            array. A 2-D array if the input `num` is a 2-D array.
        den: 1-D array
            The denominator of the normalized transfer function.

        Notes
        -----
        Coefficients for both the numerator and denominator should be specified in
        descending exponent order (e.g., ``s^2 + 3s + 5`` would be represented as
        ``[1, 3, 5]``).

        Examples
        --------
        >>> from scipy.signal import normalize

        Normalize the coefficients of the transfer function
        ``(3*s^2 - 2*s + 5) / (2*s^2 + 3*s + 1)``:

        >>> b = [3, -2, 5]
        >>> a = [2, 3, 1]
        >>> normalize(b, a)
        (array([ 1.5, -1. ,  2.5]), array([1. , 1.5, 0.5]))

        A warning is generated if, for example, the first coefficient of
        `b` is 0.  In the following example, the result is as expected:

        >>> import warnings
        >>> with warnings.catch_warnings(record=True) as w:
        ...     num, den = normalize([0, 3, 6], [2, -5, 4])

        >>> num
        array([1.5, 3. ])
        >>> den
        array([ 1. , -2.5,  2. ])

        >>> print(w[0].message)
        Badly conditioned filter coefficients (numerator): the results may be meaningless

    oaconvolve(in1, in2, mode='full', axes=None)
        Convolve two N-dimensional arrays using the overlap-add method.

        Convolve `in1` and `in2` using the overlap-add method, with
        the output size determined by the `mode` argument.

        This is generally much faster than `convolve` for large arrays (n > ~500),
        and generally much faster than `fftconvolve` when one array is much
        larger than the other, but can be slower when only a few output values are
        needed or when the arrays are very similar in shape, and can only
        output float arrays (int or object array inputs will be cast to float).

        Parameters
        ----------
        in1 : array_like
            First input.
        in2 : array_like
            Second input. Should have the same number of dimensions as `in1`.
        mode : str {'full', 'valid', 'same'}, optional
            A string indicating the size of the output:

            ``full``
               The output is the full discrete linear convolution
               of the inputs. (Default)
            ``valid``
               The output consists only of those elements that do not
               rely on the zero-padding. In 'valid' mode, either `in1` or `in2`
               must be at least as large as the other in every dimension.
            ``same``
               The output is the same size as `in1`, centered
               with respect to the 'full' output.
        axes : int or array_like of ints or None, optional
            Axes over which to compute the convolution.
            The default is over all axes.

        Returns
        -------
        out : array
            An N-dimensional array containing a subset of the discrete linear
            convolution of `in1` with `in2`.

        See Also
        --------
        convolve : Uses the direct convolution or FFT convolution algorithm
                   depending on which is faster.
        fftconvolve : An implementation of convolution using FFT.

        Notes
        -----
        .. versionadded:: 1.4.0

        References
        ----------
        .. [1] Wikipedia, "Overlap-add_method".
               https://en.wikipedia.org/wiki/Overlap-add_method
        .. [2] Richard G. Lyons. Understanding Digital Signal Processing,
               Third Edition, 2011. Chapter 13.10.
               ISBN 13: 978-0137-02741-5

        Examples
        --------
        Convolve a 100,000 sample signal with a 512-sample filter.

        >>> import numpy as np
        >>> from scipy import signal
        >>> rng = np.random.default_rng()
        >>> sig = rng.standard_normal(100000)
        >>> filt = signal.firwin(512, 0.01)
        >>> fsig = signal.oaconvolve(sig, filt)

        >>> import matplotlib.pyplot as plt
        >>> fig, (ax_orig, ax_mag) = plt.subplots(2, 1)
        >>> ax_orig.plot(sig)
        >>> ax_orig.set_title('White noise')
        >>> ax_mag.plot(fsig)
        >>> ax_mag.set_title('Filtered noise')
        >>> fig.tight_layout()
        >>> fig.show()

    order_filter(a, domain, rank)
        Perform an order filter on an N-D array.

        Perform an order filter on the array in. The domain argument acts as a
        mask centered over each pixel. The non-zero elements of domain are
        used to select elements surrounding each input pixel which are placed
        in a list. The list is sorted, and the output for that pixel is the
        element corresponding to rank in the sorted list.

        Parameters
        ----------
        a : ndarray
            The N-dimensional input array.
        domain : array_like
            A mask array with the same number of dimensions as `a`.
            Each dimension should have an odd number of elements.
        rank : int
            A non-negative integer which selects the element from the
            sorted list (0 corresponds to the smallest element, 1 is the
            next smallest element, etc.).

        Returns
        -------
        out : ndarray
            The results of the order filter in an array with the same
            shape as `a`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> x = np.arange(25).reshape(5, 5)
        >>> domain = np.identity(3)
        >>> x
        array([[ 0,  1,  2,  3,  4],
               [ 5,  6,  7,  8,  9],
               [10, 11, 12, 13, 14],
               [15, 16, 17, 18, 19],
               [20, 21, 22, 23, 24]])
        >>> signal.order_filter(x, domain, 0)
        array([[  0.,   0.,   0.,   0.,   0.],
               [  0.,   0.,   1.,   2.,   0.],
               [  0.,   5.,   6.,   7.,   0.],
               [  0.,  10.,  11.,  12.,   0.],
               [  0.,   0.,   0.,   0.,   0.]])
        >>> signal.order_filter(x, domain, 2)
        array([[  6.,   7.,   8.,   9.,   4.],
               [ 11.,  12.,  13.,  14.,   9.],
               [ 16.,  17.,  18.,  19.,  14.],
               [ 21.,  22.,  23.,  24.,  19.],
               [ 20.,  21.,  22.,  23.,  24.]])

    peak_prominences(x, peaks, wlen=None)
        Calculate the prominence of each peak in a signal.

        The prominence of a peak measures how much a peak stands out from the
        surrounding baseline of the signal and is defined as the vertical distance
        between the peak and its lowest contour line.

        Parameters
        ----------
        x : sequence
            A signal with peaks.
        peaks : sequence
            Indices of peaks in `x`.
        wlen : int, optional
            A window length in samples that optionally limits the evaluated area for
            each peak to a subset of `x`. The peak is always placed in the middle of
            the window therefore the given length is rounded up to the next odd
            integer. This parameter can speed up the calculation (see Notes).

        Returns
        -------
        prominences : ndarray
            The calculated prominences for each peak in `peaks`.
        left_bases, right_bases : ndarray
            The peaks' bases as indices in `x` to the left and right of each peak.
            The higher base of each pair is a peak's lowest contour line.

        Raises
        ------
        ValueError
            If a value in `peaks` is an invalid index for `x`.

        Warns
        -----
        PeakPropertyWarning
            For indices in `peaks` that don't point to valid local maxima in `x`,
            the returned prominence will be 0 and this warning is raised. This
            also happens if `wlen` is smaller than the plateau size of a peak.

        Warnings
        --------
        This function may return unexpected results for data containing NaNs. To
        avoid this, NaNs should either be removed or replaced.

        See Also
        --------
        find_peaks
            Find peaks inside a signal based on peak properties.
        peak_widths
            Calculate the width of peaks.

        Notes
        -----
        Strategy to compute a peak's prominence:

        1. Extend a horizontal line from the current peak to the left and right
           until the line either reaches the window border (see `wlen`) or
           intersects the signal again at the slope of a higher peak. An
           intersection with a peak of the same height is ignored.
        2. On each side find the minimal signal value within the interval defined
           above. These points are the peak's bases.
        3. The higher one of the two bases marks the peak's lowest contour line. The
           prominence can then be calculated as the vertical difference between the
           peaks height itself and its lowest contour line.

        Searching for the peak's bases can be slow for large `x` with periodic
        behavior because large chunks or even the full signal need to be evaluated
        for the first algorithmic step. This evaluation area can be limited with the
        parameter `wlen` which restricts the algorithm to a window around the
        current peak and can shorten the calculation time if the window length is
        short in relation to `x`.
        However, this may stop the algorithm from finding the true global contour
        line if the peak's true bases are outside this window. Instead, a higher
        contour line is found within the restricted window leading to a smaller
        calculated prominence. In practice, this is only relevant for the highest set
        of peaks in `x`. This behavior may even be used intentionally to calculate
        "local" prominences.

        .. versionadded:: 1.1.0

        References
        ----------
        .. [1] Wikipedia Article for Topographic Prominence:
           https://en.wikipedia.org/wiki/Topographic_prominence

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import find_peaks, peak_prominences
        >>> import matplotlib.pyplot as plt

        Create a test signal with two overlaid harmonics

        >>> x = np.linspace(0, 6 * np.pi, 1000)
        >>> x = np.sin(x) + 0.6 * np.sin(2.6 * x)

        Find all peaks and calculate prominences

        >>> peaks, _ = find_peaks(x)
        >>> prominences = peak_prominences(x, peaks)[0]
        >>> prominences
        array([1.24159486, 0.47840168, 0.28470524, 3.10716793, 0.284603  ,
               0.47822491, 2.48340261, 0.47822491])

        Calculate the height of each peak's contour line and plot the results

        >>> contour_heights = x[peaks] - prominences
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.vlines(x=peaks, ymin=contour_heights, ymax=x[peaks])
        >>> plt.show()

        Let's evaluate a second example that demonstrates several edge cases for
        one peak at index 5.

        >>> x = np.array([0, 1, 0, 3, 1, 3, 0, 4, 0])
        >>> peaks = np.array([5])
        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.show()
        >>> peak_prominences(x, peaks)  # -> (prominences, left_bases, right_bases)
        (array([3.]), array([2]), array([6]))

        Note how the peak at index 3 of the same height is not considered as a
        border while searching for the left base. Instead, two minima at 0 and 2
        are found in which case the one closer to the evaluated peak is always
        chosen. On the right side, however, the base must be placed at 6 because the
        higher peak represents the right border to the evaluated area.

        >>> peak_prominences(x, peaks, wlen=3.1)
        (array([2.]), array([4]), array([6]))

        Here, we restricted the algorithm to a window from 3 to 7 (the length is 5
        samples because `wlen` was rounded up to the next odd integer). Thus, the
        only two candidates in the evaluated area are the two neighboring samples
        and a smaller prominence is calculated.

    peak_widths(x, peaks, rel_height=0.5, prominence_data=None, wlen=None)
        Calculate the width of each peak in a signal.

        This function calculates the width of a peak in samples at a relative
        distance to the peak's height and prominence.

        Parameters
        ----------
        x : sequence
            A signal with peaks.
        peaks : sequence
            Indices of peaks in `x`.
        rel_height : float, optional
            Chooses the relative height at which the peak width is measured as a
            percentage of its prominence. 1.0 calculates the width of the peak at
            its lowest contour line while 0.5 evaluates at half the prominence
            height. Must be at least 0. See notes for further explanation.
        prominence_data : tuple, optional
            A tuple of three arrays matching the output of `peak_prominences` when
            called with the same arguments `x` and `peaks`. This data are calculated
            internally if not provided.
        wlen : int, optional
            A window length in samples passed to `peak_prominences` as an optional
            argument for internal calculation of `prominence_data`. This argument
            is ignored if `prominence_data` is given.

        Returns
        -------
        widths : ndarray
            The widths for each peak in samples.
        width_heights : ndarray
            The height of the contour lines at which the `widths` where evaluated.
        left_ips, right_ips : ndarray
            Interpolated positions of left and right intersection points of a
            horizontal line at the respective evaluation height.

        Raises
        ------
        ValueError
            If `prominence_data` is supplied but doesn't satisfy the condition
            ``0 <= left_base <= peak <= right_base < x.shape[0]`` for each peak,
            has the wrong dtype, is not C-contiguous or does not have the same
            shape.

        Warns
        -----
        PeakPropertyWarning
            Raised if any calculated width is 0. This may stem from the supplied
            `prominence_data` or if `rel_height` is set to 0.

        Warnings
        --------
        This function may return unexpected results for data containing NaNs. To
        avoid this, NaNs should either be removed or replaced.

        See Also
        --------
        find_peaks
            Find peaks inside a signal based on peak properties.
        peak_prominences
            Calculate the prominence of peaks.

        Notes
        -----
        The basic algorithm to calculate a peak's width is as follows:

        * Calculate the evaluation height :math:`h_{eval}` with the formula
          :math:`h_{eval} = h_{Peak} - P \cdot R`, where :math:`h_{Peak}` is the
          height of the peak itself, :math:`P` is the peak's prominence and
          :math:`R` a positive ratio specified with the argument `rel_height`.
        * Draw a horizontal line at the evaluation height to both sides, starting at
          the peak's current vertical position until the lines either intersect a
          slope, the signal border or cross the vertical position of the peak's
          base (see `peak_prominences` for an definition). For the first case,
          intersection with the signal, the true intersection point is estimated
          with linear interpolation.
        * Calculate the width as the horizontal distance between the chosen
          endpoints on both sides. As a consequence of this the maximal possible
          width for each peak is the horizontal distance between its bases.

        As shown above to calculate a peak's width its prominence and bases must be
        known. You can supply these yourself with the argument `prominence_data`.
        Otherwise, they are internally calculated (see `peak_prominences`).

        .. versionadded:: 1.1.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import chirp, find_peaks, peak_widths
        >>> import matplotlib.pyplot as plt

        Create a test signal with two overlaid harmonics

        >>> x = np.linspace(0, 6 * np.pi, 1000)
        >>> x = np.sin(x) + 0.6 * np.sin(2.6 * x)

        Find all peaks and calculate their widths at the relative height of 0.5
        (contour line at half the prominence height) and 1 (at the lowest contour
        line at full prominence height).

        >>> peaks, _ = find_peaks(x)
        >>> results_half = peak_widths(x, peaks, rel_height=0.5)
        >>> results_half[0]  # widths
        array([ 64.25172825,  41.29465463,  35.46943289, 104.71586081,
                35.46729324,  41.30429622, 181.93835853,  45.37078546])
        >>> results_full = peak_widths(x, peaks, rel_height=1)
        >>> results_full[0]  # widths
        array([181.9396084 ,  72.99284945,  61.28657872, 373.84622694,
            61.78404617,  72.48822812, 253.09161876,  79.36860878])

        Plot signal, peaks and contour lines at which the widths where calculated

        >>> plt.plot(x)
        >>> plt.plot(peaks, x[peaks], "x")
        >>> plt.hlines(*results_half[1:], color="C2")
        >>> plt.hlines(*results_full[1:], color="C3")
        >>> plt.show()

    periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1)
        Estimate power spectral density using a periodogram.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` time series. Defaults to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be equal to the length
            of the axis over which the periodogram is computed. Defaults
            to 'boxcar'.
        nfft : int, optional
            Length of the FFT used. If `None` the length of `x` will be
            used.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to 'constant'.
        return_onesided : bool, optional
            If `True`, return a one-sided spectrum for real data. If
            `False` return a two-sided spectrum. Defaults to `True`, but for
            complex data, a two-sided spectrum is always returned.
        scaling : { 'density', 'spectrum' }, optional
            Selects between computing the power spectral density ('density')
            where `Pxx` has units of V**2/Hz and computing the squared magnitude
            spectrum ('spectrum') where `Pxx` has units of V**2, if `x`
            is measured in V and `fs` is measured in Hz. Defaults to
            'density'
        axis : int, optional
            Axis along which the periodogram is computed; the default is
            over the last axis (i.e. ``axis=-1``).

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        Pxx : ndarray
            Power spectral density or power spectrum of `x`.

        See Also
        --------
        welch: Estimate power spectral density using Welch's method
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data

        Notes
        -----
        Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
        for a discussion of the scalings of the power spectral density and
        the magnitude (squared) spectrum.

        .. versionadded:: 0.12.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate a test signal, a 2 Vrms sine wave at 1234 Hz, corrupted by
        0.001 V**2/Hz of white noise sampled at 10 kHz.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 2*np.sqrt(2)
        >>> freq = 1234.0
        >>> noise_power = 0.001 * fs / 2
        >>> time = np.arange(N) / fs
        >>> x = amp*np.sin(2*np.pi*freq*time)
        >>> x += rng.normal(scale=np.sqrt(noise_power), size=time.shape)

        Compute and plot the power spectral density.

        >>> f, Pxx_den = signal.periodogram(x, fs)
        >>> plt.semilogy(f, Pxx_den)
        >>> plt.ylim([1e-7, 1e2])
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('PSD [V**2/Hz]')
        >>> plt.show()

        If we average the last half of the spectral density, to exclude the
        peak, we can recover the noise power on the signal.

        >>> np.mean(Pxx_den[25000:])
        0.000985320699252543

        Now compute and plot the power spectrum.

        >>> f, Pxx_spec = signal.periodogram(x, fs, 'flattop', scaling='spectrum')
        >>> plt.figure()
        >>> plt.semilogy(f, np.sqrt(Pxx_spec))
        >>> plt.ylim([1e-4, 1e1])
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('Linear spectrum [V RMS]')
        >>> plt.show()

        The peak height in the power spectrum is an estimate of the RMS
        amplitude.

        >>> np.sqrt(Pxx_spec.max())
        2.0077340678640727

    place_poles(A, B, poles, method='YT', rtol=0.001, maxiter=30)
        Compute K such that eigenvalues (A - dot(B, K))=poles.

        K is the gain matrix such as the plant described by the linear system
        ``AX+BU`` will have its closed-loop poles, i.e the eigenvalues ``A - B*K``,
        as close as possible to those asked for in poles.

        SISO, MISO and MIMO systems are supported.

        Parameters
        ----------
        A, B : ndarray
            State-space representation of linear system ``AX + BU``.
        poles : array_like
            Desired real poles and/or complex conjugates poles.
            Complex poles are only supported with ``method="YT"`` (default).
        method: {'YT', 'KNV0'}, optional
            Which method to choose to find the gain matrix K. One of:

                - 'YT': Yang Tits
                - 'KNV0': Kautsky, Nichols, Van Dooren update method 0

            See References and Notes for details on the algorithms.
        rtol: float, optional
            After each iteration the determinant of the eigenvectors of
            ``A - B*K`` is compared to its previous value, when the relative
            error between these two values becomes lower than `rtol` the algorithm
            stops.  Default is 1e-3.
        maxiter: int, optional
            Maximum number of iterations to compute the gain matrix.
            Default is 30.

        Returns
        -------
        full_state_feedback : Bunch object
            full_state_feedback is composed of:
                gain_matrix : 1-D ndarray
                    The closed loop matrix K such as the eigenvalues of ``A-BK``
                    are as close as possible to the requested poles.
                computed_poles : 1-D ndarray
                    The poles corresponding to ``A-BK`` sorted as first the real
                    poles in increasing order, then the complex congugates in
                    lexicographic order.
                requested_poles : 1-D ndarray
                    The poles the algorithm was asked to place sorted as above,
                    they may differ from what was achieved.
                X : 2-D ndarray
                    The transfer matrix such as ``X * diag(poles) = (A - B*K)*X``
                    (see Notes)
                rtol : float
                    The relative tolerance achieved on ``det(X)`` (see Notes).
                    `rtol` will be NaN if it is possible to solve the system
                    ``diag(poles) = (A - B*K)``, or 0 when the optimization
                    algorithms can't do anything i.e when ``B.shape[1] == 1``.
                nb_iter : int
                    The number of iterations performed before converging.
                    `nb_iter` will be NaN if it is possible to solve the system
                    ``diag(poles) = (A - B*K)``, or 0 when the optimization
                    algorithms can't do anything i.e when ``B.shape[1] == 1``.

        Notes
        -----
        The Tits and Yang (YT), [2]_ paper is an update of the original Kautsky et
        al. (KNV) paper [1]_.  KNV relies on rank-1 updates to find the transfer
        matrix X such that ``X * diag(poles) = (A - B*K)*X``, whereas YT uses
        rank-2 updates. This yields on average more robust solutions (see [2]_
        pp 21-22), furthermore the YT algorithm supports complex poles whereas KNV
        does not in its original version.  Only update method 0 proposed by KNV has
        been implemented here, hence the name ``'KNV0'``.

        KNV extended to complex poles is used in Matlab's ``place`` function, YT is
        distributed under a non-free licence by Slicot under the name ``robpole``.
        It is unclear and undocumented how KNV0 has been extended to complex poles
        (Tits and Yang claim on page 14 of their paper that their method can not be
        used to extend KNV to complex poles), therefore only YT supports them in
        this implementation.

        As the solution to the problem of pole placement is not unique for MIMO
        systems, both methods start with a tentative transfer matrix which is
        altered in various way to increase its determinant.  Both methods have been
        proven to converge to a stable solution, however depending on the way the
        initial transfer matrix is chosen they will converge to different
        solutions and therefore there is absolutely no guarantee that using
        ``'KNV0'`` will yield results similar to Matlab's or any other
        implementation of these algorithms.

        Using the default method ``'YT'`` should be fine in most cases; ``'KNV0'``
        is only provided because it is needed by ``'YT'`` in some specific cases.
        Furthermore ``'YT'`` gives on average more robust results than ``'KNV0'``
        when ``abs(det(X))`` is used as a robustness indicator.

        [2]_ is available as a technical report on the following URL:
        https://hdl.handle.net/1903/5598

        References
        ----------
        .. [1] J. Kautsky, N.K. Nichols and P. van Dooren, "Robust pole assignment
               in linear state feedback", International Journal of Control, Vol. 41
               pp. 1129-1155, 1985.
        .. [2] A.L. Tits and Y. Yang, "Globally convergent algorithms for robust
               pole assignment by state feedback", IEEE Transactions on Automatic
               Control, Vol. 41, pp. 1432-1452, 1996.

        Examples
        --------
        A simple example demonstrating real pole placement using both KNV and YT
        algorithms.  This is example number 1 from section 4 of the reference KNV
        publication ([1]_):

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> A = np.array([[ 1.380,  -0.2077,  6.715, -5.676  ],
        ...               [-0.5814, -4.290,   0,      0.6750 ],
        ...               [ 1.067,   4.273,  -6.654,  5.893  ],
        ...               [ 0.0480,  4.273,   1.343, -2.104  ]])
        >>> B = np.array([[ 0,      5.679 ],
        ...               [ 1.136,  1.136 ],
        ...               [ 0,      0,    ],
        ...               [-3.146,  0     ]])
        >>> P = np.array([-0.2, -0.5, -5.0566, -8.6659])

        Now compute K with KNV method 0, with the default YT method and with the YT
        method while forcing 100 iterations of the algorithm and print some results
        after each call.

        >>> fsf1 = signal.place_poles(A, B, P, method='KNV0')
        >>> fsf1.gain_matrix
        array([[ 0.20071427, -0.96665799,  0.24066128, -0.10279785],
               [ 0.50587268,  0.57779091,  0.51795763, -0.41991442]])

        >>> fsf2 = signal.place_poles(A, B, P)  # uses YT method
        >>> fsf2.computed_poles
        array([-8.6659, -5.0566, -0.5   , -0.2   ])

        >>> fsf3 = signal.place_poles(A, B, P, rtol=-1, maxiter=100)
        >>> fsf3.X
        array([[ 0.52072442+0.j, -0.08409372+0.j, -0.56847937+0.j,  0.74823657+0.j],
               [-0.04977751+0.j, -0.80872954+0.j,  0.13566234+0.j, -0.29322906+0.j],
               [-0.82266932+0.j, -0.19168026+0.j, -0.56348322+0.j, -0.43815060+0.j],
               [ 0.22267347+0.j,  0.54967577+0.j, -0.58387806+0.j, -0.40271926+0.j]])

        The absolute value of the determinant of X is a good indicator to check the
        robustness of the results, both ``'KNV0'`` and ``'YT'`` aim at maximizing
        it.  Below a comparison of the robustness of the results above:

        >>> abs(np.linalg.det(fsf1.X)) < abs(np.linalg.det(fsf2.X))
        True
        >>> abs(np.linalg.det(fsf2.X)) < abs(np.linalg.det(fsf3.X))
        True

        Now a simple example for complex poles:

        >>> A = np.array([[ 0,  7/3.,  0,   0   ],
        ...               [ 0,   0,    0,  7/9. ],
        ...               [ 0,   0,    0,   0   ],
        ...               [ 0,   0,    0,   0   ]])
        >>> B = np.array([[ 0,  0 ],
        ...               [ 0,  0 ],
        ...               [ 1,  0 ],
        ...               [ 0,  1 ]])
        >>> P = np.array([-3, -1, -2-1j, -2+1j]) / 3.
        >>> fsf = signal.place_poles(A, B, P, method='YT')

        We can plot the desired and computed poles in the complex plane:

        >>> t = np.linspace(0, 2*np.pi, 401)
        >>> plt.plot(np.cos(t), np.sin(t), 'k--')  # unit circle
        >>> plt.plot(fsf.requested_poles.real, fsf.requested_poles.imag,
        ...          'wo', label='Desired')
        >>> plt.plot(fsf.computed_poles.real, fsf.computed_poles.imag, 'bx',
        ...          label='Placed')
        >>> plt.grid()
        >>> plt.axis('image')
        >>> plt.axis([-1.1, 1.1, -1.1, 1.1])
        >>> plt.legend(bbox_to_anchor=(1.05, 1), loc=2, numpoints=1)

    qmf(hk)
        Return high-pass qmf filter from low-pass

        .. deprecated:: 1.12.0

            scipy.signal.qmf is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        Parameters
        ----------
        hk : array_like
            Coefficients of high-pass filter.

        Returns
        -------
        array_like
            High-pass filter coefficients.

    qspline1d(signal, lamb=0.0)
        Compute quadratic spline coefficients for rank-1 array.

        Parameters
        ----------
        signal : ndarray
            A rank-1 array representing samples of a signal.
        lamb : float, optional
            Smoothing coefficient (must be zero for now).

        Returns
        -------
        c : ndarray
            Quadratic spline coefficients.

        See Also
        --------
        qspline1d_eval : Evaluate a quadratic spline at the new set of points.

        Notes
        -----
        Find the quadratic spline coefficients for a 1-D signal assuming
        mirror-symmetric boundary conditions. To obtain the signal back from the
        spline representation mirror-symmetric-convolve these coefficients with a
        length 3 FIR window [1.0, 6.0, 1.0]/ 8.0 .

        Examples
        --------
        We can filter a signal to reduce and smooth out high-frequency noise with
        a quadratic spline:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import qspline1d, qspline1d_eval
        >>> rng = np.random.default_rng()
        >>> sig = np.repeat([0., 1., 0.], 100)
        >>> sig += rng.standard_normal(len(sig))*0.05  # add noise
        >>> time = np.linspace(0, len(sig))
        >>> filtered = qspline1d_eval(qspline1d(sig), time)
        >>> plt.plot(sig, label="signal")
        >>> plt.plot(time, filtered, label="filtered")
        >>> plt.legend()
        >>> plt.show()

    qspline1d_eval(cj, newx, dx=1.0, x0=0)
        Evaluate a quadratic spline at the new set of points.

        Parameters
        ----------
        cj : ndarray
            Quadratic spline coefficients
        newx : ndarray
            New set of points.
        dx : float, optional
            Old sample-spacing, the default value is 1.0.
        x0 : int, optional
            Old origin, the default value is 0.

        Returns
        -------
        res : ndarray
            Evaluated a quadratic spline points.

        See Also
        --------
        qspline1d : Compute quadratic spline coefficients for rank-1 array.

        Notes
        -----
        `dx` is the old sample-spacing while `x0` was the old origin. In
        other-words the old-sample points (knot-points) for which the `cj`
        represent spline coefficients were at equally-spaced points of::

          oldx = x0 + j*dx  j=0...N-1, with N=len(cj)

        Edges are handled using mirror-symmetric boundary conditions.

        Examples
        --------
        We can filter a signal to reduce and smooth out high-frequency noise with
        a quadratic spline:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.signal import qspline1d, qspline1d_eval
        >>> rng = np.random.default_rng()
        >>> sig = np.repeat([0., 1., 0.], 100)
        >>> sig += rng.standard_normal(len(sig))*0.05  # add noise
        >>> time = np.linspace(0, len(sig))
        >>> filtered = qspline1d_eval(qspline1d(sig), time)
        >>> plt.plot(sig, label="signal")
        >>> plt.plot(time, filtered, label="filtered")
        >>> plt.legend()
        >>> plt.show()

    qspline2d(...)
        out = qspline2d(input, lambda=0.0, precision=-1.0)

        Coefficients for 2-D quadratic (2nd order) B-spline:

        Return the second-order B-spline coefficients over a regularly spaced
        input grid for the two-dimensional input image.

        Parameters
        ----------
        input : ndarray
            The input signal.
        lambda : float
            Specifies the amount of smoothing in the transfer function.
        precision : float
            Specifies the precision for computing the infinite sum needed to apply mirror-
            symmetric boundary conditions.

        Returns
        -------
        output : ndarray
            The filtered signal.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-signal-bsplines>`.

    remez(numtaps, bands, desired, *, weight=None, type='bandpass', maxiter=25, grid_density=16, fs=None)
        Calculate the minimax optimal filter using the Remez exchange algorithm.

        Calculate the filter-coefficients for the finite impulse response
        (FIR) filter whose transfer function minimizes the maximum error
        between the desired gain and the realized gain in the specified
        frequency bands using the Remez exchange algorithm.

        Parameters
        ----------
        numtaps : int
            The desired number of taps in the filter. The number of taps is
            the number of terms in the filter, or the filter order plus one.
        bands : array_like
            A monotonic sequence containing the band edges.
            All elements must be non-negative and less than half the sampling
            frequency as given by `fs`.
        desired : array_like
            A sequence half the size of bands containing the desired gain
            in each of the specified bands.
        weight : array_like, optional
            A relative weighting to give to each band region. The length of
            `weight` has to be half the length of `bands`.
        type : {'bandpass', 'differentiator', 'hilbert'}, optional
            The type of filter:

              * 'bandpass' : flat response in bands. This is the default.

              * 'differentiator' : frequency proportional response in bands.

              * 'hilbert' : filter with odd symmetry, that is, type III
                            (for even order) or type IV (for odd order)
                            linear phase filters.

        maxiter : int, optional
            Maximum number of iterations of the algorithm. Default is 25.
        grid_density : int, optional
            Grid density. The dense grid used in `remez` is of size
            ``(numtaps + 1) * grid_density``. Default is 16.
        fs : float, optional
            The sampling frequency of the signal.  Default is 1.

        Returns
        -------
        out : ndarray
            A rank-1 array containing the coefficients of the optimal
            (in a minimax sense) filter.

        See Also
        --------
        firls
        firwin
        firwin2
        minimum_phase

        References
        ----------
        .. [1] J. H. McClellan and T. W. Parks, "A unified approach to the
               design of optimum FIR linear phase digital filters",
               IEEE Trans. Circuit Theory, vol. CT-20, pp. 697-701, 1973.
        .. [2] J. H. McClellan, T. W. Parks and L. R. Rabiner, "A Computer
               Program for Designing Optimum FIR Linear Phase Digital
               Filters", IEEE Trans. Audio Electroacoust., vol. AU-21,
               pp. 506-525, 1973.

        Examples
        --------
        In these examples, `remez` is used to design low-pass, high-pass,
        band-pass and band-stop filters.  The parameters that define each filter
        are the filter order, the band boundaries, the transition widths of the
        boundaries, the desired gains in each band, and the sampling frequency.

        We'll use a sample frequency of 22050 Hz in all the examples.  In each
        example, the desired gain in each band is either 0 (for a stop band)
        or 1 (for a pass band).

        `freqz` is used to compute the frequency response of each filter, and
        the utility function ``plot_response`` defined below is used to plot
        the response.

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> fs = 22050   # Sample rate, Hz

        >>> def plot_response(w, h, title):
        ...     "Utility function to plot response functions"
        ...     fig = plt.figure()
        ...     ax = fig.add_subplot(111)
        ...     ax.plot(w, 20*np.log10(np.abs(h)))
        ...     ax.set_ylim(-40, 5)
        ...     ax.grid(True)
        ...     ax.set_xlabel('Frequency (Hz)')
        ...     ax.set_ylabel('Gain (dB)')
        ...     ax.set_title(title)

        The first example is a low-pass filter, with cutoff frequency 8 kHz.
        The filter length is 325, and the transition width from pass to stop
        is 100 Hz.

        >>> cutoff = 8000.0    # Desired cutoff frequency, Hz
        >>> trans_width = 100  # Width of transition from pass to stop, Hz
        >>> numtaps = 325      # Size of the FIR filter.
        >>> taps = signal.remez(numtaps, [0, cutoff, cutoff + trans_width, 0.5*fs],
        ...                     [1, 0], fs=fs)
        >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
        >>> plot_response(w, h, "Low-pass Filter")
        >>> plt.show()

        This example shows a high-pass filter:

        >>> cutoff = 2000.0    # Desired cutoff frequency, Hz
        >>> trans_width = 250  # Width of transition from pass to stop, Hz
        >>> numtaps = 125      # Size of the FIR filter.
        >>> taps = signal.remez(numtaps, [0, cutoff - trans_width, cutoff, 0.5*fs],
        ...                     [0, 1], fs=fs)
        >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
        >>> plot_response(w, h, "High-pass Filter")
        >>> plt.show()

        This example shows a band-pass filter with a pass-band from 2 kHz to
        5 kHz.  The transition width is 260 Hz and the length of the filter
        is 63, which is smaller than in the other examples:

        >>> band = [2000, 5000]  # Desired pass band, Hz
        >>> trans_width = 260    # Width of transition from pass to stop, Hz
        >>> numtaps = 63         # Size of the FIR filter.
        >>> edges = [0, band[0] - trans_width, band[0], band[1],
        ...          band[1] + trans_width, 0.5*fs]
        >>> taps = signal.remez(numtaps, edges, [0, 1, 0], fs=fs)
        >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
        >>> plot_response(w, h, "Band-pass Filter")
        >>> plt.show()

        The low order leads to higher ripple and less steep transitions.

        The next example shows a band-stop filter.

        >>> band = [6000, 8000]  # Desired stop band, Hz
        >>> trans_width = 200    # Width of transition from pass to stop, Hz
        >>> numtaps = 175        # Size of the FIR filter.
        >>> edges = [0, band[0] - trans_width, band[0], band[1],
        ...          band[1] + trans_width, 0.5*fs]
        >>> taps = signal.remez(numtaps, edges, [1, 0, 1], fs=fs)
        >>> w, h = signal.freqz(taps, [1], worN=2000, fs=fs)
        >>> plot_response(w, h, "Band-stop Filter")
        >>> plt.show()

    resample(x, num, t=None, axis=0, window=None, domain='time')
        Resample `x` to `num` samples using Fourier method along the given axis.

        The resampled signal starts at the same value as `x` but is sampled
        with a spacing of ``len(x) / num * (spacing of x)``.  Because a
        Fourier method is used, the signal is assumed to be periodic.

        Parameters
        ----------
        x : array_like
            The data to be resampled.
        num : int
            The number of samples in the resampled signal.
        t : array_like, optional
            If `t` is given, it is assumed to be the equally spaced sample
            positions associated with the signal data in `x`.
        axis : int, optional
            The axis of `x` that is resampled.  Default is 0.
        window : array_like, callable, string, float, or tuple, optional
            Specifies the window applied to the signal in the Fourier
            domain.  See below for details.
        domain : string, optional
            A string indicating the domain of the input `x`:
            ``time`` Consider the input `x` as time-domain (Default),
            ``freq`` Consider the input `x` as frequency-domain.

        Returns
        -------
        resampled_x or (resampled_x, resampled_t)
            Either the resampled array, or, if `t` was given, a tuple
            containing the resampled array and the corresponding resampled
            positions.

        See Also
        --------
        decimate : Downsample the signal after applying an FIR or IIR filter.
        resample_poly : Resample using polyphase filtering and an FIR filter.

        Notes
        -----
        The argument `window` controls a Fourier-domain window that tapers
        the Fourier spectrum before zero-padding to alleviate ringing in
        the resampled values for sampled signals you didn't intend to be
        interpreted as band-limited.

        If `window` is a function, then it is called with a vector of inputs
        indicating the frequency bins (i.e. fftfreq(x.shape[axis]) ).

        If `window` is an array of the same length as `x.shape[axis]` it is
        assumed to be the window to be applied directly in the Fourier
        domain (with dc and low-frequency first).

        For any other type of `window`, the function `scipy.signal.get_window`
        is called to generate the window.

        The first sample of the returned vector is the same as the first
        sample of the input vector.  The spacing between samples is changed
        from ``dx`` to ``dx * len(x) / num``.

        If `t` is not None, then it is used solely to calculate the resampled
        positions `resampled_t`

        As noted, `resample` uses FFT transformations, which can be very
        slow if the number of input or output samples is large and prime;
        see `scipy.fft.fft`.

        Examples
        --------
        Note that the end of the resampled data rises to meet the first
        sample of the next cycle:

        >>> import numpy as np
        >>> from scipy import signal

        >>> x = np.linspace(0, 10, 20, endpoint=False)
        >>> y = np.cos(-x**2/6.0)
        >>> f = signal.resample(y, 100)
        >>> xnew = np.linspace(0, 10, 100, endpoint=False)

        >>> import matplotlib.pyplot as plt
        >>> plt.plot(x, y, 'go-', xnew, f, '.-', 10, y[0], 'ro')
        >>> plt.legend(['data', 'resampled'], loc='best')
        >>> plt.show()

    resample_poly(x, up, down, axis=0, window=('kaiser', 5.0), padtype='constant', cval=None)
        Resample `x` along the given axis using polyphase filtering.

        The signal `x` is upsampled by the factor `up`, a zero-phase low-pass
        FIR filter is applied, and then it is downsampled by the factor `down`.
        The resulting sample rate is ``up / down`` times the original sample
        rate. By default, values beyond the boundary of the signal are assumed
        to be zero during the filtering step.

        Parameters
        ----------
        x : array_like
            The data to be resampled.
        up : int
            The upsampling factor.
        down : int
            The downsampling factor.
        axis : int, optional
            The axis of `x` that is resampled. Default is 0.
        window : string, tuple, or array_like, optional
            Desired window to use to design the low-pass filter, or the FIR filter
            coefficients to employ. See below for details.
        padtype : string, optional
            `constant`, `line`, `mean`, `median`, `maximum`, `minimum` or any of
            the other signal extension modes supported by `scipy.signal.upfirdn`.
            Changes assumptions on values beyond the boundary. If `constant`,
            assumed to be `cval` (default zero). If `line` assumed to continue a
            linear trend defined by the first and last points. `mean`, `median`,
            `maximum` and `minimum` work as in `np.pad` and assume that the values
            beyond the boundary are the mean, median, maximum or minimum
            respectively of the array along the axis.

            .. versionadded:: 1.4.0
        cval : float, optional
            Value to use if `padtype='constant'`. Default is zero.

            .. versionadded:: 1.4.0

        Returns
        -------
        resampled_x : array
            The resampled array.

        See Also
        --------
        decimate : Downsample the signal after applying an FIR or IIR filter.
        resample : Resample up or down using the FFT method.

        Notes
        -----
        This polyphase method will likely be faster than the Fourier method
        in `scipy.signal.resample` when the number of samples is large and
        prime, or when the number of samples is large and `up` and `down`
        share a large greatest common denominator. The length of the FIR
        filter used will depend on ``max(up, down) // gcd(up, down)``, and
        the number of operations during polyphase filtering will depend on
        the filter length and `down` (see `scipy.signal.upfirdn` for details).

        The argument `window` specifies the FIR low-pass filter design.

        If `window` is an array_like it is assumed to be the FIR filter
        coefficients. Note that the FIR filter is applied after the upsampling
        step, so it should be designed to operate on a signal at a sampling
        frequency higher than the original by a factor of `up//gcd(up, down)`.
        This function's output will be centered with respect to this array, so it
        is best to pass a symmetric filter with an odd number of samples if, as
        is usually the case, a zero-phase filter is desired.

        For any other type of `window`, the functions `scipy.signal.get_window`
        and `scipy.signal.firwin` are called to generate the appropriate filter
        coefficients.

        The first sample of the returned vector is the same as the first
        sample of the input vector. The spacing between samples is changed
        from ``dx`` to ``dx * down / float(up)``.

        Examples
        --------
        By default, the end of the resampled data rises to meet the first
        sample of the next cycle for the FFT method, and gets closer to zero
        for the polyphase method:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(0, 10, 20, endpoint=False)
        >>> y = np.cos(-x**2/6.0)
        >>> f_fft = signal.resample(y, 100)
        >>> f_poly = signal.resample_poly(y, 100, 20)
        >>> xnew = np.linspace(0, 10, 100, endpoint=False)

        >>> plt.plot(xnew, f_fft, 'b.-', xnew, f_poly, 'r.-')
        >>> plt.plot(x, y, 'ko-')
        >>> plt.plot(10, y[0], 'bo', 10, 0., 'ro')  # boundaries
        >>> plt.legend(['resample', 'resamp_poly', 'data'], loc='best')
        >>> plt.show()

        This default behaviour can be changed by using the padtype option:

        >>> N = 5
        >>> x = np.linspace(0, 1, N, endpoint=False)
        >>> y = 2 + x**2 - 1.7*np.sin(x) + .2*np.cos(11*x)
        >>> y2 = 1 + x**3 + 0.1*np.sin(x) + .1*np.cos(11*x)
        >>> Y = np.stack([y, y2], axis=-1)
        >>> up = 4
        >>> xr = np.linspace(0, 1, N*up, endpoint=False)

        >>> y2 = signal.resample_poly(Y, up, 1, padtype='constant')
        >>> y3 = signal.resample_poly(Y, up, 1, padtype='mean')
        >>> y4 = signal.resample_poly(Y, up, 1, padtype='line')

        >>> for i in [0,1]:
        ...     plt.figure()
        ...     plt.plot(xr, y4[:,i], 'g.', label='line')
        ...     plt.plot(xr, y3[:,i], 'y.', label='mean')
        ...     plt.plot(xr, y2[:,i], 'r.', label='constant')
        ...     plt.plot(x, Y[:,i], 'k-')
        ...     plt.legend()
        >>> plt.show()

    residue(b, a, tol=0.001, rtype='avg')
        Compute partial-fraction expansion of b(s) / a(s).

        If `M` is the degree of numerator `b` and `N` the degree of denominator
        `a`::

                  b(s)     b[0] s**(M) + b[1] s**(M-1) + ... + b[M]
          H(s) = ------ = ------------------------------------------
                  a(s)     a[0] s**(N) + a[1] s**(N-1) + ... + a[N]

        then the partial-fraction expansion H(s) is defined as::

                   r[0]       r[1]             r[-1]
               = -------- + -------- + ... + --------- + k(s)
                 (s-p[0])   (s-p[1])         (s-p[-1])

        If there are any repeated roots (closer together than `tol`), then H(s)
        has terms like::

              r[i]      r[i+1]              r[i+n-1]
            -------- + ----------- + ... + -----------
            (s-p[i])  (s-p[i])**2          (s-p[i])**n

        This function is used for polynomials in positive powers of s or z,
        such as analog filters or digital filters in controls engineering.  For
        negative powers of z (typical for digital filters in DSP), use `residuez`.

        See Notes for details about the algorithm.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        tol : float, optional
            The tolerance for two roots to be considered equal in terms of
            the distance between them. Default is 1e-3. See `unique_roots`
            for further details.
        rtype : {'avg', 'min', 'max'}, optional
            Method for computing a root to represent a group of identical roots.
            Default is 'avg'. See `unique_roots` for further details.

        Returns
        -------
        r : ndarray
            Residues corresponding to the poles. For repeated poles, the residues
            are ordered to correspond to ascending by power fractions.
        p : ndarray
            Poles ordered by magnitude in ascending order.
        k : ndarray
            Coefficients of the direct polynomial term.

        See Also
        --------
        invres, residuez, numpy.poly, unique_roots

        Notes
        -----
        The "deflation through subtraction" algorithm is used for
        computations --- method 6 in [1]_.

        The form of partial fraction expansion depends on poles multiplicity in
        the exact mathematical sense. However there is no way to exactly
        determine multiplicity of roots of a polynomial in numerical computing.
        Thus you should think of the result of `residue` with given `tol` as
        partial fraction expansion computed for the denominator composed of the
        computed poles with empirically determined multiplicity. The choice of
        `tol` can drastically change the result if there are close poles.

        References
        ----------
        .. [1] J. F. Mahoney, B. D. Sivazlian, "Partial fractions expansion: a
               review of computational methodology and efficiency", Journal of
               Computational and Applied Mathematics, Vol. 9, 1983.

    residuez(b, a, tol=0.001, rtype='avg')
        Compute partial-fraction expansion of b(z) / a(z).

        If `M` is the degree of numerator `b` and `N` the degree of denominator
        `a`::

                    b(z)     b[0] + b[1] z**(-1) + ... + b[M] z**(-M)
            H(z) = ------ = ------------------------------------------
                    a(z)     a[0] + a[1] z**(-1) + ... + a[N] z**(-N)

        then the partial-fraction expansion H(z) is defined as::

                     r[0]                   r[-1]
             = --------------- + ... + ---------------- + k[0] + k[1]z**(-1) ...
               (1-p[0]z**(-1))         (1-p[-1]z**(-1))

        If there are any repeated roots (closer than `tol`), then the partial
        fraction expansion has terms like::

                 r[i]              r[i+1]                    r[i+n-1]
            -------------- + ------------------ + ... + ------------------
            (1-p[i]z**(-1))  (1-p[i]z**(-1))**2         (1-p[i]z**(-1))**n

        This function is used for polynomials in negative powers of z,
        such as digital filters in DSP.  For positive powers, use `residue`.

        See Notes of `residue` for details about the algorithm.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        tol : float, optional
            The tolerance for two roots to be considered equal in terms of
            the distance between them. Default is 1e-3. See `unique_roots`
            for further details.
        rtype : {'avg', 'min', 'max'}, optional
            Method for computing a root to represent a group of identical roots.
            Default is 'avg'. See `unique_roots` for further details.

        Returns
        -------
        r : ndarray
            Residues corresponding to the poles. For repeated poles, the residues
            are ordered to correspond to ascending by power fractions.
        p : ndarray
            Poles ordered by magnitude in ascending order.
        k : ndarray
            Coefficients of the direct polynomial term.

        See Also
        --------
        invresz, residue, unique_roots

    ricker(points, a)
        Return a Ricker wavelet, also known as the "Mexican hat wavelet".

        .. deprecated:: 1.12.0

            scipy.signal.ricker is deprecated in SciPy 1.12 and will be removed
            in SciPy 1.15. We recommend using PyWavelets instead.

        It models the function:

            ``A * (1 - (x/a)**2) * exp(-0.5*(x/a)**2)``,

        where ``A = 2/(sqrt(3*a)*(pi**0.25))``.

        Parameters
        ----------
        points : int
            Number of points in `vector`.
            Will be centered around 0.
        a : scalar
            Width parameter of the wavelet.

        Returns
        -------
        vector : (N,) ndarray
            Array of length `points` in shape of ricker curve.

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> points = 100
        >>> a = 4.0
        >>> vec2 = signal.ricker(points, a)
        >>> print(len(vec2))
        100
        >>> plt.plot(vec2)
        >>> plt.show()

    savgol_coeffs(window_length, polyorder, deriv=0, delta=1.0, pos=None, use='conv')
        Compute the coefficients for a 1-D Savitzky-Golay FIR filter.

        Parameters
        ----------
        window_length : int
            The length of the filter window (i.e., the number of coefficients).
        polyorder : int
            The order of the polynomial used to fit the samples.
            `polyorder` must be less than `window_length`.
        deriv : int, optional
            The order of the derivative to compute. This must be a
            nonnegative integer. The default is 0, which means to filter
            the data without differentiating.
        delta : float, optional
            The spacing of the samples to which the filter will be applied.
            This is only used if deriv > 0.
        pos : int or None, optional
            If pos is not None, it specifies evaluation position within the
            window. The default is the middle of the window.
        use : str, optional
            Either 'conv' or 'dot'. This argument chooses the order of the
            coefficients. The default is 'conv', which means that the
            coefficients are ordered to be used in a convolution. With
            use='dot', the order is reversed, so the filter is applied by
            dotting the coefficients with the data set.

        Returns
        -------
        coeffs : 1-D ndarray
            The filter coefficients.

        See Also
        --------
        savgol_filter

        Notes
        -----
        .. versionadded:: 0.14.0

        References
        ----------
        A. Savitzky, M. J. E. Golay, Smoothing and Differentiation of Data by
        Simplified Least Squares Procedures. Analytical Chemistry, 1964, 36 (8),
        pp 1627-1639.
        Jianwen Luo, Kui Ying, and Jing Bai. 2005. Savitzky-Golay smoothing and
        differentiation filter for even number data. Signal Process.
        85, 7 (July 2005), 1429-1434.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import savgol_coeffs
        >>> savgol_coeffs(5, 2)
        array([-0.08571429,  0.34285714,  0.48571429,  0.34285714, -0.08571429])
        >>> savgol_coeffs(5, 2, deriv=1)
        array([ 2.00000000e-01,  1.00000000e-01,  2.07548111e-16, -1.00000000e-01,
               -2.00000000e-01])

        Note that use='dot' simply reverses the coefficients.

        >>> savgol_coeffs(5, 2, pos=3)
        array([ 0.25714286,  0.37142857,  0.34285714,  0.17142857, -0.14285714])
        >>> savgol_coeffs(5, 2, pos=3, use='dot')
        array([-0.14285714,  0.17142857,  0.34285714,  0.37142857,  0.25714286])
        >>> savgol_coeffs(4, 2, pos=3, deriv=1, use='dot')
        array([0.45,  -0.85,  -0.65,  1.05])

        `x` contains data from the parabola x = t**2, sampled at
        t = -1, 0, 1, 2, 3.  `c` holds the coefficients that will compute the
        derivative at the last position.  When dotted with `x` the result should
        be 6.

        >>> x = np.array([1, 0, 1, 4, 9])
        >>> c = savgol_coeffs(5, 2, pos=4, deriv=1, use='dot')
        >>> c.dot(x)
        6.0

    savgol_filter(x, window_length, polyorder, deriv=0, delta=1.0, axis=-1, mode='interp', cval=0.0)
        Apply a Savitzky-Golay filter to an array.

        This is a 1-D filter. If `x`  has dimension greater than 1, `axis`
        determines the axis along which the filter is applied.

        Parameters
        ----------
        x : array_like
            The data to be filtered. If `x` is not a single or double precision
            floating point array, it will be converted to type ``numpy.float64``
            before filtering.
        window_length : int
            The length of the filter window (i.e., the number of coefficients).
            If `mode` is 'interp', `window_length` must be less than or equal
            to the size of `x`.
        polyorder : int
            The order of the polynomial used to fit the samples.
            `polyorder` must be less than `window_length`.
        deriv : int, optional
            The order of the derivative to compute. This must be a
            nonnegative integer. The default is 0, which means to filter
            the data without differentiating.
        delta : float, optional
            The spacing of the samples to which the filter will be applied.
            This is only used if deriv > 0. Default is 1.0.
        axis : int, optional
            The axis of the array `x` along which the filter is to be applied.
            Default is -1.
        mode : str, optional
            Must be 'mirror', 'constant', 'nearest', 'wrap' or 'interp'. This
            determines the type of extension to use for the padded signal to
            which the filter is applied.  When `mode` is 'constant', the padding
            value is given by `cval`.  See the Notes for more details on 'mirror',
            'constant', 'wrap', and 'nearest'.
            When the 'interp' mode is selected (the default), no extension
            is used.  Instead, a degree `polyorder` polynomial is fit to the
            last `window_length` values of the edges, and this polynomial is
            used to evaluate the last `window_length // 2` output values.
        cval : scalar, optional
            Value to fill past the edges of the input if `mode` is 'constant'.
            Default is 0.0.

        Returns
        -------
        y : ndarray, same shape as `x`
            The filtered data.

        See Also
        --------
        savgol_coeffs

        Notes
        -----
        Details on the `mode` options:

            'mirror':
                Repeats the values at the edges in reverse order. The value
                closest to the edge is not included.
            'nearest':
                The extension contains the nearest input value.
            'constant':
                The extension contains the value given by the `cval` argument.
            'wrap':
                The extension contains the values from the other end of the array.

        For example, if the input is [1, 2, 3, 4, 5, 6, 7, 8], and
        `window_length` is 7, the following shows the extended data for
        the various `mode` options (assuming `cval` is 0)::

            mode       |   Ext   |         Input          |   Ext
            -----------+---------+------------------------+---------
            'mirror'   | 4  3  2 | 1  2  3  4  5  6  7  8 | 7  6  5
            'nearest'  | 1  1  1 | 1  2  3  4  5  6  7  8 | 8  8  8
            'constant' | 0  0  0 | 1  2  3  4  5  6  7  8 | 0  0  0
            'wrap'     | 6  7  8 | 1  2  3  4  5  6  7  8 | 1  2  3

        .. versionadded:: 0.14.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import savgol_filter
        >>> np.set_printoptions(precision=2)  # For compact display.
        >>> x = np.array([2, 2, 5, 2, 1, 0, 1, 4, 9])

        Filter with a window length of 5 and a degree 2 polynomial.  Use
        the defaults for all other parameters.

        >>> savgol_filter(x, 5, 2)
        array([1.66, 3.17, 3.54, 2.86, 0.66, 0.17, 1.  , 4.  , 9.  ])

        Note that the last five values in x are samples of a parabola, so
        when mode='interp' (the default) is used with polyorder=2, the last
        three values are unchanged. Compare that to, for example,
        `mode='nearest'`:

        >>> savgol_filter(x, 5, 2, mode='nearest')
        array([1.74, 3.03, 3.54, 2.86, 0.66, 0.17, 1.  , 4.6 , 7.97])

    sawtooth(t, width=1)
        Return a periodic sawtooth or triangle waveform.

        The sawtooth waveform has a period ``2*pi``, rises from -1 to 1 on the
        interval 0 to ``width*2*pi``, then drops from 1 to -1 on the interval
        ``width*2*pi`` to ``2*pi``. `width` must be in the interval [0, 1].

        Note that this is not band-limited.  It produces an infinite number
        of harmonics, which are aliased back and forth across the frequency
        spectrum.

        Parameters
        ----------
        t : array_like
            Time.
        width : array_like, optional
            Width of the rising ramp as a proportion of the total cycle.
            Default is 1, producing a rising ramp, while 0 produces a falling
            ramp.  `width` = 0.5 produces a triangle wave.
            If an array, causes wave shape to change over time, and must be the
            same length as t.

        Returns
        -------
        y : ndarray
            Output array containing the sawtooth waveform.

        Examples
        --------
        A 5 Hz waveform sampled at 500 Hz for 1 second:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> t = np.linspace(0, 1, 500)
        >>> plt.plot(t, signal.sawtooth(2 * np.pi * 5 * t))

    sepfir2d(...)
        out = sepfir2d(input, hrow, hcol)

        Convolve with a 2-D separable FIR filter.

        Convolve the rank-2 input array with the separable filter defined by the
        rank-1 arrays hrow, and hcol. Mirror symmetric boundary conditions are
        assumed. This function can be used to find an image given its B-spline
        representation.

        Parameters
        ----------
        input : ndarray
            The input signal. Must be a rank-2 array.
        hrow : ndarray
            A rank-1 array defining the row direction of the filter.
            Must be odd-length
        hcol : ndarray
            A rank-1 array defining the column direction of the filter.
            Must be odd-length

        Returns
        -------
        output : ndarray
            The filtered signal.

        Examples
        --------
        Examples are given :ref:`in the tutorial <tutorial-signal-bsplines>`.

    sos2tf(sos)
        Return a single transfer function from a series of second-order sections

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. See `sosfilt` for the SOS filter format
            specification.

        Returns
        -------
        b : ndarray
            Numerator polynomial coefficients.
        a : ndarray
            Denominator polynomial coefficients.

        Notes
        -----
        .. versionadded:: 0.16.0

        Examples
        --------
        Find the polynomial representation of an elliptic filter
        using its 'sos' (second-order sections) format.

        >>> from scipy.signal import sos2tf
        >>> from scipy import signal
        >>> sos = signal.ellip(1, 0.001, 50, 0.1, output='sos')
        >>> sos2tf(sos)
        (   array([0.91256522, 0.91256522, 0.        ]),
            array([1.        , 0.82513043, 0.        ]))

    sos2zpk(sos)
        Return zeros, poles, and gain of a series of second-order sections

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. See `sosfilt` for the SOS filter format
            specification.

        Returns
        -------
        z : ndarray
            Zeros of the transfer function.
        p : ndarray
            Poles of the transfer function.
        k : float
            System gain.

        Notes
        -----
        The number of zeros and poles returned will be ``n_sections * 2``
        even if some of these are (effectively) zero.

        .. versionadded:: 0.16.0

    sosfilt(sos, x, axis=-1, zi=None)
        Filter data along one dimension using cascaded second-order sections.

        Filter a data sequence, `x`, using a digital IIR filter defined by
        `sos`.

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. Each row corresponds to a second-order
            section, with the first three columns providing the numerator
            coefficients and the last three providing the denominator
            coefficients.
        x : array_like
            An N-dimensional input array.
        axis : int, optional
            The axis of the input data array along which to apply the
            linear filter. The filter is applied to each subarray along
            this axis.  Default is -1.
        zi : array_like, optional
            Initial conditions for the cascaded filter delays.  It is a (at
            least 2D) vector of shape ``(n_sections, ..., 2, ...)``, where
            ``..., 2, ...`` denotes the shape of `x`, but with ``x.shape[axis]``
            replaced by 2.  If `zi` is None or is not given then initial rest
            (i.e. all zeros) is assumed.
            Note that these initial conditions are *not* the same as the initial
            conditions given by `lfiltic` or `lfilter_zi`.

        Returns
        -------
        y : ndarray
            The output of the digital filter.
        zf : ndarray, optional
            If `zi` is None, this is not returned, otherwise, `zf` holds the
            final filter delay values.

        See Also
        --------
        zpk2sos, sos2zpk, sosfilt_zi, sosfiltfilt, sosfreqz

        Notes
        -----
        The filter function is implemented as a series of second-order filters
        with direct-form II transposed structure. It is designed to minimize
        numerical precision errors for high-order filters.

        .. versionadded:: 0.16.0

        Examples
        --------
        Plot a 13th-order filter's impulse response using both `lfilter` and
        `sosfilt`, showing the instability that results from trying to do a
        13th-order filter in a single stage (the numerical error pushes some poles
        outside of the unit circle):

        >>> import matplotlib.pyplot as plt
        >>> from scipy import signal
        >>> b, a = signal.ellip(13, 0.009, 80, 0.05, output='ba')
        >>> sos = signal.ellip(13, 0.009, 80, 0.05, output='sos')
        >>> x = signal.unit_impulse(700)
        >>> y_tf = signal.lfilter(b, a, x)
        >>> y_sos = signal.sosfilt(sos, x)
        >>> plt.plot(y_tf, 'r', label='TF')
        >>> plt.plot(y_sos, 'k', label='SOS')
        >>> plt.legend(loc='best')
        >>> plt.show()

    sosfilt_zi(sos)
        Construct initial conditions for sosfilt for step response steady-state.

        Compute an initial state `zi` for the `sosfilt` function that corresponds
        to the steady state of the step response.

        A typical use of this function is to set the initial state so that the
        output of the filter starts at the same value as the first element of
        the signal to be filtered.

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. See `sosfilt` for the SOS filter format
            specification.

        Returns
        -------
        zi : ndarray
            Initial conditions suitable for use with ``sosfilt``, shape
            ``(n_sections, 2)``.

        See Also
        --------
        sosfilt, zpk2sos

        Notes
        -----
        .. versionadded:: 0.16.0

        Examples
        --------
        Filter a rectangular pulse that begins at time 0, with and without
        the use of the `zi` argument of `scipy.signal.sosfilt`.

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt

        >>> sos = signal.butter(9, 0.125, output='sos')
        >>> zi = signal.sosfilt_zi(sos)
        >>> x = (np.arange(250) < 100).astype(int)
        >>> f1 = signal.sosfilt(sos, x)
        >>> f2, zo = signal.sosfilt(sos, x, zi=zi)

        >>> plt.plot(x, 'k--', label='x')
        >>> plt.plot(f1, 'b', alpha=0.5, linewidth=2, label='filtered')
        >>> plt.plot(f2, 'g', alpha=0.25, linewidth=4, label='filtered with zi')
        >>> plt.legend(loc='best')
        >>> plt.show()

    sosfiltfilt(sos, x, axis=-1, padtype='odd', padlen=None)
        A forward-backward digital filter using cascaded second-order sections.

        See `filtfilt` for more complete information about this method.

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. Each row corresponds to a second-order
            section, with the first three columns providing the numerator
            coefficients and the last three providing the denominator
            coefficients.
        x : array_like
            The array of data to be filtered.
        axis : int, optional
            The axis of `x` to which the filter is applied.
            Default is -1.
        padtype : str or None, optional
            Must be 'odd', 'even', 'constant', or None.  This determines the
            type of extension to use for the padded signal to which the filter
            is applied.  If `padtype` is None, no padding is used.  The default
            is 'odd'.
        padlen : int or None, optional
            The number of elements by which to extend `x` at both ends of
            `axis` before applying the filter.  This value must be less than
            ``x.shape[axis] - 1``.  ``padlen=0`` implies no padding.
            The default value is::

                3 * (2 * len(sos) + 1 - min((sos[:, 2] == 0).sum(),
                                            (sos[:, 5] == 0).sum()))

            The extra subtraction at the end attempts to compensate for poles
            and zeros at the origin (e.g. for odd-order filters) to yield
            equivalent estimates of `padlen` to those of `filtfilt` for
            second-order section filters built with `scipy.signal` functions.

        Returns
        -------
        y : ndarray
            The filtered output with the same shape as `x`.

        See Also
        --------
        filtfilt, sosfilt, sosfilt_zi, sosfreqz

        Notes
        -----
        .. versionadded:: 0.18.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.signal import sosfiltfilt, butter
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Create an interesting signal to filter.

        >>> n = 201
        >>> t = np.linspace(0, 1, n)
        >>> x = 1 + (t < 0.5) - 0.25*t**2 + 0.05*rng.standard_normal(n)

        Create a lowpass Butterworth filter, and use it to filter `x`.

        >>> sos = butter(4, 0.125, output='sos')
        >>> y = sosfiltfilt(sos, x)

        For comparison, apply an 8th order filter using `sosfilt`.  The filter
        is initialized using the mean of the first four values of `x`.

        >>> from scipy.signal import sosfilt, sosfilt_zi
        >>> sos8 = butter(8, 0.125, output='sos')
        >>> zi = x[:4].mean() * sosfilt_zi(sos8)
        >>> y2, zo = sosfilt(sos8, x, zi=zi)

        Plot the results.  Note that the phase of `y` matches the input, while
        `y2` has a significant phase delay.

        >>> plt.plot(t, x, alpha=0.5, label='x(t)')
        >>> plt.plot(t, y, label='y(t)')
        >>> plt.plot(t, y2, label='y2(t)')
        >>> plt.legend(framealpha=1, shadow=True)
        >>> plt.grid(alpha=0.25)
        >>> plt.xlabel('t')
        >>> plt.show()

    sosfreqz(sos, worN=512, whole=False, fs=6.283185307179586)
        Compute the frequency response of a digital filter in SOS format.

        Given `sos`, an array with shape (n, 6) of second order sections of
        a digital filter, compute the frequency response of the system function::

                   B0(z)   B1(z)         B{n-1}(z)
            H(z) = ----- * ----- * ... * ---------
                   A0(z)   A1(z)         A{n-1}(z)

        for z = exp(omega*1j), where B{k}(z) and A{k}(z) are numerator and
        denominator of the transfer function of the k-th second order section.

        Parameters
        ----------
        sos : array_like
            Array of second-order filter coefficients, must have shape
            ``(n_sections, 6)``. Each row corresponds to a second-order
            section, with the first three columns providing the numerator
            coefficients and the last three providing the denominator
            coefficients.
        worN : {None, int, array_like}, optional
            If a single integer, then compute at that many frequencies (default is
            N=512).  Using a number that is fast for FFT computations can result
            in faster computations (see Notes of `freqz`).

            If an array_like, compute the response at the frequencies given (must
            be 1-D). These are in the same units as `fs`.
        whole : bool, optional
            Normally, frequencies are computed from 0 to the Nyquist frequency,
            fs/2 (upper-half of unit-circle). If `whole` is True, compute
            frequencies from 0 to fs.
        fs : float, optional
            The sampling frequency of the digital system. Defaults to 2*pi
            radians/sample (so w is from 0 to pi).

            .. versionadded:: 1.2.0

        Returns
        -------
        w : ndarray
            The frequencies at which `h` was computed, in the same units as `fs`.
            By default, `w` is normalized to the range [0, pi) (radians/sample).
        h : ndarray
            The frequency response, as complex numbers.

        See Also
        --------
        freqz, sosfilt

        Notes
        -----
        .. versionadded:: 0.19.0

        Examples
        --------
        Design a 15th-order bandpass filter in SOS format.

        >>> from scipy import signal
        >>> import numpy as np
        >>> sos = signal.ellip(15, 0.5, 60, (0.2, 0.4), btype='bandpass',
        ...                    output='sos')

        Compute the frequency response at 1500 points from DC to Nyquist.

        >>> w, h = signal.sosfreqz(sos, worN=1500)

        Plot the response.

        >>> import matplotlib.pyplot as plt
        >>> plt.subplot(2, 1, 1)
        >>> db = 20*np.log10(np.maximum(np.abs(h), 1e-5))
        >>> plt.plot(w/np.pi, db)
        >>> plt.ylim(-75, 5)
        >>> plt.grid(True)
        >>> plt.yticks([0, -20, -40, -60])
        >>> plt.ylabel('Gain [dB]')
        >>> plt.title('Frequency Response')
        >>> plt.subplot(2, 1, 2)
        >>> plt.plot(w/np.pi, np.angle(h))
        >>> plt.grid(True)
        >>> plt.yticks([-np.pi, -0.5*np.pi, 0, 0.5*np.pi, np.pi],
        ...            [r'$-\pi$', r'$-\pi/2$', '0', r'$\pi/2$', r'$\pi$'])
        >>> plt.ylabel('Phase [rad]')
        >>> plt.xlabel('Normalized frequency (1.0 = Nyquist)')
        >>> plt.show()

        If the same filter is implemented as a single transfer function,
        numerical error corrupts the frequency response:

        >>> b, a = signal.ellip(15, 0.5, 60, (0.2, 0.4), btype='bandpass',
        ...                    output='ba')
        >>> w, h = signal.freqz(b, a, worN=1500)
        >>> plt.subplot(2, 1, 1)
        >>> db = 20*np.log10(np.maximum(np.abs(h), 1e-5))
        >>> plt.plot(w/np.pi, db)
        >>> plt.ylim(-75, 5)
        >>> plt.grid(True)
        >>> plt.yticks([0, -20, -40, -60])
        >>> plt.ylabel('Gain [dB]')
        >>> plt.title('Frequency Response')
        >>> plt.subplot(2, 1, 2)
        >>> plt.plot(w/np.pi, np.angle(h))
        >>> plt.grid(True)
        >>> plt.yticks([-np.pi, -0.5*np.pi, 0, 0.5*np.pi, np.pi],
        ...            [r'$-\pi$', r'$-\pi/2$', '0', r'$\pi/2$', r'$\pi$'])
        >>> plt.ylabel('Phase [rad]')
        >>> plt.xlabel('Normalized frequency (1.0 = Nyquist)')
        >>> plt.show()

    spectrogram(x, fs=1.0, window=('tukey', 0.25), nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1, mode='psd')
        Compute a spectrogram with consecutive Fourier transforms (legacy function).

        Spectrograms can be used as a way of visualizing the change of a
        nonstationary signal's frequency content over time.

        .. legacy:: function

            :class:`ShortTimeFFT` is a newer STFT / ISTFT implementation with more
            features also including a :meth:`~ShortTimeFFT.spectrogram` method.
            A :ref:`comparison <tutorial_stft_legacy_stft>` between the
            implementations can be found in the :ref:`tutorial_stft` section of
            the :ref:`user_guide`.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` time series. Defaults to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg.
            Defaults to a Tukey window with shape parameter of 0.25.
        nperseg : int, optional
            Length of each segment. Defaults to None, but if window is str or
            tuple, is set to 256, and if window is array_like, is set to the
            length of the window.
        noverlap : int, optional
            Number of points to overlap between segments. If `None`,
            ``noverlap = nperseg // 8``. Defaults to `None`.
        nfft : int, optional
            Length of the FFT used, if a zero padded FFT is desired. If
            `None`, the FFT length is `nperseg`. Defaults to `None`.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to 'constant'.
        return_onesided : bool, optional
            If `True`, return a one-sided spectrum for real data. If
            `False` return a two-sided spectrum. Defaults to `True`, but for
            complex data, a two-sided spectrum is always returned.
        scaling : { 'density', 'spectrum' }, optional
            Selects between computing the power spectral density ('density')
            where `Sxx` has units of V**2/Hz and computing the power
            spectrum ('spectrum') where `Sxx` has units of V**2, if `x`
            is measured in V and `fs` is measured in Hz. Defaults to
            'density'.
        axis : int, optional
            Axis along which the spectrogram is computed; the default is over
            the last axis (i.e. ``axis=-1``).
        mode : str, optional
            Defines what kind of return values are expected. Options are
            ['psd', 'complex', 'magnitude', 'angle', 'phase']. 'complex' is
            equivalent to the output of `stft` with no padding or boundary
            extension. 'magnitude' returns the absolute magnitude of the
            STFT. 'angle' and 'phase' return the complex angle of the STFT,
            with and without unwrapping, respectively.

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        t : ndarray
            Array of segment times.
        Sxx : ndarray
            Spectrogram of x. By default, the last axis of Sxx corresponds
            to the segment times.

        See Also
        --------
        periodogram: Simple, optionally modified periodogram
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data
        welch: Power spectral density by Welch's method.
        csd: Cross spectral density by Welch's method.
        ShortTimeFFT: Newer STFT/ISTFT implementation providing more features,
                      which also includes a :meth:`~ShortTimeFFT.spectrogram`
                      method.

        Notes
        -----
        An appropriate amount of overlap will depend on the choice of window
        and on your requirements. In contrast to welch's method, where the
        entire data stream is averaged over, one may wish to use a smaller
        overlap (or perhaps none at all) when computing a spectrogram, to
        maintain some statistical independence between individual segments.
        It is for this reason that the default window is a Tukey window with
        1/8th of a window's length overlap at each end.


        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
               "Discrete-Time Signal Processing", Prentice Hall, 1999.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> from scipy.fft import fftshift
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate a test signal, a 2 Vrms sine wave whose frequency is slowly
        modulated around 3kHz, corrupted by white noise of exponentially
        decreasing magnitude sampled at 10 kHz.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 2 * np.sqrt(2)
        >>> noise_power = 0.01 * fs / 2
        >>> time = np.arange(N) / float(fs)
        >>> mod = 500*np.cos(2*np.pi*0.25*time)
        >>> carrier = amp * np.sin(2*np.pi*3e3*time + mod)
        >>> noise = rng.normal(scale=np.sqrt(noise_power), size=time.shape)
        >>> noise *= np.exp(-time/5)
        >>> x = carrier + noise

        Compute and plot the spectrogram.

        >>> f, t, Sxx = signal.spectrogram(x, fs)
        >>> plt.pcolormesh(t, f, Sxx, shading='gouraud')
        >>> plt.ylabel('Frequency [Hz]')
        >>> plt.xlabel('Time [sec]')
        >>> plt.show()

        Note, if using output that is not one sided, then use the following:

        >>> f, t, Sxx = signal.spectrogram(x, fs, return_onesided=False)
        >>> plt.pcolormesh(t, fftshift(f), fftshift(Sxx, axes=0), shading='gouraud')
        >>> plt.ylabel('Frequency [Hz]')
        >>> plt.xlabel('Time [sec]')
        >>> plt.show()

    spline_filter(Iin, lmbda=5.0)
        Smoothing spline (cubic) filtering of a rank-2 array.

        Filter an input data set, `Iin`, using a (cubic) smoothing spline of
        fall-off `lmbda`.

        Parameters
        ----------
        Iin : array_like
            input data set
        lmbda : float, optional
            spline smooghing fall-off value, default is `5.0`.

        Returns
        -------
        res : ndarray
            filtered input data

        Examples
        --------
        We can filter an multi dimensional signal (ex: 2D image) using cubic
        B-spline filter:

        >>> import numpy as np
        >>> from scipy.signal import spline_filter
        >>> import matplotlib.pyplot as plt
        >>> orig_img = np.eye(20)  # create an image
        >>> orig_img[10, :] = 1.0
        >>> sp_filter = spline_filter(orig_img, lmbda=0.1)
        >>> f, ax = plt.subplots(1, 2, sharex=True)
        >>> for ind, data in enumerate([[orig_img, "original image"],
        ...                             [sp_filter, "spline filter"]]):
        ...     ax[ind].imshow(data[0], cmap='gray_r')
        ...     ax[ind].set_title(data[1])
        >>> plt.tight_layout()
        >>> plt.show()

    square(t, duty=0.5)
        Return a periodic square-wave waveform.

        The square wave has a period ``2*pi``, has value +1 from 0 to
        ``2*pi*duty`` and -1 from ``2*pi*duty`` to ``2*pi``. `duty` must be in
        the interval [0,1].

        Note that this is not band-limited.  It produces an infinite number
        of harmonics, which are aliased back and forth across the frequency
        spectrum.

        Parameters
        ----------
        t : array_like
            The input time array.
        duty : array_like, optional
            Duty cycle.  Default is 0.5 (50% duty cycle).
            If an array, causes wave shape to change over time, and must be the
            same length as t.

        Returns
        -------
        y : ndarray
            Output array containing the square waveform.

        Examples
        --------
        A 5 Hz waveform sampled at 500 Hz for 1 second:

        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> t = np.linspace(0, 1, 500, endpoint=False)
        >>> plt.plot(t, signal.square(2 * np.pi * 5 * t))
        >>> plt.ylim(-2, 2)

        A pulse-width modulated sine wave:

        >>> plt.figure()
        >>> sig = np.sin(2 * np.pi * t)
        >>> pwm = signal.square(2 * np.pi * 30 * t, duty=(sig + 1)/2)
        >>> plt.subplot(2, 1, 1)
        >>> plt.plot(t, sig)
        >>> plt.subplot(2, 1, 2)
        >>> plt.plot(t, pwm)
        >>> plt.ylim(-1.5, 1.5)

    ss2tf(A, B, C, D, input=0)
        State-space to transfer function.

        A, B, C, D defines a linear state-space system with `p` inputs,
        `q` outputs, and `n` state variables.

        Parameters
        ----------
        A : array_like
            State (or system) matrix of shape ``(n, n)``
        B : array_like
            Input matrix of shape ``(n, p)``
        C : array_like
            Output matrix of shape ``(q, n)``
        D : array_like
            Feedthrough (or feedforward) matrix of shape ``(q, p)``
        input : int, optional
            For multiple-input systems, the index of the input to use.

        Returns
        -------
        num : 2-D ndarray
            Numerator(s) of the resulting transfer function(s). `num` has one row
            for each of the system's outputs. Each row is a sequence representation
            of the numerator polynomial.
        den : 1-D ndarray
            Denominator of the resulting transfer function(s). `den` is a sequence
            representation of the denominator polynomial.

        Examples
        --------
        Convert the state-space representation:

        .. math::

            \dot{\textbf{x}}(t) =
            \begin{bmatrix} -2 & -1 \\ 1 & 0 \end{bmatrix} \textbf{x}(t) +
            \begin{bmatrix} 1 \\ 0 \end{bmatrix} \textbf{u}(t) \\

            \textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) +
            \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)

        >>> A = [[-2, -1], [1, 0]]
        >>> B = [[1], [0]]  # 2-D column vector
        >>> C = [[1, 2]]    # 2-D row vector
        >>> D = 1

        to the transfer function:

        .. math:: H(s) = \frac{s^2 + 3s + 3}{s^2 + 2s + 1}

        >>> from scipy.signal import ss2tf
        >>> ss2tf(A, B, C, D)
        (array([[1., 3., 3.]]), array([ 1.,  2.,  1.]))

    ss2zpk(A, B, C, D, input=0)
        State-space representation to zero-pole-gain representation.

        A, B, C, D defines a linear state-space system with `p` inputs,
        `q` outputs, and `n` state variables.

        Parameters
        ----------
        A : array_like
            State (or system) matrix of shape ``(n, n)``
        B : array_like
            Input matrix of shape ``(n, p)``
        C : array_like
            Output matrix of shape ``(q, n)``
        D : array_like
            Feedthrough (or feedforward) matrix of shape ``(q, p)``
        input : int, optional
            For multiple-input systems, the index of the input to use.

        Returns
        -------
        z, p : sequence
            Zeros and poles.
        k : float
            System gain.

    step(system, X0=None, T=None, N=None)
        Step response of continuous-time system.

        Parameters
        ----------
        system : an instance of the LTI class or a tuple of array_like
            describing the system.
            The following gives the number of elements in the tuple and
            the interpretation:

                * 1 (instance of `lti`)
                * 2 (num, den)
                * 3 (zeros, poles, gain)
                * 4 (A, B, C, D)

        X0 : array_like, optional
            Initial state-vector (default is zero).
        T : array_like, optional
            Time points (computed if not given).
        N : int, optional
            Number of time points to compute if `T` is not given.

        Returns
        -------
        T : 1D ndarray
            Output time points.
        yout : 1D ndarray
            Step response of system.


        Notes
        -----
        If (num, den) is passed in for ``system``, coefficients for both the
        numerator and denominator should be specified in descending exponent
        order (e.g. ``s^2 + 3s + 5`` would be represented as ``[1, 3, 5]``).

        Examples
        --------
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> lti = signal.lti([1.0], [1.0, 1.0])
        >>> t, y = signal.step(lti)
        >>> plt.plot(t, y)
        >>> plt.xlabel('Time [s]')
        >>> plt.ylabel('Amplitude')
        >>> plt.title('Step response for 1. Order Lowpass')
        >>> plt.grid()

    stft(x, fs=1.0, window='hann', nperseg=256, noverlap=None, nfft=None, detrend=False, return_onesided=True, boundary='zeros', padded=True, axis=-1, scaling='spectrum')
        Compute the Short Time Fourier Transform (legacy function).

        STFTs can be used as a way of quantifying the change of a
        nonstationary signal's frequency and phase content over time.

        .. legacy:: function

            `ShortTimeFFT` is a newer STFT / ISTFT implementation with more
            features. A :ref:`comparison <tutorial_stft_legacy_stft>` between the
            implementations can be found in the :ref:`tutorial_stft` section of the
            :ref:`user_guide`.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` time series. Defaults to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg. Defaults
            to a Hann window.
        nperseg : int, optional
            Length of each segment. Defaults to 256.
        noverlap : int, optional
            Number of points to overlap between segments. If `None`,
            ``noverlap = nperseg // 2``. Defaults to `None`. When
            specified, the COLA constraint must be met (see Notes below).
        nfft : int, optional
            Length of the FFT used, if a zero padded FFT is desired. If
            `None`, the FFT length is `nperseg`. Defaults to `None`.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to `False`.
        return_onesided : bool, optional
            If `True`, return a one-sided spectrum for real data. If
            `False` return a two-sided spectrum. Defaults to `True`, but for
            complex data, a two-sided spectrum is always returned.
        boundary : str or None, optional
            Specifies whether the input signal is extended at both ends, and
            how to generate the new values, in order to center the first
            windowed segment on the first input point. This has the benefit
            of enabling reconstruction of the first input point when the
            employed window function starts at zero. Valid options are
            ``['even', 'odd', 'constant', 'zeros', None]``. Defaults to
            'zeros', for zero padding extension. I.e. ``[1, 2, 3, 4]`` is
            extended to ``[0, 1, 2, 3, 4, 0]`` for ``nperseg=3``.
        padded : bool, optional
            Specifies whether the input signal is zero-padded at the end to
            make the signal fit exactly into an integer number of window
            segments, so that all of the signal is included in the output.
            Defaults to `True`. Padding occurs after boundary extension, if
            `boundary` is not `None`, and `padded` is `True`, as is the
            default.
        axis : int, optional
            Axis along which the STFT is computed; the default is over the
            last axis (i.e. ``axis=-1``).
        scaling: {'spectrum', 'psd'}
            The default 'spectrum' scaling allows each frequency line of `Zxx` to
            be interpreted as a magnitude spectrum. The 'psd' option scales each
            line to a power spectral density - it allows to calculate the signal's
            energy by numerically integrating over ``abs(Zxx)**2``.

            .. versionadded:: 1.9.0

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        t : ndarray
            Array of segment times.
        Zxx : ndarray
            STFT of `x`. By default, the last axis of `Zxx` corresponds
            to the segment times.

        See Also
        --------
        istft: Inverse Short Time Fourier Transform
        ShortTimeFFT: Newer STFT/ISTFT implementation providing more features.
        check_COLA: Check whether the Constant OverLap Add (COLA) constraint
                    is met
        check_NOLA: Check whether the Nonzero Overlap Add (NOLA) constraint is met
        welch: Power spectral density by Welch's method.
        spectrogram: Spectrogram by Welch's method.
        csd: Cross spectral density by Welch's method.
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data

        Notes
        -----
        In order to enable inversion of an STFT via the inverse STFT in
        `istft`, the signal windowing must obey the constraint of "Nonzero
        OverLap Add" (NOLA), and the input signal must have complete
        windowing coverage (i.e. ``(x.shape[axis] - nperseg) %
        (nperseg-noverlap) == 0``). The `padded` argument may be used to
        accomplish this.

        Given a time-domain signal :math:`x[n]`, a window :math:`w[n]`, and a hop
        size :math:`H` = `nperseg - noverlap`, the windowed frame at time index
        :math:`t` is given by

        .. math:: x_{t}[n]=x[n]w[n-tH]

        The overlap-add (OLA) reconstruction equation is given by

        .. math:: x[n]=\frac{\sum_{t}x_{t}[n]w[n-tH]}{\sum_{t}w^{2}[n-tH]}

        The NOLA constraint ensures that every normalization term that appears
        in the denomimator of the OLA reconstruction equation is nonzero. Whether a
        choice of `window`, `nperseg`, and `noverlap` satisfy this constraint can
        be tested with `check_NOLA`.


        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Oppenheim, Alan V., Ronald W. Schafer, John R. Buck
               "Discrete-Time Signal Processing", Prentice Hall, 1999.
        .. [2] Daniel W. Griffin, Jae S. Lim "Signal Estimation from
               Modified Short-Time Fourier Transform", IEEE 1984,
               10.1109/TASSP.1984.1164317

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate a test signal, a 2 Vrms sine wave whose frequency is slowly
        modulated around 3kHz, corrupted by white noise of exponentially
        decreasing magnitude sampled at 10 kHz.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 2 * np.sqrt(2)
        >>> noise_power = 0.01 * fs / 2
        >>> time = np.arange(N) / float(fs)
        >>> mod = 500*np.cos(2*np.pi*0.25*time)
        >>> carrier = amp * np.sin(2*np.pi*3e3*time + mod)
        >>> noise = rng.normal(scale=np.sqrt(noise_power),
        ...                    size=time.shape)
        >>> noise *= np.exp(-time/5)
        >>> x = carrier + noise

        Compute and plot the STFT's magnitude.

        >>> f, t, Zxx = signal.stft(x, fs, nperseg=1000)
        >>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud')
        >>> plt.title('STFT Magnitude')
        >>> plt.ylabel('Frequency [Hz]')
        >>> plt.xlabel('Time [sec]')
        >>> plt.show()

        Compare the energy of the signal `x` with the energy of its STFT:

        >>> E_x = sum(x**2) / fs  # Energy of x
        >>> # Calculate a two-sided STFT with PSD scaling:
        >>> f, t, Zxx = signal.stft(x, fs, nperseg=1000, return_onesided=False,
        ...                         scaling='psd')
        >>> # Integrate numerically over abs(Zxx)**2:
        >>> df, dt = f[1] - f[0], t[1] - t[0]
        >>> E_Zxx = sum(np.sum(Zxx.real**2 + Zxx.imag**2, axis=0) * df) * dt
        >>> # The energy is the same, but the numerical errors are quite large:
        >>> np.isclose(E_x, E_Zxx, rtol=1e-2)
        True

    sweep_poly(t, poly, phi=0)
        Frequency-swept cosine generator, with a time-dependent frequency.

        This function generates a sinusoidal function whose instantaneous
        frequency varies with time.  The frequency at time `t` is given by
        the polynomial `poly`.

        Parameters
        ----------
        t : ndarray
            Times at which to evaluate the waveform.
        poly : 1-D array_like or instance of numpy.poly1d
            The desired frequency expressed as a polynomial.  If `poly` is
            a list or ndarray of length n, then the elements of `poly` are
            the coefficients of the polynomial, and the instantaneous
            frequency is

              ``f(t) = poly[0]*t**(n-1) + poly[1]*t**(n-2) + ... + poly[n-1]``

            If `poly` is an instance of numpy.poly1d, then the
            instantaneous frequency is

              ``f(t) = poly(t)``

        phi : float, optional
            Phase offset, in degrees, Default: 0.

        Returns
        -------
        sweep_poly : ndarray
            A numpy array containing the signal evaluated at `t` with the
            requested time-varying frequency.  More precisely, the function
            returns ``cos(phase + (pi/180)*phi)``, where `phase` is the integral
            (from 0 to t) of ``2 * pi * f(t)``; ``f(t)`` is defined above.

        See Also
        --------
        chirp

        Notes
        -----
        .. versionadded:: 0.8.0

        If `poly` is a list or ndarray of length `n`, then the elements of
        `poly` are the coefficients of the polynomial, and the instantaneous
        frequency is:

            ``f(t) = poly[0]*t**(n-1) + poly[1]*t**(n-2) + ... + poly[n-1]``

        If `poly` is an instance of `numpy.poly1d`, then the instantaneous
        frequency is:

              ``f(t) = poly(t)``

        Finally, the output `s` is:

            ``cos(phase + (pi/180)*phi)``

        where `phase` is the integral from 0 to `t` of ``2 * pi * f(t)``,
        ``f(t)`` as defined above.

        Examples
        --------
        Compute the waveform with instantaneous frequency::

            f(t) = 0.025*t**3 - 0.36*t**2 + 1.25*t + 2

        over the interval 0 <= t <= 10.

        >>> import numpy as np
        >>> from scipy.signal import sweep_poly
        >>> p = np.poly1d([0.025, -0.36, 1.25, 2.0])
        >>> t = np.linspace(0, 10, 5001)
        >>> w = sweep_poly(t, p)

        Plot it:

        >>> import matplotlib.pyplot as plt
        >>> plt.subplot(2, 1, 1)
        >>> plt.plot(t, w)
        >>> plt.title("Sweep Poly\nwith frequency " +
        ...           "$f(t) = 0.025t^3 - 0.36t^2 + 1.25t + 2$")
        >>> plt.subplot(2, 1, 2)
        >>> plt.plot(t, p(t), 'r', label='f(t)')
        >>> plt.legend()
        >>> plt.xlabel('t')
        >>> plt.tight_layout()
        >>> plt.show()

    symiirorder1(...)
        out = symiirorder1(input, c0, z1, precision=-1.0)

        Implement a smoothing IIR filter with mirror-symmetric boundary conditions
        using a cascade of first-order sections.  The second section uses a
        reversed sequence.  This implements a system with the following
        transfer function and mirror-symmetric boundary conditions::

                               c0
               H(z) = ---------------------
                       (1-z1/z) (1 - z1 z)

        The resulting signal will have mirror symmetric boundary conditions as well.

        Parameters
        ----------
        input : ndarray
            The input signal.
        c0, z1 : scalar
            Parameters in the transfer function.
        precision :
            Specifies the precision for calculating initial conditions
            of the recursive filter based on mirror-symmetric input.

        Returns
        -------
        output : ndarray
            The filtered signal.

    symiirorder2(...)
        out = symiirorder2(input, r, omega, precision=-1.0)

        Implement a smoothing IIR filter with mirror-symmetric boundary conditions
        using a cascade of second-order sections.  The second section uses a
        reversed sequence.  This implements the following transfer function::

                                      cs^2
             H(z) = ---------------------------------------
                    (1 - a2/z - a3/z^2) (1 - a2 z - a3 z^2 )

        where::

              a2 = (2 r cos omega)
              a3 = - r^2
              cs = 1 - 2 r cos omega + r^2

        Parameters
        ----------
        input : ndarray
            The input signal.
        r, omega : float
            Parameters in the transfer function.
        precision : float
            Specifies the precision for calculating initial conditions
            of the recursive filter based on mirror-symmetric input.

        Returns
        -------
        output : ndarray
            The filtered signal.

    tf2sos(b, a, pairing=None, *, analog=False)
        Return second-order sections from transfer function representation

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.
        pairing : {None, 'nearest', 'keep_odd', 'minimal'}, optional
            The method to use to combine pairs of poles and zeros into sections.
            See `zpk2sos` for information and restrictions on `pairing` and
            `analog` arguments.
        analog : bool, optional
            If True, system is analog, otherwise discrete.

            .. versionadded:: 1.8.0

        Returns
        -------
        sos : ndarray
            Array of second-order filter coefficients, with shape
            ``(n_sections, 6)``. See `sosfilt` for the SOS filter format
            specification.

        See Also
        --------
        zpk2sos, sosfilt

        Notes
        -----
        It is generally discouraged to convert from TF to SOS format, since doing
        so usually will not improve numerical precision errors. Instead, consider
        designing filters in ZPK format and converting directly to SOS. TF is
        converted to SOS by first converting to ZPK format, then converting
        ZPK to SOS.

        .. versionadded:: 0.16.0

        Examples
        --------
        Find the 'sos' (second-order sections) of the transfer function H(s)
        using its polynomial representation.

        .. math::

            H(s) = \frac{s^2 - 3.5s - 2}{s^4 + 3s^3 - 15s^2 - 19s + 30}

        >>> from scipy.signal import tf2sos
        >>> tf2sos([1, -3.5, -2], [1, 3, -15, -19, 30], analog=True)
        array([[  0. ,   0. ,   1. ,   1. ,   2. , -15. ],
               [  1. ,  -3.5,  -2. ,   1. ,   1. ,  -2. ]])

    tf2ss(num, den)
        Transfer function to state-space representation.

        Parameters
        ----------
        num, den : array_like
            Sequences representing the coefficients of the numerator and
            denominator polynomials, in order of descending degree. The
            denominator needs to be at least as long as the numerator.

        Returns
        -------
        A, B, C, D : ndarray
            State space representation of the system, in controller canonical
            form.

        Examples
        --------
        Convert the transfer function:

        .. math:: H(s) = \frac{s^2 + 3s + 3}{s^2 + 2s + 1}

        >>> num = [1, 3, 3]
        >>> den = [1, 2, 1]

        to the state-space representation:

        .. math::

            \dot{\textbf{x}}(t) =
            \begin{bmatrix} -2 & -1 \\ 1 & 0 \end{bmatrix} \textbf{x}(t) +
            \begin{bmatrix} 1 \\ 0 \end{bmatrix} \textbf{u}(t) \\

            \textbf{y}(t) = \begin{bmatrix} 1 & 2 \end{bmatrix} \textbf{x}(t) +
            \begin{bmatrix} 1 \end{bmatrix} \textbf{u}(t)

        >>> from scipy.signal import tf2ss
        >>> A, B, C, D = tf2ss(num, den)
        >>> A
        array([[-2., -1.],
               [ 1.,  0.]])
        >>> B
        array([[ 1.],
               [ 0.]])
        >>> C
        array([[ 1.,  2.]])
        >>> D
        array([[ 1.]])

    tf2zpk(b, a)
        Return zero, pole, gain (z, p, k) representation from a numerator,
        denominator representation of a linear filter.

        Parameters
        ----------
        b : array_like
            Numerator polynomial coefficients.
        a : array_like
            Denominator polynomial coefficients.

        Returns
        -------
        z : ndarray
            Zeros of the transfer function.
        p : ndarray
            Poles of the transfer function.
        k : float
            System gain.

        Notes
        -----
        If some values of `b` are too close to 0, they are removed. In that case,
        a BadCoefficients warning is emitted.

        The `b` and `a` arrays are interpreted as coefficients for positive,
        descending powers of the transfer function variable. So the inputs
        :math:`b = [b_0, b_1, ..., b_M]` and :math:`a =[a_0, a_1, ..., a_N]`
        can represent an analog filter of the form:

        .. math::

            H(s) = \frac
            {b_0 s^M + b_1 s^{(M-1)} + \cdots + b_M}
            {a_0 s^N + a_1 s^{(N-1)} + \cdots + a_N}

        or a discrete-time filter of the form:

        .. math::

            H(z) = \frac
            {b_0 z^M + b_1 z^{(M-1)} + \cdots + b_M}
            {a_0 z^N + a_1 z^{(N-1)} + \cdots + a_N}

        This "positive powers" form is found more commonly in controls
        engineering. If `M` and `N` are equal (which is true for all filters
        generated by the bilinear transform), then this happens to be equivalent
        to the "negative powers" discrete-time form preferred in DSP:

        .. math::

            H(z) = \frac
            {b_0 + b_1 z^{-1} + \cdots + b_M z^{-M}}
            {a_0 + a_1 z^{-1} + \cdots + a_N z^{-N}}

        Although this is true for common filters, remember that this is not true
        in the general case. If `M` and `N` are not equal, the discrete-time
        transfer function coefficients must first be converted to the "positive
        powers" form before finding the poles and zeros.

        Examples
        --------
        Find the zeroes, poles and gain of
        a filter with the transfer function

        .. math::

            H(s) = \frac{3s^2}{s^2 + 5s + 13}

        >>> from scipy.signal import tf2zpk
        >>> tf2zpk([3, 0, 0], [1, 5, 13])
        (   array([ 0.               ,  0.              ]),
            array([ -2.5+2.59807621j ,  -2.5-2.59807621j]),
            3.0)

    unique_roots(p, tol=0.001, rtype='min')
        Determine unique roots and their multiplicities from a list of roots.

        Parameters
        ----------
        p : array_like
            The list of roots.
        tol : float, optional
            The tolerance for two roots to be considered equal in terms of
            the distance between them. Default is 1e-3. Refer to Notes about
            the details on roots grouping.
        rtype : {'max', 'maximum', 'min', 'minimum', 'avg', 'mean'}, optional
            How to determine the returned root if multiple roots are within
            `tol` of each other.

              - 'max', 'maximum': pick the maximum of those roots
              - 'min', 'minimum': pick the minimum of those roots
              - 'avg', 'mean': take the average of those roots

            When finding minimum or maximum among complex roots they are compared
            first by the real part and then by the imaginary part.

        Returns
        -------
        unique : ndarray
            The list of unique roots.
        multiplicity : ndarray
            The multiplicity of each root.

        Notes
        -----
        If we have 3 roots ``a``, ``b`` and ``c``, such that ``a`` is close to
        ``b`` and ``b`` is close to ``c`` (distance is less than `tol`), then it
        doesn't necessarily mean that ``a`` is close to ``c``. It means that roots
        grouping is not unique. In this function we use "greedy" grouping going
        through the roots in the order they are given in the input `p`.

        This utility function is not specific to roots but can be used for any
        sequence of values for which uniqueness and multiplicity has to be
        determined. For a more general routine, see `numpy.unique`.

        Examples
        --------
        >>> from scipy import signal
        >>> vals = [0, 1.3, 1.31, 2.8, 1.25, 2.2, 10.3]
        >>> uniq, mult = signal.unique_roots(vals, tol=2e-2, rtype='avg')

        Check which roots have multiplicity larger than 1:

        >>> uniq[mult > 1]
        array([ 1.305])

    unit_impulse(shape, idx=None, dtype=<class 'float'>)
        Unit impulse signal (discrete delta function) or unit basis vector.

        Parameters
        ----------
        shape : int or tuple of int
            Number of samples in the output (1-D), or a tuple that represents the
            shape of the output (N-D).
        idx : None or int or tuple of int or 'mid', optional
            Index at which the value is 1.  If None, defaults to the 0th element.
            If ``idx='mid'``, the impulse will be centered at ``shape // 2`` in
            all dimensions.  If an int, the impulse will be at `idx` in all
            dimensions.
        dtype : data-type, optional
            The desired data-type for the array, e.g., ``numpy.int8``.  Default is
            ``numpy.float64``.

        Returns
        -------
        y : ndarray
            Output array containing an impulse signal.

        Notes
        -----
        The 1D case is also known as the Kronecker delta.

        .. versionadded:: 0.19.0

        Examples
        --------
        An impulse at the 0th element (:math:`\delta[n]`):

        >>> from scipy import signal
        >>> signal.unit_impulse(8)
        array([ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

        Impulse offset by 2 samples (:math:`\delta[n-2]`):

        >>> signal.unit_impulse(7, 2)
        array([ 0.,  0.,  1.,  0.,  0.,  0.,  0.])

        2-dimensional impulse, centered:

        >>> signal.unit_impulse((3, 3), 'mid')
        array([[ 0.,  0.,  0.],
               [ 0.,  1.,  0.],
               [ 0.,  0.,  0.]])

        Impulse at (2, 2), using broadcasting:

        >>> signal.unit_impulse((4, 4), 2)
        array([[ 0.,  0.,  0.,  0.],
               [ 0.,  0.,  0.,  0.],
               [ 0.,  0.,  1.,  0.],
               [ 0.,  0.,  0.,  0.]])

        Plot the impulse response of a 4th-order Butterworth lowpass filter:

        >>> imp = signal.unit_impulse(100, 'mid')
        >>> b, a = signal.butter(4, 0.2)
        >>> response = signal.lfilter(b, a, imp)

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(np.arange(-50, 50), imp)
        >>> plt.plot(np.arange(-50, 50), response)
        >>> plt.margins(0.1, 0.1)
        >>> plt.xlabel('Time [samples]')
        >>> plt.ylabel('Amplitude')
        >>> plt.grid(True)
        >>> plt.show()

    upfirdn(h, x, up=1, down=1, axis=-1, mode='constant', cval=0)
        Upsample, FIR filter, and downsample.

        Parameters
        ----------
        h : array_like
            1-D FIR (finite-impulse response) filter coefficients.
        x : array_like
            Input signal array.
        up : int, optional
            Upsampling rate. Default is 1.
        down : int, optional
            Downsampling rate. Default is 1.
        axis : int, optional
            The axis of the input data array along which to apply the
            linear filter. The filter is applied to each subarray along
            this axis. Default is -1.
        mode : str, optional
            The signal extension mode to use. The set
            ``{"constant", "symmetric", "reflect", "edge", "wrap"}`` correspond to
            modes provided by `numpy.pad`. ``"smooth"`` implements a smooth
            extension by extending based on the slope of the last 2 points at each
            end of the array. ``"antireflect"`` and ``"antisymmetric"`` are
            anti-symmetric versions of ``"reflect"`` and ``"symmetric"``. The mode
            `"line"` extends the signal based on a linear trend defined by the
            first and last points along the ``axis``.

            .. versionadded:: 1.4.0
        cval : float, optional
            The constant value to use when ``mode == "constant"``.

            .. versionadded:: 1.4.0

        Returns
        -------
        y : ndarray
            The output signal array. Dimensions will be the same as `x` except
            for along `axis`, which will change size according to the `h`,
            `up`,  and `down` parameters.

        Notes
        -----
        The algorithm is an implementation of the block diagram shown on page 129
        of the Vaidyanathan text [1]_ (Figure 4.3-8d).

        The direct approach of upsampling by factor of P with zero insertion,
        FIR filtering of length ``N``, and downsampling by factor of Q is
        O(N*Q) per output sample. The polyphase implementation used here is
        O(N/P).

        .. versionadded:: 0.18

        References
        ----------
        .. [1] P. P. Vaidyanathan, Multirate Systems and Filter Banks,
               Prentice Hall, 1993.

        Examples
        --------
        Simple operations:

        >>> import numpy as np
        >>> from scipy.signal import upfirdn
        >>> upfirdn([1, 1, 1], [1, 1, 1])   # FIR filter
        array([ 1.,  2.,  3.,  2.,  1.])
        >>> upfirdn([1], [1, 2, 3], 3)  # upsampling with zeros insertion
        array([ 1.,  0.,  0.,  2.,  0.,  0.,  3.])
        >>> upfirdn([1, 1, 1], [1, 2, 3], 3)  # upsampling with sample-and-hold
        array([ 1.,  1.,  1.,  2.,  2.,  2.,  3.,  3.,  3.])
        >>> upfirdn([.5, 1, .5], [1, 1, 1], 2)  # linear interpolation
        array([ 0.5,  1. ,  1. ,  1. ,  1. ,  1. ,  0.5])
        >>> upfirdn([1], np.arange(10), 1, 3)  # decimation by 3
        array([ 0.,  3.,  6.,  9.])
        >>> upfirdn([.5, 1, .5], np.arange(10), 2, 3)  # linear interp, rate 2/3
        array([ 0. ,  1. ,  2.5,  4. ,  5.5,  7. ,  8.5])

        Apply a single filter to multiple signals:

        >>> x = np.reshape(np.arange(8), (4, 2))
        >>> x
        array([[0, 1],
               [2, 3],
               [4, 5],
               [6, 7]])

        Apply along the last dimension of ``x``:

        >>> h = [1, 1]
        >>> upfirdn(h, x, 2)
        array([[ 0.,  0.,  1.,  1.],
               [ 2.,  2.,  3.,  3.],
               [ 4.,  4.,  5.,  5.],
               [ 6.,  6.,  7.,  7.]])

        Apply along the 0th dimension of ``x``:

        >>> upfirdn(h, x, 2, axis=0)
        array([[ 0.,  1.],
               [ 0.,  1.],
               [ 2.,  3.],
               [ 2.,  3.],
               [ 4.,  5.],
               [ 4.,  5.],
               [ 6.,  7.],
               [ 6.,  7.]])

    vectorstrength(events, period)
        Determine the vector strength of the events corresponding to the given
        period.

        The vector strength is a measure of phase synchrony, how well the
        timing of the events is synchronized to a single period of a periodic
        signal.

        If multiple periods are used, calculate the vector strength of each.
        This is called the "resonating vector strength".

        Parameters
        ----------
        events : 1D array_like
            An array of time points containing the timing of the events.
        period : float or array_like
            The period of the signal that the events should synchronize to.
            The period is in the same units as `events`.  It can also be an array
            of periods, in which case the outputs are arrays of the same length.

        Returns
        -------
        strength : float or 1D array
            The strength of the synchronization.  1.0 is perfect synchronization
            and 0.0 is no synchronization.  If `period` is an array, this is also
            an array with each element containing the vector strength at the
            corresponding period.
        phase : float or array
            The phase that the events are most strongly synchronized to in radians.
            If `period` is an array, this is also an array with each element
            containing the phase for the corresponding period.

        References
        ----------
        van Hemmen, JL, Longtin, A, and Vollmayr, AN. Testing resonating vector
            strength: Auditory system, electric fish, and noise.
            Chaos 21, 047508 (2011);
            :doi:`10.1063/1.3670512`.
        van Hemmen, JL.  Vector strength after Goldberg, Brown, and von Mises:
            biological and mathematical perspectives.  Biol Cybern.
            2013 Aug;107(4):385-96. :doi:`10.1007/s00422-013-0561-7`.
        van Hemmen, JL and Vollmayr, AN.  Resonating vector strength: what happens
            when we vary the "probing" frequency while keeping the spike times
            fixed.  Biol Cybern. 2013 Aug;107(4):491-94.
            :doi:`10.1007/s00422-013-0560-8`.

    welch(x, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1, average='mean')
        Estimate power spectral density using Welch's method.

        Welch's method [1]_ computes an estimate of the power spectral
        density by dividing the data into overlapping segments, computing a
        modified periodogram for each segment and averaging the
        periodograms.

        Parameters
        ----------
        x : array_like
            Time series of measurement values
        fs : float, optional
            Sampling frequency of the `x` time series. Defaults to 1.0.
        window : str or tuple or array_like, optional
            Desired window to use. If `window` is a string or tuple, it is
            passed to `get_window` to generate the window values, which are
            DFT-even by default. See `get_window` for a list of windows and
            required parameters. If `window` is array_like it will be used
            directly as the window and its length must be nperseg. Defaults
            to a Hann window.
        nperseg : int, optional
            Length of each segment. Defaults to None, but if window is str or
            tuple, is set to 256, and if window is array_like, is set to the
            length of the window.
        noverlap : int, optional
            Number of points to overlap between segments. If `None`,
            ``noverlap = nperseg // 2``. Defaults to `None`.
        nfft : int, optional
            Length of the FFT used, if a zero padded FFT is desired. If
            `None`, the FFT length is `nperseg`. Defaults to `None`.
        detrend : str or function or `False`, optional
            Specifies how to detrend each segment. If `detrend` is a
            string, it is passed as the `type` argument to the `detrend`
            function. If it is a function, it takes a segment and returns a
            detrended segment. If `detrend` is `False`, no detrending is
            done. Defaults to 'constant'.
        return_onesided : bool, optional
            If `True`, return a one-sided spectrum for real data. If
            `False` return a two-sided spectrum. Defaults to `True`, but for
            complex data, a two-sided spectrum is always returned.
        scaling : { 'density', 'spectrum' }, optional
            Selects between computing the power spectral density ('density')
            where `Pxx` has units of V**2/Hz and computing the squared magnitude
            spectrum ('spectrum') where `Pxx` has units of V**2, if `x`
            is measured in V and `fs` is measured in Hz. Defaults to
            'density'
        axis : int, optional
            Axis along which the periodogram is computed; the default is
            over the last axis (i.e. ``axis=-1``).
        average : { 'mean', 'median' }, optional
            Method to use when averaging periodograms. Defaults to 'mean'.

            .. versionadded:: 1.2.0

        Returns
        -------
        f : ndarray
            Array of sample frequencies.
        Pxx : ndarray
            Power spectral density or power spectrum of x.

        See Also
        --------
        periodogram: Simple, optionally modified periodogram
        lombscargle: Lomb-Scargle periodogram for unevenly sampled data

        Notes
        -----
        An appropriate amount of overlap will depend on the choice of window
        and on your requirements. For the default Hann window an overlap of
        50% is a reasonable trade off between accurately estimating the
        signal power, while not over counting any of the data. Narrower
        windows may require a larger overlap.

        If `noverlap` is 0, this method is equivalent to Bartlett's method
        [2]_.

        Consult the :ref:`tutorial_SpectralAnalysis` section of the :ref:`user_guide`
        for a discussion of the scalings of the power spectral density and
        the (squared) magnitude spectrum.

        .. versionadded:: 0.12.0

        References
        ----------
        .. [1] P. Welch, "The use of the fast Fourier transform for the
               estimation of power spectra: A method based on time averaging
               over short, modified periodograms", IEEE Trans. Audio
               Electroacoust. vol. 15, pp. 70-73, 1967.
        .. [2] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra",
               Biometrika, vol. 37, pp. 1-16, 1950.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import signal
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()

        Generate a test signal, a 2 Vrms sine wave at 1234 Hz, corrupted by
        0.001 V**2/Hz of white noise sampled at 10 kHz.

        >>> fs = 10e3
        >>> N = 1e5
        >>> amp = 2*np.sqrt(2)
        >>> freq = 1234.0
        >>> noise_power = 0.001 * fs / 2
        >>> time = np.arange(N) / fs
        >>> x = amp*np.sin(2*np.pi*freq*time)
        >>> x += rng.normal(scale=np.sqrt(noise_power), size=time.shape)

        Compute and plot the power spectral density.

        >>> f, Pxx_den = signal.welch(x, fs, nperseg=1024)
        >>> plt.semilogy(f, Pxx_den)
        >>> plt.ylim([0.5e-3, 1])
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('PSD [V**2/Hz]')
        >>> plt.show()

        If we average the last half of the spectral density, to exclude the
        peak, we can recover the noise power on the signal.

        >>> np.mean(Pxx_den[256:])
        0.0009924865443739191

        Now compute and plot the power spectrum.

        >>> f, Pxx_spec = signal.welch(x, fs, 'flattop', 1024, scaling='spectrum')
        >>> plt.figure()
        >>> plt.semilogy(f, np.sqrt(Pxx_spec))
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('Linear spectrum [V RMS]')
        >>> plt.show()

        The peak height in the power spectrum is an estimate of the RMS
        amplitude.

        >>> np.sqrt(Pxx_spec.max())
        2.0077340678640727

        If we now introduce a discontinuity in the signal, by increasing the
        amplitude of a small portion of the signal by 50, we can see the
        corruption of the mean average power spectral density, but using a
        median average better estimates the normal behaviour.

        >>> x[int(N//2):int(N//2)+10] *= 50.
        >>> f, Pxx_den = signal.welch(x, fs, nperseg=1024)
        >>> f_med, Pxx_den_med = signal.welch(x, fs, nperseg=1024, average='median')
        >>> plt.semilogy(f, Pxx_den, label='mean')
        >>> plt.semilogy(f_med, Pxx_den_med, label='median')
        >>> plt.ylim([0.5e-3, 1])
        >>> plt.xlabel('frequency [Hz]')
        >>> plt.ylabel('PSD [V**2/Hz]')
        >>> plt.legend()
        >>> plt.show()

    wiener(im, mysize=None, noise=None)
        Perform a Wiener filter on an N-dimensional array.

        Apply a Wiener filter to the N-dimensional array `im`.

        Parameters
        ----------
        im : ndarray
            An N-dimensional array.
        mysize : int or array_like, optional
            A scalar or an N-length list giving the size of the Wiener filter
            window in each dimension.  Elements of mysize should be odd.
            If mysize is a scalar, then this scalar is used as the size
            in each dimension.
        noise : float, optional
            The noise-power to use. If None, then noise is estimated as the
            average of the local variance of the input.

        Returns
        -------
        out : ndarray
            Wiener filtered result with the same shape as `im`.

        Notes
        -----
        This implementation is similar to wiener2 in Matlab/Octave.
        For more details see [1]_

        References
        ----------
        .. [1] Lim, Jae S., Two-Dimensional Signal and Image Processing,
               Englewood Cliffs, NJ, Prentice Hall, 1990, p. 548.

        Examples
        --------
        >>> from scipy.datasets import face
        >>> from scipy.signal import wiener
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> img = rng.random((40, 40))    #Create a random image
        >>> filtered_img = wiener(img, (5, 5))  #Filter the image
        >>> f, (plot1, plot2) = plt.subplots(1, 2)
        >>> plot1.imshow(img)
        >>> plot2.imshow(filtered_img)
        >>> plt.show()

    zoom_fft(x, fn, m=None, *, fs=2, endpoint=False, axis=-1)
        Compute the DFT of `x` only for frequencies in range `fn`.

        Parameters
        ----------
        x : array
            The signal to transform.
        fn : array_like
            A length-2 sequence [`f1`, `f2`] giving the frequency range, or a
            scalar, for which the range [0, `fn`] is assumed.
        m : int, optional
            The number of points to evaluate.  The default is the length of `x`.
        fs : float, optional
            The sampling frequency.  If ``fs=10`` represented 10 kHz, for example,
            then `f1` and `f2` would also be given in kHz.
            The default sampling frequency is 2, so `f1` and `f2` should be
            in the range [0, 1] to keep the transform below the Nyquist
            frequency.
        endpoint : bool, optional
            If True, `f2` is the last sample. Otherwise, it is not included.
            Default is False.
        axis : int, optional
            Axis over which to compute the FFT. If not given, the last axis is
            used.

        Returns
        -------
        out : ndarray
            The transformed signal.  The Fourier transform will be calculated
            at the points f1, f1+df, f1+2df, ..., f2, where df=(f2-f1)/m.

        See Also
        --------
        ZoomFFT : Class that creates a callable partial FFT function.

        Notes
        -----
        The defaults are chosen such that ``signal.zoom_fft(x, 2)`` is equivalent
        to ``fft.fft(x)`` and, if ``m > len(x)``, that ``signal.zoom_fft(x, 2, m)``
        is equivalent to ``fft.fft(x, m)``.

        To graph the magnitude of the resulting transform, use::

            plot(linspace(f1, f2, m, endpoint=False), abs(zoom_fft(x, [f1, f2], m)))

        If the transform needs to be repeated, use `ZoomFFT` to construct
        a specialized transform function which can be reused without
        recomputing constants.

        Examples
        --------
        To plot the transform results use something like the following:

        >>> import numpy as np
        >>> from scipy.signal import zoom_fft
        >>> t = np.linspace(0, 1, 1021)
        >>> x = np.cos(2*np.pi*15*t) + np.sin(2*np.pi*17*t)
        >>> f1, f2 = 5, 27
        >>> X = zoom_fft(x, [f1, f2], len(x), fs=1021)
        >>> f = np.linspace(f1, f2, len(x))
        >>> import matplotlib.pyplot as plt
        >>> plt.plot(f, 20*np.log10(np.abs(X)))
        >>> plt.show()

    zpk2sos(z, p, k, pairing=None, *, analog=False)
        Return second-order sections from zeros, poles, and gain of a system

        Parameters
        ----------
        z : array_like
            Zeros of the transfer function.
        p : array_like
            Poles of the transfer function.
        k : float
            System gain.
        pairing : {None, 'nearest', 'keep_odd', 'minimal'}, optional
            The method to use to combine pairs of poles and zeros into sections.
            If analog is False and pairing is None, pairing is set to 'nearest';
            if analog is True, pairing must be 'minimal', and is set to that if
            it is None.
        analog : bool, optional
            If True, system is analog, otherwise discrete.

            .. versionadded:: 1.8.0

        Returns
        -------
        sos : ndarray
            Array of second-order filter coefficients, with shape
            ``(n_sections, 6)``. See `sosfilt` for the SOS filter format
            specification.

        See Also
        --------
        sosfilt

        Notes
        -----
        The algorithm used to convert ZPK to SOS format is designed to
        minimize errors due to numerical precision issues. The pairing
        algorithm attempts to minimize the peak gain of each biquadratic
        section. This is done by pairing poles with the nearest zeros, starting
        with the poles closest to the unit circle for discrete-time systems, and
        poles closest to the imaginary axis for continuous-time systems.

        ``pairing='minimal'`` outputs may not be suitable for `sosfilt`,
        and ``analog=True`` outputs will never be suitable for `sosfilt`.

        *Algorithms*

        The steps in the ``pairing='nearest'``, ``pairing='keep_odd'``,
        and ``pairing='minimal'`` algorithms are mostly shared. The
        ``'nearest'`` algorithm attempts to minimize the peak gain, while
        ``'keep_odd'`` minimizes peak gain under the constraint that
        odd-order systems should retain one section as first order.
        ``'minimal'`` is similar to ``'keep_odd'``, but no additional
        poles or zeros are introduced

        The algorithm steps are as follows:

        As a pre-processing step for ``pairing='nearest'``,
        ``pairing='keep_odd'``, add poles or zeros to the origin as
        necessary to obtain the same number of poles and zeros for
        pairing.  If ``pairing == 'nearest'`` and there are an odd number
        of poles, add an additional pole and a zero at the origin.

        The following steps are then iterated over until no more poles or
        zeros remain:

        1. Take the (next remaining) pole (complex or real) closest to the
           unit circle (or imaginary axis, for ``analog=True``) to
           begin a new filter section.

        2. If the pole is real and there are no other remaining real poles [#]_,
           add the closest real zero to the section and leave it as a first
           order section. Note that after this step we are guaranteed to be
           left with an even number of real poles, complex poles, real zeros,
           and complex zeros for subsequent pairing iterations.

        3. Else:

            1. If the pole is complex and the zero is the only remaining real
               zero*, then pair the pole with the *next* closest zero
               (guaranteed to be complex). This is necessary to ensure that
               there will be a real zero remaining to eventually create a
               first-order section (thus keeping the odd order).

            2. Else pair the pole with the closest remaining zero (complex or
               real).

            3. Proceed to complete the second-order section by adding another
               pole and zero to the current pole and zero in the section:

                1. If the current pole and zero are both complex, add their
                   conjugates.

                2. Else if the pole is complex and the zero is real, add the
                   conjugate pole and the next closest real zero.

                3. Else if the pole is real and the zero is complex, add the
                   conjugate zero and the real pole closest to those zeros.

                4. Else (we must have a real pole and real zero) add the next
                   real pole closest to the unit circle, and then add the real
                   zero closest to that pole.

        .. [#] This conditional can only be met for specific odd-order inputs
               with the ``pairing = 'keep_odd'`` or ``'minimal'`` methods.

        .. versionadded:: 0.16.0

        Examples
        --------

        Design a 6th order low-pass elliptic digital filter for a system with a
        sampling rate of 8000 Hz that has a pass-band corner frequency of
        1000 Hz. The ripple in the pass-band should not exceed 0.087 dB, and
        the attenuation in the stop-band should be at least 90 dB.

        In the following call to `ellip`, we could use ``output='sos'``,
        but for this example, we'll use ``output='zpk'``, and then convert
        to SOS format with `zpk2sos`:

        >>> from scipy import signal
        >>> import numpy as np
        >>> z, p, k = signal.ellip(6, 0.087, 90, 1000/(0.5*8000), output='zpk')

        Now convert to SOS format.

        >>> sos = signal.zpk2sos(z, p, k)

        The coefficients of the numerators of the sections:

        >>> sos[:, :3]
        array([[0.0014152 , 0.00248677, 0.0014152 ],
               [1.        , 0.72976874, 1.        ],
               [1.        , 0.17607852, 1.        ]])

        The symmetry in the coefficients occurs because all the zeros are on the
        unit circle.

        The coefficients of the denominators of the sections:

        >>> sos[:, 3:]
        array([[ 1.        , -1.32544025,  0.46989976],
               [ 1.        , -1.26118294,  0.62625924],
               [ 1.        , -1.2570723 ,  0.8619958 ]])

        The next example shows the effect of the `pairing` option.  We have a
        system with three poles and three zeros, so the SOS array will have
        shape (2, 6). The means there is, in effect, an extra pole and an extra
        zero at the origin in the SOS representation.

        >>> z1 = np.array([-1, -0.5-0.5j, -0.5+0.5j])
        >>> p1 = np.array([0.75, 0.8+0.1j, 0.8-0.1j])

        With ``pairing='nearest'`` (the default), we obtain

        >>> signal.zpk2sos(z1, p1, 1)
        array([[ 1.  ,  1.  ,  0.5 ,  1.  , -0.75,  0.  ],
               [ 1.  ,  1.  ,  0.  ,  1.  , -1.6 ,  0.65]])

        The first section has the zeros {-0.5-0.05j, -0.5+0.5j} and the poles
        {0, 0.75}, and the second section has the zeros {-1, 0} and poles
        {0.8+0.1j, 0.8-0.1j}. Note that the extra pole and zero at the origin
        have been assigned to different sections.

        With ``pairing='keep_odd'``, we obtain:

        >>> signal.zpk2sos(z1, p1, 1, pairing='keep_odd')
        array([[ 1.  ,  1.  ,  0.  ,  1.  , -0.75,  0.  ],
               [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])

        The extra pole and zero at the origin are in the same section.
        The first section is, in effect, a first-order section.

        With ``pairing='minimal'``, the first-order section doesn't have
        the extra pole and zero at the origin:

        >>> signal.zpk2sos(z1, p1, 1, pairing='minimal')
        array([[ 0.  ,  1.  ,  1.  ,  0.  ,  1.  , -0.75],
               [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])

    zpk2ss(z, p, k)
        Zero-pole-gain representation to state-space representation

        Parameters
        ----------
        z, p : sequence
            Zeros and poles.
        k : float
            System gain.

        Returns
        -------
        A, B, C, D : ndarray
            State space representation of the system, in controller canonical
            form.

    zpk2tf(z, p, k)
        Return polynomial transfer function representation from zeros and poles

        Parameters
        ----------
        z : array_like
            Zeros of the transfer function.
        p : array_like
            Poles of the transfer function.
        k : float
            System gain.

        Returns
        -------
        b : ndarray
            Numerator polynomial coefficients.
        a : ndarray
            Denominator polynomial coefficients.

        Examples
        --------
        Find the polynomial representation of a transfer function H(s)
        using its 'zpk' (Zero-Pole-Gain) representation.

        .. math::

            H(z) = 5 \frac
            { (s - 2)(s - 6) }
            { (s - 1)(s - 8) }

        >>> from scipy.signal import zpk2tf
        >>> z   = [2,   6]
        >>> p   = [1,   8]
        >>> k   = 5
        >>> zpk2tf(z, p, k)
        (   array([  5., -40.,  60.]), array([ 1., -9.,  8.]))

DATA
    __all__ = ['BadCoefficients', 'CZT', 'ShortTimeFFT', 'StateSpace', 'Tr...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\signal\__init__.py

scipy.sparse
Python Library Documentation: package scipy.sparse in scipy

NAME
    scipy.sparse

DESCRIPTION
    =====================================
    Sparse matrices (:mod:`scipy.sparse`)
    =====================================

    .. currentmodule:: scipy.sparse

    .. toctree::
       :hidden:

       sparse.csgraph
       sparse.linalg

    SciPy 2-D sparse array package for numeric data.

    .. note::

       This package is switching to an array interface, compatible with
       NumPy arrays, from the older matrix interface.  We recommend that
       you use the array objects (`bsr_array`, `coo_array`, etc.) for
       all new work.

       When using the array interface, please note that:

       - ``x * y`` no longer performs matrix multiplication, but
         element-wise multiplication (just like with NumPy arrays).  To
         make code work with both arrays and matrices, use ``x @ y`` for
         matrix multiplication.
       - Operations such as `sum`, that used to produce dense matrices, now
         produce arrays, whose multiplication behavior differs similarly.
       - Sparse arrays currently must be two-dimensional.  This also means
         that all *slicing* operations on these objects must produce
         two-dimensional results, or they will result in an error. This
         will be addressed in a future version.

       The construction utilities (`eye`, `kron`, `random`, `diags`, etc.)
       have not yet been ported, but their results can be wrapped into arrays::

         A = csr_array(eye(3))

    Contents
    ========

    Sparse array classes
    --------------------

    .. autosummary::
       :toctree: generated/

       bsr_array - Block Sparse Row array
       coo_array - A sparse array in COOrdinate format
       csc_array - Compressed Sparse Column array
       csr_array - Compressed Sparse Row array
       dia_array - Sparse array with DIAgonal storage
       dok_array - Dictionary Of Keys based sparse array
       lil_array - Row-based list of lists sparse array
       sparray - Sparse array base class

    Sparse matrix classes
    ---------------------

    .. autosummary::
       :toctree: generated/

       bsr_matrix - Block Sparse Row matrix
       coo_matrix - A sparse matrix in COOrdinate format
       csc_matrix - Compressed Sparse Column matrix
       csr_matrix - Compressed Sparse Row matrix
       dia_matrix - Sparse matrix with DIAgonal storage
       dok_matrix - Dictionary Of Keys based sparse matrix
       lil_matrix - Row-based list of lists sparse matrix
       spmatrix - Sparse matrix base class

    Functions
    ---------

    Building sparse arrays:

    .. autosummary::
       :toctree: generated/

       diags_array - Return a sparse array from diagonals
       eye_array - Sparse MxN array whose k-th diagonal is all ones
       random_array - Random values in a given shape array
       block_array - Build a sparse array from sub-blocks

    Building sparse matrices:

    .. autosummary::
       :toctree: generated/

       eye - Sparse MxN matrix whose k-th diagonal is all ones
       identity - Identity matrix in sparse matrix format
       diags - Return a sparse matrix from diagonals
       spdiags - Return a sparse matrix from diagonals
       bmat - Build a sparse matrix from sparse sub-blocks
       random - Random values in a given shape matrix
       rand - Random values in a given shape matrix (old interface)

    Building larger structures from smaller (array or matrix)

    .. autosummary::
       :toctree: generated/

       kron - kronecker product of two sparse matrices
       kronsum - kronecker sum of sparse matrices
       block_diag - Build a block diagonal sparse matrix
       tril - Lower triangular portion of a matrix in sparse format
       triu - Upper triangular portion of a matrix in sparse format
       hstack - Stack sparse matrices horizontally (column wise)
       vstack - Stack sparse matrices vertically (row wise)

    Save and load sparse matrices:

    .. autosummary::
       :toctree: generated/

       save_npz - Save a sparse matrix/array to a file using ``.npz`` format.
       load_npz - Load a sparse matrix/array from a file using ``.npz`` format.

    Sparse tools:

    .. autosummary::
       :toctree: generated/

       find

    Identifying sparse arrays:

    - use `isinstance(A, sp.sparse.sparray)` to check whether an array or matrix.
    - use `A.format == 'csr'` to check the sparse format

    Identifying sparse matrices:

    .. autosummary::
       :toctree: generated/

       issparse
       isspmatrix
       isspmatrix_csc
       isspmatrix_csr
       isspmatrix_bsr
       isspmatrix_lil
       isspmatrix_dok
       isspmatrix_coo
       isspmatrix_dia

    Submodules
    ----------

    .. autosummary::

       csgraph - Compressed sparse graph routines
       linalg - sparse linear algebra routines

    Exceptions
    ----------

    .. autosummary::
       :toctree: generated/

       SparseEfficiencyWarning
       SparseWarning


    Usage information
    =================

    There are seven available sparse array types:

        1. `csc_array`: Compressed Sparse Column format
        2. `csr_array`: Compressed Sparse Row format
        3. `bsr_array`: Block Sparse Row format
        4. `lil_array`: List of Lists format
        5. `dok_array`: Dictionary of Keys format
        6. `coo_array`: COOrdinate format (aka IJV, triplet format)
        7. `dia_array`: DIAgonal format

    To construct an array efficiently, use either `dok_array` or `lil_array`.
    The `lil_array` class supports basic slicing and fancy indexing with a
    similar syntax to NumPy arrays. As illustrated below, the COO format
    may also be used to efficiently construct arrays. Despite their
    similarity to NumPy arrays, it is **strongly discouraged** to use NumPy
    functions directly on these arrays because NumPy may not properly convert
    them for computations, leading to unexpected (and incorrect) results. If you
    do want to apply a NumPy function to these arrays, first check if SciPy has
    its own implementation for the given sparse array class, or **convert the
    sparse array to a NumPy array** (e.g., using the ``toarray`` method of the
    class) first before applying the method.

    To perform manipulations such as multiplication or inversion, first
    convert the array to either CSC or CSR format. The `lil_array` format is
    row-based, so conversion to CSR is efficient, whereas conversion to CSC
    is less so.

    All conversions among the CSR, CSC, and COO formats are efficient,
    linear-time operations.

    Matrix vector product
    ---------------------
    To do a vector product between a sparse array and a vector simply use
    the array ``dot`` method, as described in its docstring:

    >>> import numpy as np
    >>> from scipy.sparse import csr_array
    >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
    >>> v = np.array([1, 0, -1])
    >>> A.dot(v)
    array([ 1, -3, -1], dtype=int64)

    .. warning:: As of NumPy 1.7, ``np.dot`` is not aware of sparse arrays,
      therefore using it will result on unexpected results or errors.
      The corresponding dense array should be obtained first instead:

      >>> np.dot(A.toarray(), v)
      array([ 1, -3, -1], dtype=int64)

      but then all the performance advantages would be lost.

    The CSR format is especially suitable for fast matrix vector products.

    Example 1
    ---------
    Construct a 1000x1000 `lil_array` and add some values to it:

    >>> from scipy.sparse import lil_array
    >>> from scipy.sparse.linalg import spsolve
    >>> from numpy.linalg import solve, norm
    >>> from numpy.random import rand

    >>> A = lil_array((1000, 1000))
    >>> A[0, :100] = rand(100)
    >>> A.setdiag(rand(1000))

    Now convert it to CSR format and solve A x = b for x:

    >>> A = A.tocsr()
    >>> b = rand(1000)
    >>> x = spsolve(A, b)

    Convert it to a dense array and solve, and check that the result
    is the same:

    >>> x_ = solve(A.toarray(), b)

    Now we can compute norm of the error with:

    >>> err = norm(x-x_)
    >>> err < 1e-10
    True

    It should be small :)


    Example 2
    ---------

    Construct an array in COO format:

    >>> from scipy import sparse
    >>> from numpy import array
    >>> I = array([0,3,1,0])
    >>> J = array([0,3,1,2])
    >>> V = array([4,5,7,9])
    >>> A = sparse.coo_array((V,(I,J)),shape=(4,4))

    Notice that the indices do not need to be sorted.

    Duplicate (i,j) entries are summed when converting to CSR or CSC.

    >>> I = array([0,0,1,3,1,0,0])
    >>> J = array([0,2,1,3,1,0,0])
    >>> V = array([1,1,1,1,1,1,1])
    >>> B = sparse.coo_array((V,(I,J)),shape=(4,4)).tocsr()

    This is useful for constructing finite-element stiffness and mass matrices.

    Further details
    ---------------

    CSR column indices are not necessarily sorted. Likewise for CSC row
    indices. Use the ``.sorted_indices()`` and ``.sort_indices()`` methods when
    sorted indices are required (e.g., when passing data to other libraries).

PACKAGE CONTENTS
    _base
    _bsr
    _compressed
    _construct
    _coo
    _csc
    _csparsetools
    _csr
    _data
    _dia
    _dok
    _extract
    _index
    _lil
    _matrix
    _matrix_io
    _sparsetools
    _spfuncs
    _sputils
    base
    bsr
    compressed
    construct
    coo
    csc
    csgraph (package)
    csr
    data
    dia
    dok
    extract
    lil
    linalg (package)
    sparsetools
    spfuncs
    sputils
    tests (package)

CLASSES
    builtins.Warning(builtins.Exception)
        scipy.sparse._base.SparseWarning
            scipy.sparse._base.SparseEfficiencyWarning
    builtins.object
        scipy.sparse._base.sparray
            scipy.sparse._bsr.bsr_array(scipy.sparse._bsr._bsr_base, scipy.sparse._base.sparray)
            scipy.sparse._coo.coo_array(scipy.sparse._coo._coo_base, scipy.sparse._base.sparray)
            scipy.sparse._csc.csc_array(scipy.sparse._csc._csc_base, scipy.sparse._base.sparray)
            scipy.sparse._csr.csr_array(scipy.sparse._csr._csr_base, scipy.sparse._base.sparray)
            scipy.sparse._dia.dia_array(scipy.sparse._dia._dia_base, scipy.sparse._base.sparray)
            scipy.sparse._dok.dok_array(scipy.sparse._dok._dok_base, scipy.sparse._base.sparray)
            scipy.sparse._lil.lil_array(scipy.sparse._lil._lil_base, scipy.sparse._base.sparray)
        scipy.sparse._matrix.spmatrix
            scipy.sparse._bsr.bsr_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._bsr._bsr_base)
            scipy.sparse._coo.coo_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._coo._coo_base)
            scipy.sparse._csc.csc_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._csc._csc_base)
            scipy.sparse._csr.csr_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._csr._csr_base)
            scipy.sparse._dia.dia_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._dia._dia_base)
            scipy.sparse._dok.dok_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._dok._dok_base)
            scipy.sparse._lil.lil_matrix(scipy.sparse._matrix.spmatrix, scipy.sparse._lil._lil_base)
    scipy.sparse._bsr._bsr_base(scipy.sparse._compressed._cs_matrix, scipy.sparse._data._minmax_mixin)
        scipy.sparse._bsr.bsr_array(scipy.sparse._bsr._bsr_base, scipy.sparse._base.sparray)
    scipy.sparse._coo._coo_base(scipy.sparse._data._data_matrix, scipy.sparse._data._minmax_mixin)
        scipy.sparse._coo.coo_array(scipy.sparse._coo._coo_base, scipy.sparse._base.sparray)
    scipy.sparse._csc._csc_base(scipy.sparse._compressed._cs_matrix)
        scipy.sparse._csc.csc_array(scipy.sparse._csc._csc_base, scipy.sparse._base.sparray)
    scipy.sparse._csr._csr_base(scipy.sparse._compressed._cs_matrix)
        scipy.sparse._csr.csr_array(scipy.sparse._csr._csr_base, scipy.sparse._base.sparray)
    scipy.sparse._dia._dia_base(scipy.sparse._data._data_matrix)
        scipy.sparse._dia.dia_array(scipy.sparse._dia._dia_base, scipy.sparse._base.sparray)
    scipy.sparse._dok._dok_base(scipy.sparse._base._spbase, scipy.sparse._index.IndexMixin, builtins.dict)
        scipy.sparse._dok.dok_array(scipy.sparse._dok._dok_base, scipy.sparse._base.sparray)
    scipy.sparse._lil._lil_base(scipy.sparse._base._spbase, scipy.sparse._index.IndexMixin)
        scipy.sparse._lil.lil_array(scipy.sparse._lil._lil_base, scipy.sparse._base.sparray)

    class SparseEfficiencyWarning(SparseWarning)
     |  Method resolution order:
     |      SparseEfficiencyWarning
     |      SparseWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors inherited from SparseWarning:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Warning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Warning:
     |
     |  __new__(*args, **kwargs) class method of builtins.Warning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class SparseWarning(builtins.Warning)
     |  Method resolution order:
     |      SparseWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Warning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Warning:
     |
     |  __new__(*args, **kwargs) class method of builtins.Warning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class bsr_array(_bsr_base, scipy.sparse._base.sparray)
     |  bsr_array(arg1, shape=None, dtype=None, copy=False, blocksize=None)
     |
     |  Block Sparse Row format sparse array.
     |
     |  This can be instantiated in several ways:
     |      bsr_array(D, [blocksize=(R,C)])
     |          where D is a 2-D ndarray.
     |
     |      bsr_array(S, [blocksize=(R,C)])
     |          with another sparse array or matrix S (equivalent to S.tobsr())
     |
     |      bsr_array((M, N), [blocksize=(R,C), dtype])
     |          to construct an empty sparse array with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      bsr_array((data, ij), [blocksize=(R,C), shape=(M, N)])
     |          where ``data`` and ``ij`` satisfy ``a[ij[0, k], ij[1, k]] = data[k]``
     |
     |      bsr_array((data, indices, indptr), [shape=(M, N)])
     |          is the standard BSR representation where the block column
     |          indices for row i are stored in ``indices[indptr[i]:indptr[i+1]]``
     |          and their corresponding block values are stored in
     |          ``data[ indptr[i]: indptr[i+1] ]``. If the shape parameter is not
     |          supplied, the array dimensions are inferred from the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      BSR format data array of the array
     |  indices
     |      BSR format index array of the array
     |  indptr
     |      BSR format index pointer array of the array
     |  blocksize
     |      Block size
     |  has_sorted_indices : bool
     |      Whether indices are sorted
     |  has_canonical_format : bool
     |  T
     |
     |  Notes
     |  -----
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  **Summary of BSR format**
     |
     |  The Block Sparse Row (BSR) format is very similar to the Compressed
     |  Sparse Row (CSR) format. BSR is appropriate for sparse matrices with dense
     |  sub matrices like the last example below. Such sparse block matrices often
     |  arise in vector-valued finite element discretizations. In such cases, BSR is
     |  considerably more efficient than CSR and CSC for many sparse arithmetic
     |  operations.
     |
     |  **Blocksize**
     |
     |  The blocksize (R,C) must evenly divide the shape of the sparse array (M,N).
     |  That is, R and C must satisfy the relationship ``M % R = 0`` and
     |  ``N % C = 0``.
     |
     |  If no blocksize is specified, a simple heuristic is applied to determine
     |  an appropriate blocksize.
     |
     |  **Canonical Format**
     |
     |  In canonical format, there are no duplicate blocks and indices are sorted
     |  per row.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.sparse import bsr_array
     |  >>> bsr_array((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 0, 1, 2, 2, 2])
     |  >>> col = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3 ,4, 5, 6])
     |  >>> bsr_array((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6]).repeat(4).reshape(6, 2, 2)
     |  >>> bsr_array((data,indices,indptr), shape=(6, 6)).toarray()
     |  array([[1, 1, 0, 0, 2, 2],
     |         [1, 1, 0, 0, 2, 2],
     |         [0, 0, 0, 0, 3, 3],
     |         [0, 0, 0, 0, 3, 3],
     |         [4, 4, 5, 5, 6, 6],
     |         [4, 4, 5, 5, 6, 6]])
     |
     |  Method resolution order:
     |      bsr_array
     |      _bsr_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _bsr_base:
     |
     |  __getitem__(self, key)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False, blocksize=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __setitem__(self, key, val)
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the BSR format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero elements in-place.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate array/matrix entries by adding them together
     |
     |      The is an *in place* operation
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix into Block Sparse Row Format.
     |
     |      With copy=False, the data/indices may be shared between this
     |      array/matrix and the resultant bsr_array/bsr_matrix.
     |
     |      If blocksize=(R, C) is provided, it will be used for determining
     |      block size of the bsr_array/bsr_matrix.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      When copy=False the data array will be shared between
     |      this array/matrix and the resultant coo_array/coo_matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from _bsr_base:
     |
     |  blocksize
     |      Block size of the matrix.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class bsr_matrix(scipy.sparse._matrix.spmatrix, _bsr_base)
     |  bsr_matrix(arg1, shape=None, dtype=None, copy=False, blocksize=None)
     |
     |  Block Sparse Row format sparse matrix.
     |
     |  This can be instantiated in several ways:
     |      bsr_matrix(D, [blocksize=(R,C)])
     |          where D is a 2-D ndarray.
     |
     |      bsr_matrix(S, [blocksize=(R,C)])
     |          with another sparse array or matrix S (equivalent to S.tobsr())
     |
     |      bsr_matrix((M, N), [blocksize=(R,C), dtype])
     |          to construct an empty sparse matrix with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      bsr_matrix((data, ij), [blocksize=(R,C), shape=(M, N)])
     |          where ``data`` and ``ij`` satisfy ``a[ij[0, k], ij[1, k]] = data[k]``
     |
     |      bsr_matrix((data, indices, indptr), [shape=(M, N)])
     |          is the standard BSR representation where the block column
     |          indices for row i are stored in ``indices[indptr[i]:indptr[i+1]]``
     |          and their corresponding block values are stored in
     |          ``data[ indptr[i]: indptr[i+1] ]``. If the shape parameter is not
     |          supplied, the matrix dimensions are inferred from the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      BSR format data array of the matrix
     |  indices
     |      BSR format index array of the matrix
     |  indptr
     |      BSR format index pointer array of the matrix
     |  blocksize
     |      Block size
     |  has_sorted_indices : bool
     |      Whether indices are sorted
     |  has_canonical_format : bool
     |  T
     |
     |  Notes
     |  -----
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  **Summary of BSR format**
     |
     |  The Block Sparse Row (BSR) format is very similar to the Compressed
     |  Sparse Row (CSR) format. BSR is appropriate for sparse matrices with dense
     |  sub matrices like the last example below. Such sparse block matrices often
     |  arise in vector-valued finite element discretizations. In such cases, BSR is
     |  considerably more efficient than CSR and CSC for many sparse arithmetic
     |  operations.
     |
     |  **Blocksize**
     |
     |  The blocksize (R,C) must evenly divide the shape of the sparse matrix (M,N).
     |  That is, R and C must satisfy the relationship ``M % R = 0`` and
     |  ``N % C = 0``.
     |
     |  If no blocksize is specified, a simple heuristic is applied to determine
     |  an appropriate blocksize.
     |
     |  **Canonical Format**
     |
     |  In canonical format, there are no duplicate blocks and indices are sorted
     |  per row.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.sparse import bsr_matrix
     |  >>> bsr_matrix((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 0, 1, 2, 2, 2])
     |  >>> col = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3 ,4, 5, 6])
     |  >>> bsr_matrix((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6]).repeat(4).reshape(6, 2, 2)
     |  >>> bsr_matrix((data,indices,indptr), shape=(6, 6)).toarray()
     |  array([[1, 1, 0, 0, 2, 2],
     |         [1, 1, 0, 0, 2, 2],
     |         [0, 0, 0, 0, 3, 3],
     |         [0, 0, 0, 0, 3, 3],
     |         [4, 4, 5, 5, 6, 6],
     |         [4, 4, 5, 5, 6, 6]])
     |
     |  Method resolution order:
     |      bsr_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _bsr_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      builtins.object
     |
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _bsr_base:
     |
     |  __getitem__(self, key)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False, blocksize=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __setitem__(self, key, val)
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the BSR format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero elements in-place.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate array/matrix entries by adding them together
     |
     |      The is an *in place* operation
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix into Block Sparse Row Format.
     |
     |      With copy=False, the data/indices may be shared between this
     |      array/matrix and the resultant bsr_array/bsr_matrix.
     |
     |      If blocksize=(R, C) is provided, it will be used for determining
     |      block size of the bsr_array/bsr_matrix.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      When copy=False the data array will be shared between
     |      this array/matrix and the resultant coo_array/coo_matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from _bsr_base:
     |
     |  blocksize
     |      Block size of the matrix.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __rmatmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class coo_array(_coo_base, scipy.sparse._base.sparray)
     |  coo_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  A sparse array in COOrdinate format.
     |
     |  Also known as the 'ijv' or 'triplet' format.
     |
     |  This can be instantiated in several ways:
     |      coo_array(D)
     |          where D is an ndarray
     |
     |      coo_array(S)
     |          with another sparse array or matrix S (equivalent to S.tocoo())
     |
     |      coo_array(shape, [dtype])
     |          to construct an empty sparse array with shape `shape`
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      coo_array((data, coords), [shape])
     |          to construct from existing data and index arrays:
     |              1. data[:]       the entries of the sparse array, in any order
     |              2. coords[i][:]  the axis-i coordinates of the data entries
     |
     |          Where ``A[coords] = data``, and coords is a tuple of index arrays.
     |          When shape is not specified, it is inferred from the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the sparse array
     |  shape : tuple of integers
     |      Shape of the sparse array
     |  ndim : int
     |      Number of dimensions of the sparse array
     |  nnz
     |  size
     |  data
     |      COO format data array of the sparse array
     |  coords
     |      COO format tuple of index arrays
     |  has_canonical_format : bool
     |      Whether the matrix has sorted coordinates and no duplicates
     |  format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the COO format
     |      - facilitates fast conversion among sparse formats
     |      - permits duplicate entries (see example)
     |      - very fast conversion to and from CSR/CSC formats
     |
     |  Disadvantages of the COO format
     |      - does not directly support:
     |          + arithmetic operations
     |          + slicing
     |
     |  Intended Usage
     |      - COO is a fast format for constructing sparse arrays
     |      - Once a COO array has been constructed, convert to CSR or
     |        CSC format for fast arithmetic and matrix vector operations
     |      - By default when converting to CSR or CSC format, duplicate (i,j)
     |        entries will be summed together.  This facilitates efficient
     |        construction of finite element matrices and the like. (see example)
     |
     |  Canonical format
     |      - Entries and coordinates sorted by row, then column.
     |      - There are no duplicate entries (i.e. duplicate (i,j) locations)
     |      - Data arrays MAY have explicit zeros.
     |
     |  Examples
     |  --------
     |
     |  >>> # Constructing an empty sparse array
     |  >>> import numpy as np
     |  >>> from scipy.sparse import coo_array
     |  >>> coo_array((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> # Constructing a sparse array using ijv format
     |  >>> row  = np.array([0, 3, 1, 0])
     |  >>> col  = np.array([0, 3, 1, 2])
     |  >>> data = np.array([4, 5, 7, 9])
     |  >>> coo_array((data, (row, col)), shape=(4, 4)).toarray()
     |  array([[4, 0, 9, 0],
     |         [0, 7, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 5]])
     |
     |  >>> # Constructing a sparse array with duplicate coordinates
     |  >>> row  = np.array([0, 0, 1, 3, 1, 0, 0])
     |  >>> col  = np.array([0, 2, 1, 3, 1, 0, 0])
     |  >>> data = np.array([1, 1, 1, 1, 1, 1, 1])
     |  >>> coo = coo_array((data, (row, col)), shape=(4, 4))
     |  >>> # Duplicate coordinates are maintained until implicitly or explicitly summed
     |  >>> np.max(coo.data)
     |  1
     |  >>> coo.toarray()
     |  array([[3, 0, 1, 0],
     |         [0, 2, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 1]])
     |
     |  Method resolution order:
     |      coo_array
     |      _coo_base
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _coo_base:
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  resize(self, *shape) -> None
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sum_duplicates(self) -> None
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format
     |
     |      Duplicate entries will be summed together.
     |
     |      Examples
     |      --------
     |      >>> from numpy import array
     |      >>> from scipy.sparse import coo_array
     |      >>> row  = array([0, 0, 1, 3, 1, 0, 0])
     |      >>> col  = array([0, 2, 1, 3, 1, 0, 0])
     |      >>> data = array([1, 1, 1, 1, 1, 1, 1])
     |      >>> A = coo_array((data, (row, col)), shape=(4, 4)).tocsc()
     |      >>> A.toarray()
     |      array([[3, 0, 1, 0],
     |             [0, 2, 0, 0],
     |             [0, 0, 0, 0],
     |             [0, 0, 0, 1]])
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format
     |
     |      Duplicate entries will be summed together.
     |
     |      Examples
     |      --------
     |      >>> from numpy import array
     |      >>> from scipy.sparse import coo_array
     |      >>> row  = array([0, 0, 1, 3, 1, 0, 0])
     |      >>> col  = array([0, 2, 1, 3, 1, 0, 0])
     |      >>> data = array([1, 1, 1, 1, 1, 1, 1])
     |      >>> A = coo_array((data, (row, col)), shape=(4, 4)).tocsr()
     |      >>> A.toarray()
     |      array([[3, 0, 1, 0],
     |             [0, 2, 0, 0],
     |             [0, 0, 0, 0],
     |             [0, 0, 0, 1]])
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _coo_base:
     |
     |  col
     |
     |  row
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class coo_matrix(scipy.sparse._matrix.spmatrix, _coo_base)
     |  coo_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  A sparse matrix in COOrdinate format.
     |
     |  Also known as the 'ijv' or 'triplet' format.
     |
     |  This can be instantiated in several ways:
     |      coo_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      coo_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.tocoo())
     |
     |      coo_matrix((M, N), [dtype])
     |          to construct an empty matrix with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      coo_matrix((data, (i, j)), [shape=(M, N)])
     |          to construct from three arrays:
     |              1. data[:]   the entries of the matrix, in any order
     |              2. i[:]      the row indices of the matrix entries
     |              3. j[:]      the column indices of the matrix entries
     |
     |          Where ``A[i[k], j[k]] = data[k]``.  When shape is not
     |          specified, it is inferred from the index arrays
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      COO format data array of the matrix
     |  row
     |      COO format row index array of the matrix
     |  col
     |      COO format column index array of the matrix
     |  has_canonical_format : bool
     |      Whether the matrix has sorted indices and no duplicates
     |  format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the COO format
     |      - facilitates fast conversion among sparse formats
     |      - permits duplicate entries (see example)
     |      - very fast conversion to and from CSR/CSC formats
     |
     |  Disadvantages of the COO format
     |      - does not directly support:
     |          + arithmetic operations
     |          + slicing
     |
     |  Intended Usage
     |      - COO is a fast format for constructing sparse matrices
     |      - Once a COO matrix has been constructed, convert to CSR or
     |        CSC format for fast arithmetic and matrix vector operations
     |      - By default when converting to CSR or CSC format, duplicate (i,j)
     |        entries will be summed together.  This facilitates efficient
     |        construction of finite element matrices and the like. (see example)
     |
     |  Canonical format
     |      - Entries and coordinates sorted by row, then column.
     |      - There are no duplicate entries (i.e. duplicate (i,j) locations)
     |      - Data arrays MAY have explicit zeros.
     |
     |  Examples
     |  --------
     |
     |  >>> # Constructing an empty matrix
     |  >>> import numpy as np
     |  >>> from scipy.sparse import coo_matrix
     |  >>> coo_matrix((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> # Constructing a matrix using ijv format
     |  >>> row  = np.array([0, 3, 1, 0])
     |  >>> col  = np.array([0, 3, 1, 2])
     |  >>> data = np.array([4, 5, 7, 9])
     |  >>> coo_matrix((data, (row, col)), shape=(4, 4)).toarray()
     |  array([[4, 0, 9, 0],
     |         [0, 7, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 5]])
     |
     |  >>> # Constructing a matrix with duplicate coordinates
     |  >>> row  = np.array([0, 0, 1, 3, 1, 0, 0])
     |  >>> col  = np.array([0, 2, 1, 3, 1, 0, 0])
     |  >>> data = np.array([1, 1, 1, 1, 1, 1, 1])
     |  >>> coo = coo_matrix((data, (row, col)), shape=(4, 4))
     |  >>> # Duplicate coordinates are maintained until implicitly or explicitly summed
     |  >>> np.max(coo.data)
     |  1
     |  >>> coo.toarray()
     |  array([[3, 0, 1, 0],
     |         [0, 2, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 1]])
     |
     |  Method resolution order:
     |      coo_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _coo_base
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __setstate__(self, state)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _coo_base:
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  resize(self, *shape) -> None
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sum_duplicates(self) -> None
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format
     |
     |      Duplicate entries will be summed together.
     |
     |      Examples
     |      --------
     |      >>> from numpy import array
     |      >>> from scipy.sparse import coo_array
     |      >>> row  = array([0, 0, 1, 3, 1, 0, 0])
     |      >>> col  = array([0, 2, 1, 3, 1, 0, 0])
     |      >>> data = array([1, 1, 1, 1, 1, 1, 1])
     |      >>> A = coo_array((data, (row, col)), shape=(4, 4)).tocsc()
     |      >>> A.toarray()
     |      array([[3, 0, 1, 0],
     |             [0, 2, 0, 0],
     |             [0, 0, 0, 0],
     |             [0, 0, 0, 1]])
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format
     |
     |      Duplicate entries will be summed together.
     |
     |      Examples
     |      --------
     |      >>> from numpy import array
     |      >>> from scipy.sparse import coo_array
     |      >>> row  = array([0, 0, 1, 3, 1, 0, 0])
     |      >>> col  = array([0, 2, 1, 3, 1, 0, 0])
     |      >>> data = array([1, 1, 1, 1, 1, 1, 1])
     |      >>> A = coo_array((data, (row, col)), shape=(4, 4)).tocsr()
     |      >>> A.toarray()
     |      array([[3, 0, 1, 0],
     |             [0, 2, 0, 0],
     |             [0, 0, 0, 0],
     |             [0, 0, 0, 1]])
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _coo_base:
     |
     |  col
     |
     |  row
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class csc_array(_csc_base, scipy.sparse._base.sparray)
     |  csc_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  Compressed Sparse Column array.
     |
     |  This can be instantiated in several ways:
     |      csc_array(D)
     |          where D is a 2-D ndarray
     |
     |      csc_array(S)
     |          with another sparse array or matrix S (equivalent to S.tocsc())
     |
     |      csc_array((M, N), [dtype])
     |          to construct an empty array with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      csc_array((data, (row_ind, col_ind)), [shape=(M, N)])
     |          where ``data``, ``row_ind`` and ``col_ind`` satisfy the
     |          relationship ``a[row_ind[k], col_ind[k]] = data[k]``.
     |
     |      csc_array((data, indices, indptr), [shape=(M, N)])
     |          is the standard CSC representation where the row indices for
     |          column i are stored in ``indices[indptr[i]:indptr[i+1]]``
     |          and their corresponding values are stored in
     |          ``data[indptr[i]:indptr[i+1]]``.  If the shape parameter is
     |          not supplied, the array dimensions are inferred from
     |          the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      CSC format data array of the array
     |  indices
     |      CSC format index array of the array
     |  indptr
     |      CSC format index pointer array of the array
     |  has_sorted_indices
     |  has_canonical_format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the CSC format
     |      - efficient arithmetic operations CSC + CSC, CSC * CSC, etc.
     |      - efficient column slicing
     |      - fast matrix vector products (CSR, BSR may be faster)
     |
     |  Disadvantages of the CSC format
     |    - slow row slicing operations (consider CSR)
     |    - changes to the sparsity structure are expensive (consider LIL or DOK)
     |
     |  Canonical format
     |    - Within each column, indices are sorted by row.
     |    - There are no duplicate entries.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import csc_array
     |  >>> csc_array((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 2, 2, 0, 1, 2])
     |  >>> col = np.array([0, 0, 1, 2, 2, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csc_array((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 4],
     |         [0, 0, 5],
     |         [2, 3, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csc_array((data, indices, indptr), shape=(3, 3)).toarray()
     |  array([[1, 0, 4],
     |         [0, 0, 5],
     |         [2, 3, 6]])
     |
     |  Method resolution order:
     |      csc_array
     |      _csc_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _csc_base:
     |
     |  __iter__(self)
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the CSR or CSC format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._index.IndexMixin:
     |
     |  __getitem__(self, key)
     |
     |  __setitem__(self, key, x)

    class csc_matrix(scipy.sparse._matrix.spmatrix, _csc_base)
     |  csc_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  Compressed Sparse Column matrix.
     |
     |  This can be instantiated in several ways:
     |      csc_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      csc_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.tocsc())
     |
     |      csc_matrix((M, N), [dtype])
     |          to construct an empty matrix with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      csc_matrix((data, (row_ind, col_ind)), [shape=(M, N)])
     |          where ``data``, ``row_ind`` and ``col_ind`` satisfy the
     |          relationship ``a[row_ind[k], col_ind[k]] = data[k]``.
     |
     |      csc_matrix((data, indices, indptr), [shape=(M, N)])
     |          is the standard CSC representation where the row indices for
     |          column i are stored in ``indices[indptr[i]:indptr[i+1]]``
     |          and their corresponding values are stored in
     |          ``data[indptr[i]:indptr[i+1]]``.  If the shape parameter is
     |          not supplied, the matrix dimensions are inferred from
     |          the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      CSC format data array of the matrix
     |  indices
     |      CSC format index array of the matrix
     |  indptr
     |      CSC format index pointer array of the matrix
     |  has_sorted_indices
     |  has_canonical_format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the CSC format
     |      - efficient arithmetic operations CSC + CSC, CSC * CSC, etc.
     |      - efficient column slicing
     |      - fast matrix vector products (CSR, BSR may be faster)
     |
     |  Disadvantages of the CSC format
     |    - slow row slicing operations (consider CSR)
     |    - changes to the sparsity structure are expensive (consider LIL or DOK)
     |
     |  Canonical format
     |    - Within each column, indices are sorted by row.
     |    - There are no duplicate entries.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import csc_matrix
     |  >>> csc_matrix((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 2, 2, 0, 1, 2])
     |  >>> col = np.array([0, 0, 1, 2, 2, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csc_matrix((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 4],
     |         [0, 0, 5],
     |         [2, 3, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csc_matrix((data, indices, indptr), shape=(3, 3)).toarray()
     |  array([[1, 0, 4],
     |         [0, 0, 5],
     |         [2, 3, 6]])
     |
     |  Method resolution order:
     |      csc_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _csc_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      builtins.object
     |
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _csc_base:
     |
     |  __iter__(self)
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the CSR or CSC format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._index.IndexMixin:
     |
     |  __getitem__(self, key)
     |
     |  __setitem__(self, key, x)

    class csr_array(_csr_base, scipy.sparse._base.sparray)
     |  csr_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  Compressed Sparse Row array.
     |
     |  This can be instantiated in several ways:
     |      csr_array(D)
     |          where D is a 2-D ndarray
     |
     |      csr_array(S)
     |          with another sparse array or matrix S (equivalent to S.tocsr())
     |
     |      csr_array((M, N), [dtype])
     |          to construct an empty array with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      csr_array((data, (row_ind, col_ind)), [shape=(M, N)])
     |          where ``data``, ``row_ind`` and ``col_ind`` satisfy the
     |          relationship ``a[row_ind[k], col_ind[k]] = data[k]``.
     |
     |      csr_array((data, indices, indptr), [shape=(M, N)])
     |          is the standard CSR representation where the column indices for
     |          row i are stored in ``indices[indptr[i]:indptr[i+1]]`` and their
     |          corresponding values are stored in ``data[indptr[i]:indptr[i+1]]``.
     |          If the shape parameter is not supplied, the array dimensions
     |          are inferred from the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      CSR format data array of the array
     |  indices
     |      CSR format index array of the array
     |  indptr
     |      CSR format index pointer array of the array
     |  has_sorted_indices
     |  has_canonical_format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the CSR format
     |    - efficient arithmetic operations CSR + CSR, CSR * CSR, etc.
     |    - efficient row slicing
     |    - fast matrix vector products
     |
     |  Disadvantages of the CSR format
     |    - slow column slicing operations (consider CSC)
     |    - changes to the sparsity structure are expensive (consider LIL or DOK)
     |
     |  Canonical Format
     |      - Within each row, indices are sorted by column.
     |      - There are no duplicate entries.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import csr_array
     |  >>> csr_array((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 0, 1, 2, 2, 2])
     |  >>> col = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csr_array((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csr_array((data, indices, indptr), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  Duplicate entries are summed together:
     |
     |  >>> row = np.array([0, 1, 2, 0])
     |  >>> col = np.array([0, 1, 1, 0])
     |  >>> data = np.array([1, 2, 4, 8])
     |  >>> csr_array((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[9, 0, 0],
     |         [0, 2, 0],
     |         [0, 4, 0]])
     |
     |  As an example of how to construct a CSR array incrementally,
     |  the following snippet builds a term-document array from texts:
     |
     |  >>> docs = [["hello", "world", "hello"], ["goodbye", "cruel", "world"]]
     |  >>> indptr = [0]
     |  >>> indices = []
     |  >>> data = []
     |  >>> vocabulary = {}
     |  >>> for d in docs:
     |  ...     for term in d:
     |  ...         index = vocabulary.setdefault(term, len(vocabulary))
     |  ...         indices.append(index)
     |  ...         data.append(1)
     |  ...     indptr.append(len(indices))
     |  ...
     |  >>> csr_array((data, indices, indptr), dtype=int).toarray()
     |  array([[2, 1, 0, 0],
     |         [0, 1, 1, 1]])
     |
     |  Method resolution order:
     |      csr_array
     |      _csr_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _csr_base:
     |
     |  __getitem__(self, key)
     |      # override IndexMixin.__getitem__ for 1d case until fully implemented
     |
     |  __iter__(self)
     |
     |  __setitem__(self, key, value)
     |      # override IndexMixin.__setitem__ for 1d case until fully implemented
     |
     |  tobsr(self, blocksize=None, copy=True)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the CSR or CSC format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class csr_matrix(scipy.sparse._matrix.spmatrix, _csr_base)
     |  csr_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  Compressed Sparse Row matrix.
     |
     |  This can be instantiated in several ways:
     |      csr_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      csr_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.tocsr())
     |
     |      csr_matrix((M, N), [dtype])
     |          to construct an empty matrix with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      csr_matrix((data, (row_ind, col_ind)), [shape=(M, N)])
     |          where ``data``, ``row_ind`` and ``col_ind`` satisfy the
     |          relationship ``a[row_ind[k], col_ind[k]] = data[k]``.
     |
     |      csr_matrix((data, indices, indptr), [shape=(M, N)])
     |          is the standard CSR representation where the column indices for
     |          row i are stored in ``indices[indptr[i]:indptr[i+1]]`` and their
     |          corresponding values are stored in ``data[indptr[i]:indptr[i+1]]``.
     |          If the shape parameter is not supplied, the matrix dimensions
     |          are inferred from the index arrays.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      CSR format data array of the matrix
     |  indices
     |      CSR format index array of the matrix
     |  indptr
     |      CSR format index pointer array of the matrix
     |  has_sorted_indices
     |  has_canonical_format
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the CSR format
     |    - efficient arithmetic operations CSR + CSR, CSR * CSR, etc.
     |    - efficient row slicing
     |    - fast matrix vector products
     |
     |  Disadvantages of the CSR format
     |    - slow column slicing operations (consider CSC)
     |    - changes to the sparsity structure are expensive (consider LIL or DOK)
     |
     |  Canonical Format
     |      - Within each row, indices are sorted by column.
     |      - There are no duplicate entries.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import csr_matrix
     |  >>> csr_matrix((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> row = np.array([0, 0, 1, 2, 2, 2])
     |  >>> col = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csr_matrix((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  >>> indptr = np.array([0, 2, 3, 6])
     |  >>> indices = np.array([0, 2, 2, 0, 1, 2])
     |  >>> data = np.array([1, 2, 3, 4, 5, 6])
     |  >>> csr_matrix((data, indices, indptr), shape=(3, 3)).toarray()
     |  array([[1, 0, 2],
     |         [0, 0, 3],
     |         [4, 5, 6]])
     |
     |  Duplicate entries are summed together:
     |
     |  >>> row = np.array([0, 1, 2, 0])
     |  >>> col = np.array([0, 1, 1, 0])
     |  >>> data = np.array([1, 2, 4, 8])
     |  >>> csr_matrix((data, (row, col)), shape=(3, 3)).toarray()
     |  array([[9, 0, 0],
     |         [0, 2, 0],
     |         [0, 4, 0]])
     |
     |  As an example of how to construct a CSR matrix incrementally,
     |  the following snippet builds a term-document matrix from texts:
     |
     |  >>> docs = [["hello", "world", "hello"], ["goodbye", "cruel", "world"]]
     |  >>> indptr = [0]
     |  >>> indices = []
     |  >>> data = []
     |  >>> vocabulary = {}
     |  >>> for d in docs:
     |  ...     for term in d:
     |  ...         index = vocabulary.setdefault(term, len(vocabulary))
     |  ...         indices.append(index)
     |  ...         data.append(1)
     |  ...     indptr.append(len(indices))
     |  ...
     |  >>> csr_matrix((data, indices, indptr), dtype=int).toarray()
     |  array([[2, 1, 0, 0],
     |         [0, 1, 1, 1]])
     |
     |  Method resolution order:
     |      csr_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _csr_base
     |      scipy.sparse._compressed._cs_matrix
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._data._minmax_mixin
     |      scipy.sparse._index.IndexMixin
     |      builtins.object
     |
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _csr_base:
     |
     |  __getitem__(self, key)
     |      # override IndexMixin.__getitem__ for 1d case until fully implemented
     |
     |  __iter__(self)
     |
     |  __setitem__(self, key, value)
     |      # override IndexMixin.__setitem__ for 1d case until fully implemented
     |
     |  tobsr(self, blocksize=None, copy=True)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  check_format(self, full_check=True)
     |      Check whether the array/matrix respects the CSR or CSC format.
     |
     |      Parameters
     |      ----------
     |      full_check : bool, optional
     |          If `True`, run rigorous check, scanning arrays for valid values.
     |          Note that activating those check might copy arrays for casting,
     |          modifying indices and index pointers' inplace.
     |          If `False`, run basic checks on attributes. O(1) operations.
     |          Default is `True`.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  eliminate_zeros(self)
     |      Remove zero entries from the array/matrix
     |
     |      This is an *in place* operation.
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by array/matrix, vector, or scalar.
     |
     |  prune(self)
     |      Remove empty space after all non-zero elements.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sort_indices(self)
     |      Sort the indices of this array/matrix *in place*
     |
     |  sorted_indices(self)
     |      Return a copy of this array/matrix with sorted indices
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  sum_duplicates(self)
     |      Eliminate duplicate entries by adding them together
     |
     |      This is an *in place* operation.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocoo(self, copy=True)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  has_canonical_format
     |      Whether the array/matrix has sorted indices and no duplicates
     |
     |      Returns
     |          - True: if the above applies
     |          - False: otherwise
     |
     |      has_canonical_format implies has_sorted_indices, so if the latter flag
     |      is False, so will the former be; if the former is found True, the
     |      latter flag is also set.
     |
     |  has_sorted_indices
     |      Whether the indices are sorted
     |
     |      Returns
     |          - True: if the indices of the array/matrix are in sorted order
     |          - False: otherwise
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._compressed._cs_matrix:
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __matmul__(self, other)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._minmax_mixin:
     |
     |  argmax(self, axis=None, out=None)
     |      Return indices of maximum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several maximum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmax is computed. If None (default), index
     |          of the maximum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      ind : numpy.matrix or int
     |          Indices of maximum elements. If matrix, its size along `axis` is 1.
     |
     |  argmin(self, axis=None, out=None)
     |      Return indices of minimum elements along an axis.
     |
     |      Implicit zero elements are also taken into account. If there are
     |      several minimum values, the index of the first occurrence is returned.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None}, optional
     |          Axis along which the argmin is computed. If None (default), index
     |          of the minimum element in the flatten data is returned.
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |       ind : numpy.matrix or int
     |          Indices of minimum elements. If matrix, its size along `axis` is 1.
     |
     |  max(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      min : The minimum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.max : NumPy's implementation of 'max' for matrices
     |
     |  min(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or maximum along an axis.
     |      This takes all elements into account, not just the non-zero ones.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      max : The maximum value of a sparse array/matrix along a given axis.
     |      numpy.matrix.min : NumPy's implementation of 'min' for matrices
     |
     |  nanmax(self, axis=None, out=None)
     |      Return the maximum of the array/matrix or maximum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the maximum is computed. The default is to
     |          compute the maximum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amax : coo_matrix or scalar
     |          Maximum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmin : The minimum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      max : The maximum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmax : NumPy's implementation of 'nanmax'.
     |
     |  nanmin(self, axis=None, out=None)
     |      Return the minimum of the array/matrix or minimum along an axis, ignoring any
     |      NaNs. This takes all elements into account, not just the non-zero
     |      ones.
     |
     |      .. versionadded:: 1.11.0
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the minimum is computed. The default is to
     |          compute the minimum over all elements, returning
     |          a scalar (i.e., `axis` = `None`).
     |
     |      out : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except for
     |          the default value, as this argument is not used.
     |
     |      Returns
     |      -------
     |      amin : coo_matrix or scalar
     |          Minimum of `a`. If `axis` is None, the result is a scalar value.
     |          If `axis` is given, the result is a sparse.coo_matrix of dimension
     |          ``a.ndim - 1``.
     |
     |      See Also
     |      --------
     |      nanmax : The maximum value of a sparse array/matrix along a given axis,
     |               ignoring NaNs.
     |      min : The minimum value of a sparse array/matrix along a given axis,
     |            propagating NaNs.
     |      numpy.nanmin : NumPy's implementation of 'nanmin'.

    class dia_array(_dia_base, scipy.sparse._base.sparray)
     |  dia_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  Sparse array with DIAgonal storage.
     |
     |  This can be instantiated in several ways:
     |      dia_array(D)
     |          where D is a 2-D ndarray
     |
     |      dia_array(S)
     |          with another sparse array or matrix S (equivalent to S.todia())
     |
     |      dia_array((M, N), [dtype])
     |          to construct an empty array with shape (M, N),
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      dia_array((data, offsets), shape=(M, N))
     |          where the ``data[k,:]`` stores the diagonal entries for
     |          diagonal ``offsets[k]`` (See example below)
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      DIA format data array of the array
     |  offsets
     |      DIA format offset array of the array
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import dia_array
     |  >>> dia_array((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
     |  >>> offsets = np.array([0, -1, 2])
     |  >>> dia_array((data, offsets), shape=(4, 4)).toarray()
     |  array([[1, 0, 3, 0],
     |         [1, 2, 0, 4],
     |         [0, 2, 3, 0],
     |         [0, 0, 3, 4]])
     |
     |  >>> from scipy.sparse import dia_array
     |  >>> n = 10
     |  >>> ex = np.ones(n)
     |  >>> data = np.array([ex, 2 * ex, ex])
     |  >>> offsets = np.array([-1, 0, 1])
     |  >>> dia_array((data, offsets), shape=(n, n)).toarray()
     |  array([[2., 1., 0., ..., 0., 0., 0.],
     |         [1., 2., 1., ..., 0., 0., 0.],
     |         [0., 1., 2., ..., 0., 0., 0.],
     |         ...,
     |         [0., 0., 0., ..., 2., 1., 0.],
     |         [0., 0., 0., ..., 1., 2., 1.],
     |         [0., 0., 0., ..., 0., 1., 2.]])
     |
     |  Method resolution order:
     |      dia_array
     |      _dia_base
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _dia_base:
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None

    class dia_matrix(scipy.sparse._matrix.spmatrix, _dia_base)
     |  dia_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  Sparse matrix with DIAgonal storage.
     |
     |  This can be instantiated in several ways:
     |      dia_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      dia_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.todia())
     |
     |      dia_matrix((M, N), [dtype])
     |          to construct an empty matrix with shape (M, N),
     |          dtype is optional, defaulting to dtype='d'.
     |
     |      dia_matrix((data, offsets), shape=(M, N))
     |          where the ``data[k,:]`` stores the diagonal entries for
     |          diagonal ``offsets[k]`` (See example below)
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      DIA format data array of the matrix
     |  offsets
     |      DIA format offset array of the matrix
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Examples
     |  --------
     |
     |  >>> import numpy as np
     |  >>> from scipy.sparse import dia_matrix
     |  >>> dia_matrix((3, 4), dtype=np.int8).toarray()
     |  array([[0, 0, 0, 0],
     |         [0, 0, 0, 0],
     |         [0, 0, 0, 0]], dtype=int8)
     |
     |  >>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
     |  >>> offsets = np.array([0, -1, 2])
     |  >>> dia_matrix((data, offsets), shape=(4, 4)).toarray()
     |  array([[1, 0, 3, 0],
     |         [1, 2, 0, 4],
     |         [0, 2, 3, 0],
     |         [0, 0, 3, 4]])
     |
     |  >>> from scipy.sparse import dia_matrix
     |  >>> n = 10
     |  >>> ex = np.ones(n)
     |  >>> data = np.array([ex, 2 * ex, ex])
     |  >>> offsets = np.array([-1, 0, 1])
     |  >>> dia_matrix((data, offsets), shape=(n, n)).toarray()
     |  array([[2., 1., 0., ..., 0., 0., 0.],
     |         [1., 2., 1., ..., 0., 0., 0.],
     |         [0., 1., 2., ..., 0., 0., 0.],
     |         ...,
     |         [0., 0., 0., ..., 2., 1., 0.],
     |         [0., 0., 0., ..., 1., 2., 1.],
     |         [0., 0., 0., ..., 0., 1., 2.]])
     |
     |  Method resolution order:
     |      dia_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _dia_base
     |      scipy.sparse._data._data_matrix
     |      scipy.sparse._base._spbase
     |      builtins.object
     |
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _dia_base:
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._data._data_matrix:
     |
     |  __abs__(self)
     |
     |  __imul__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __neg__(self)
     |
     |  __round__(self, ndigits=0)
     |
     |  arcsin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsin.
     |
     |      See `numpy.arcsin` for more information.
     |
     |  arcsinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arcsinh.
     |
     |      See `numpy.arcsinh` for more information.
     |
     |  arctan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctan.
     |
     |      See `numpy.arctan` for more information.
     |
     |  arctanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise arctanh.
     |
     |      See `numpy.arctanh` for more information.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  ceil(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise ceil.
     |
     |      See `numpy.ceil` for more information.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  deg2rad(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise deg2rad.
     |
     |      See `numpy.deg2rad` for more information.
     |
     |  expm1(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise expm1.
     |
     |      See `numpy.expm1` for more information.
     |
     |  floor(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise floor.
     |
     |      See `numpy.floor` for more information.
     |
     |  log1p(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise log1p.
     |
     |      See `numpy.log1p` for more information.
     |
     |  power(self, n, dtype=None)
     |      This function performs element-wise power.
     |
     |      Parameters
     |      ----------
     |      n : scalar
     |          n is a non-zero scalar (nonzero avoids dense ones creation)
     |          If zero power is desired, special case it to use `np.ones`
     |
     |      dtype : If dtype is not specified, the current dtype will be preserved.
     |
     |      Raises
     |      ------
     |      NotImplementedError : if n is a zero scalar
     |          If zero power is desired, special case it to use
     |          `np.ones(A.shape, dtype=A.dtype)`
     |
     |  rad2deg(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rad2deg.
     |
     |      See `numpy.rad2deg` for more information.
     |
     |  rint(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise rint.
     |
     |      See `numpy.rint` for more information.
     |
     |  sign(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sign.
     |
     |      See `numpy.sign` for more information.
     |
     |  sin(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sin.
     |
     |      See `numpy.sin` for more information.
     |
     |  sinh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sinh.
     |
     |      See `numpy.sinh` for more information.
     |
     |  sqrt(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise sqrt.
     |
     |      See `numpy.sqrt` for more information.
     |
     |  tan(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tan.
     |
     |      See `numpy.tan` for more information.
     |
     |  tanh(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise tanh.
     |
     |      See `numpy.tanh` for more information.
     |
     |  trunc(self) from scipy.sparse._data._create_method.<locals>
     |      Element-wise trunc.
     |
     |      See `numpy.trunc` for more information.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._data._data_matrix:
     |
     |  dtype
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __rmatmul__(self, other)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None

    class dok_array(_dok_base, scipy.sparse._base.sparray)
     |  dok_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  Dictionary Of Keys based sparse array.
     |
     |  This is an efficient structure for constructing sparse
     |  arrays incrementally.
     |
     |  This can be instantiated in several ways:
     |      dok_array(D)
     |          where D is a 2-D ndarray
     |
     |      dok_array(S)
     |          with another sparse array or matrix S (equivalent to S.todok())
     |
     |      dok_array((M,N), [dtype])
     |          create the array with initial shape (M,N)
     |          dtype is optional, defaulting to dtype='d'
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |      Number of nonzero elements
     |  size
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  - Allows for efficient O(1) access of individual elements.
     |  - Duplicates are not allowed.
     |  - Can be efficiently converted to a coo_array once constructed.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.sparse import dok_array
     |  >>> S = dok_array((5, 5), dtype=np.float32)
     |  >>> for i in range(5):
     |  ...     for j in range(5):
     |  ...         S[i, j] = i + j    # Update element
     |
     |  Method resolution order:
     |      dok_array
     |      _dok_base
     |      scipy.sparse._base._spbase
     |      scipy.sparse._index.IndexMixin
     |      builtins.dict
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _dok_base:
     |
     |  __add__(self, other)
     |
     |  __contains__(self, key)
     |      True if the dictionary has the specified key, else False.
     |
     |  __delitem__(self, key, /)
     |      Delete self[key].
     |
     |  __getitem__(self, key)
     |      Return self[key].
     |
     |  __imul__(self, other)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __ior__(self, other)
     |      Return self|=value.
     |
     |  __itruediv__(self, other)
     |
     |  __len__(self)
     |      Return len(self).
     |
     |  __neg__(self)
     |
     |  __or__(self, other)
     |      Return self|value.
     |
     |  __radd__(self, other)
     |
     |  __reduce__(self)
     |      Helper for pickle.
     |
     |  __reversed__(self)
     |      Return a reverse iterator over the dict keys.
     |
     |  __ror__(self, other)
     |      Return value|self.
     |
     |  __setitem__(self, key, value)
     |      Set self[key] to value.
     |
     |  __truediv__(self, other)
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  clear(self)
     |      D.clear() -> None.  Remove all items from D.
     |
     |  conjtransp(self)
     |      DEPRECATED: Return the conjugate transpose.
     |
     |      .. deprecated:: 1.14.0
     |
     |          `conjtransp` is deprecated and will be removed in v1.16.0.
     |          Use `.T.conj()` instead.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  get(self, key, default=0.0)
     |      This provides dict.get method functionality with type checking
     |
     |  items(self)
     |      D.items() -> a set-like object providing a view on D's items
     |
     |  keys(self)
     |      D.keys() -> a set-like object providing a view on D's keys
     |
     |  pop(self, /, *args)
     |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
     |
     |      If the key is not found, return the default if given; otherwise,
     |      raise a KeyError.
     |
     |  popitem(self)
     |      Remove and return a (key, value) pair as a 2-tuple.
     |
     |      Pairs are returned in LIFO (last-in, first-out) order.
     |      Raises KeyError if the dict is empty.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  setdefault(self, key, default=None, /)
     |      Insert key with a value of default if key is not in the dictionary.
     |
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  update(self, val)
     |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
     |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
     |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
     |      In either case, this is followed by: for k in F:  D[k] = F[k]
     |
     |  values(self)
     |      D.values() -> an object providing a view on D's values
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from _dok_base:
     |
     |  fromkeys(iterable, value=1, /)
     |      Create a new dictionary with keys from iterable and values set to value.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _dok_base:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __abs__(self)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __round__(self, ndigits=0)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  power(self, n, dtype=None)
     |      Element-wise power.
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.dict:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __sizeof__(...)
     |      D.__sizeof__() -> size of D in memory, in bytes
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from builtins.dict:
     |
     |  __class_getitem__(...)
     |      See PEP 585
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.dict:
     |
     |  __new__(*args, **kwargs) class method of builtins.dict
     |      Create and return a new object.  See help(type) for accurate signature.

    class dok_matrix(scipy.sparse._matrix.spmatrix, _dok_base)
     |  dok_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  Dictionary Of Keys based sparse matrix.
     |
     |  This is an efficient structure for constructing sparse
     |  matrices incrementally.
     |
     |  This can be instantiated in several ways:
     |      dok_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      dok_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.todok())
     |
     |      dok_matrix((M,N), [dtype])
     |          create the matrix with initial shape (M,N)
     |          dtype is optional, defaulting to dtype='d'
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |      Number of nonzero elements
     |  size
     |  T
     |
     |  Notes
     |  -----
     |
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  - Allows for efficient O(1) access of individual elements.
     |  - Duplicates are not allowed.
     |  - Can be efficiently converted to a coo_matrix once constructed.
     |
     |  Examples
     |  --------
     |  >>> import numpy as np
     |  >>> from scipy.sparse import dok_matrix
     |  >>> S = dok_matrix((5, 5), dtype=np.float32)
     |  >>> for i in range(5):
     |  ...     for j in range(5):
     |  ...         S[i, j] = i + j    # Update element
     |
     |  Method resolution order:
     |      dok_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _dok_base
     |      scipy.sparse._base._spbase
     |      scipy.sparse._index.IndexMixin
     |      builtins.dict
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __ior__(self, other)
     |      Return self|=value.
     |
     |  __or__(self, other)
     |      Return self|value.
     |
     |  __reversed__(self)
     |      Return a reverse iterator over the dict keys.
     |
     |  __ror__(self, other)
     |      Return value|self.
     |
     |  get_shape(self)
     |      Get shape of a sparse matrix.
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  shape
     |      Get shape of a sparse matrix.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _dok_base:
     |
     |  __add__(self, other)
     |
     |  __contains__(self, key)
     |      True if the dictionary has the specified key, else False.
     |
     |  __delitem__(self, key, /)
     |      Delete self[key].
     |
     |  __getitem__(self, key)
     |      Return self[key].
     |
     |  __imul__(self, other)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __itruediv__(self, other)
     |
     |  __len__(self)
     |      Return len(self).
     |
     |  __neg__(self)
     |
     |  __radd__(self, other)
     |
     |  __reduce__(self)
     |      Helper for pickle.
     |
     |  __setitem__(self, key, value)
     |      Set self[key] to value.
     |
     |  __truediv__(self, other)
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  clear(self)
     |      D.clear() -> None.  Remove all items from D.
     |
     |  conjtransp(self)
     |      DEPRECATED: Return the conjugate transpose.
     |
     |      .. deprecated:: 1.14.0
     |
     |          `conjtransp` is deprecated and will be removed in v1.16.0.
     |          Use `.T.conj()` instead.
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  get(self, key, default=0.0)
     |      This provides dict.get method functionality with type checking
     |
     |  items(self)
     |      D.items() -> a set-like object providing a view on D's items
     |
     |  keys(self)
     |      D.keys() -> a set-like object providing a view on D's keys
     |
     |  pop(self, /, *args)
     |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
     |
     |      If the key is not found, return the default if given; otherwise,
     |      raise a KeyError.
     |
     |  popitem(self)
     |      Remove and return a (key, value) pair as a 2-tuple.
     |
     |      Pairs are returned in LIFO (last-in, first-out) order.
     |      Raises KeyError if the dict is empty.
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  setdefault(self, key, default=None, /)
     |      Insert key with a value of default if key is not in the dictionary.
     |
     |      Return the value for key if key is in the dictionary, else default.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  update(self, val)
     |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
     |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
     |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
     |      In either case, this is followed by: for k in F:  D[k] = F[k]
     |
     |  values(self)
     |      D.values() -> an object providing a view on D's values
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from _dok_base:
     |
     |  fromkeys(iterable, value=1, /)
     |      Create a new dictionary with keys from iterable and values set to value.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __abs__(self)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __iadd__(self, other)
     |
     |  __idiv__(self, other)
     |
     |  __isub__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __round__(self, ndigits=0)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  power(self, n, dtype=None)
     |      Element-wise power.
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.dict:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __sizeof__(...)
     |      D.__sizeof__() -> size of D in memory, in bytes
     |
     |  ----------------------------------------------------------------------
     |  Class methods inherited from builtins.dict:
     |
     |  __class_getitem__(...)
     |      See PEP 585
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.dict:
     |
     |  __new__(*args, **kwargs) class method of builtins.dict
     |      Create and return a new object.  See help(type) for accurate signature.

    class lil_array(_lil_base, scipy.sparse._base.sparray)
     |  lil_array(arg1, shape=None, dtype=None, copy=False)
     |
     |  Row-based LIst of Lists sparse array.
     |
     |  This is a structure for constructing sparse arrays incrementally.
     |  Note that inserting a single item can take linear time in the worst case;
     |  to construct the array efficiently, make sure the items are pre-sorted by
     |  index, per row.
     |
     |  This can be instantiated in several ways:
     |      lil_array(D)
     |          where D is a 2-D ndarray
     |
     |      lil_array(S)
     |          with another sparse array or matrix S (equivalent to S.tolil())
     |
     |      lil_array((M, N), [dtype])
     |          to construct an empty array with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the array
     |  shape : 2-tuple
     |      Shape of the array
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      LIL format data array of the array
     |  rows
     |      LIL format row index array of the array
     |  T
     |
     |  Notes
     |  -----
     |  Sparse arrays can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the LIL format
     |      - supports flexible slicing
     |      - changes to the array sparsity structure are efficient
     |
     |  Disadvantages of the LIL format
     |      - arithmetic operations LIL + LIL are slow (consider CSR or CSC)
     |      - slow column slicing (consider CSC)
     |      - slow matrix vector products (consider CSR or CSC)
     |
     |  Intended Usage
     |      - LIL is a convenient format for constructing sparse arrays
     |      - once an array has been constructed, convert to CSR or
     |        CSC format for fast arithmetic and matrix vector operations
     |      - consider using the COO format when constructing large arrays
     |
     |  Data Structure
     |      - An array (``self.rows``) of rows, each of which is a sorted
     |        list of column indices of non-zero elements.
     |      - The corresponding nonzero values are stored in similar
     |        fashion in ``self.data``.
     |
     |  Method resolution order:
     |      lil_array
     |      _lil_base
     |      scipy.sparse._base._spbase
     |      scipy.sparse._index.IndexMixin
     |      scipy.sparse._base.sparray
     |      builtins.object
     |
     |  Methods inherited from _lil_base:
     |
     |  __getitem__(self, key)
     |
     |  __iadd__(self, other)
     |
     |  __imul__(self, other)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __isub__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __setitem__(self, key, x)
     |
     |  __truediv__(self, other)
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  getrow(self, i)
     |      Returns a copy of the 'i'th row.
     |
     |  getrowview(self, i)
     |      Returns a view of the 'i'th row (without copying).
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __abs__(self)
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __idiv__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __mul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __neg__(self)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __pow__(self, *args, **kwargs)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __rmul__(self, other)
     |
     |  __round__(self, ndigits=0)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  power(self, n, dtype=None)
     |      Element-wise power.
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  shape
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._base._spbase:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None

    class lil_matrix(scipy.sparse._matrix.spmatrix, _lil_base)
     |  lil_matrix(arg1, shape=None, dtype=None, copy=False)
     |
     |  Row-based LIst of Lists sparse matrix.
     |
     |  This is a structure for constructing sparse matrices incrementally.
     |  Note that inserting a single item can take linear time in the worst case;
     |  to construct the matrix efficiently, make sure the items are pre-sorted by
     |  index, per row.
     |
     |  This can be instantiated in several ways:
     |      lil_matrix(D)
     |          where D is a 2-D ndarray
     |
     |      lil_matrix(S)
     |          with another sparse array or matrix S (equivalent to S.tolil())
     |
     |      lil_matrix((M, N), [dtype])
     |          to construct an empty matrix with shape (M, N)
     |          dtype is optional, defaulting to dtype='d'.
     |
     |  Attributes
     |  ----------
     |  dtype : dtype
     |      Data type of the matrix
     |  shape : 2-tuple
     |      Shape of the matrix
     |  ndim : int
     |      Number of dimensions (this is always 2)
     |  nnz
     |  size
     |  data
     |      LIL format data array of the matrix
     |  rows
     |      LIL format row index array of the matrix
     |  T
     |
     |  Notes
     |  -----
     |  Sparse matrices can be used in arithmetic operations: they support
     |  addition, subtraction, multiplication, division, and matrix power.
     |
     |  Advantages of the LIL format
     |      - supports flexible slicing
     |      - changes to the matrix sparsity structure are efficient
     |
     |  Disadvantages of the LIL format
     |      - arithmetic operations LIL + LIL are slow (consider CSR or CSC)
     |      - slow column slicing (consider CSC)
     |      - slow matrix vector products (consider CSR or CSC)
     |
     |  Intended Usage
     |      - LIL is a convenient format for constructing sparse matrices
     |      - once a matrix has been constructed, convert to CSR or
     |        CSC format for fast arithmetic and matrix vector operations
     |      - consider using the COO format when constructing large matrices
     |
     |  Data Structure
     |      - An array (``self.rows``) of rows, each of which is a sorted
     |        list of column indices of non-zero elements.
     |      - The corresponding nonzero values are stored in similar
     |        fashion in ``self.data``.
     |
     |  Method resolution order:
     |      lil_matrix
     |      scipy.sparse._matrix.spmatrix
     |      _lil_base
     |      scipy.sparse._base._spbase
     |      scipy.sparse._index.IndexMixin
     |      builtins.object
     |
     |  Methods inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.sparse._matrix.spmatrix:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _lil_base:
     |
     |  __getitem__(self, key)
     |
     |  __iadd__(self, other)
     |
     |  __imul__(self, other)
     |
     |  __init__(self, arg1, shape=None, dtype=None, copy=False)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __isub__(self, other)
     |
     |  __itruediv__(self, other)
     |
     |  __setitem__(self, key, x)
     |
     |  __truediv__(self, other)
     |
     |  copy(self)
     |      Returns a copy of this array/matrix.
     |
     |      No data/indices will be shared between the returned value and current
     |      array/matrix.
     |
     |  count_nonzero(self)
     |      Number of non-zero entries, equivalent to
     |
     |      np.count_nonzero(a.toarray())
     |
     |      Unlike the nnz property, which return the number of stored
     |      entries (the length of the data attribute), this method counts the
     |      actual number of non-zero entries in data.
     |
     |  getrowview(self, i)
     |      Returns a view of the 'i'th row (without copying).
     |
     |  reshape(self, *args, **kwargs)
     |      reshape(self, shape, order='C', copy=False)
     |
     |      Gives a new shape to a sparse array/matrix without changing its data.
     |
     |      Parameters
     |      ----------
     |      shape : length-2 tuple of ints
     |          The new shape should be compatible with the original shape.
     |      order : {'C', 'F'}, optional
     |          Read the elements using this index order. 'C' means to read and
     |          write the elements using C-like index order; e.g., read entire first
     |          row, then second row, etc. 'F' means to read and write the elements
     |          using Fortran-like index order; e.g., read entire first column, then
     |          second column, etc.
     |      copy : bool, optional
     |          Indicates whether or not attributes of self should be copied
     |          whenever possible. The degree to which attributes are copied varies
     |          depending on the type of sparse array being used.
     |
     |      Returns
     |      -------
     |      reshaped : sparse array/matrix
     |          A sparse array/matrix with the given `shape`, not necessarily of the same
     |          format as the current object.
     |
     |      See Also
     |      --------
     |      numpy.reshape : NumPy's implementation of 'reshape' for ndarrays
     |
     |  resize(self, *shape)
     |      Resize the array/matrix in-place to dimensions given by ``shape``
     |
     |      Any elements that lie within the new shape will remain at the same
     |      indices, while non-zero elements lying outside the new shape are
     |      removed.
     |
     |      Parameters
     |      ----------
     |      shape : (int, int)
     |          number of rows and columns in the new array/matrix
     |
     |      Notes
     |      -----
     |      The semantics are not identical to `numpy.ndarray.resize` or
     |      `numpy.resize`. Here, the same data will be maintained at each index
     |      before and after reshape, if that index is within the new bounds. In
     |      numpy, resizing maintains contiguity of the array, moving elements
     |      around in the logical array but not within a flattened representation.
     |
     |      We give no guarantees about whether the underlying data attributes
     |      (arrays, etc.) will be modified in place or replaced with new objects.
     |
     |  toarray(self, order=None, out=None)
     |      Return a dense ndarray representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multidimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array as the output buffer
     |          instead of allocating a new array to return. The provided
     |          array must have the same shape and dtype as the sparse
     |          array/matrix on which you are calling the method. For most
     |          sparse types, `out` is required to be memory contiguous
     |          (either C or Fortran ordered).
     |
     |      Returns
     |      -------
     |      arr : ndarray, 2-D
     |          An array with the same shape and containing the same
     |          data represented by the sparse array/matrix, with the requested
     |          memory order. If `out` was passed, the same object is
     |          returned after being modified in-place to contain the
     |          appropriate values.
     |
     |  tocsr(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csr_array/matrix.
     |
     |  tolil(self, copy=False)
     |      Convert this array/matrix to List of Lists format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant lil_array/matrix.
     |
     |  transpose(self, axes=None, copy=False)
     |      Reverses the dimensions of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      axes : None, optional
     |          This argument is in the signature *solely* for NumPy
     |          compatibility reasons. Do not pass in anything except
     |          for the default value.
     |      copy : bool, optional
     |          Indicates whether or not attributes of `self` should be
     |          copied whenever possible. The degree to which attributes
     |          are copied varies depending on the type of sparse array/matrix
     |          being used.
     |
     |      Returns
     |      -------
     |      p : `self` with the dimensions reversed.
     |
     |      Notes
     |      -----
     |      If `self` is a `csr_array` or a `csc_array`, then this will return a
     |      `csc_array` or a `csr_array`, respectively.
     |
     |      See Also
     |      --------
     |      numpy.transpose : NumPy's implementation of 'transpose' for ndarrays
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.sparse._base._spbase:
     |
     |  __abs__(self)
     |
     |  __add__(self, other)
     |
     |  __bool__(self)
     |
     |  __div__(self, other)
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __ge__(self, other)
     |      Return self>=value.
     |
     |  __gt__(self, other)
     |      Return self>value.
     |
     |  __idiv__(self, other)
     |
     |  __iter__(self)
     |
     |  __le__(self, other)
     |      Return self<=value.
     |
     |  __len__(self)
     |      # What should len(sparse) return? For consistency with dense matrices,
     |      # perhaps it should be the number of rows?  But for some uses the number of
     |      # non-zeros is more important.  For now, raise an exception!
     |
     |  __lt__(self, other)
     |      Return self<value.
     |
     |  __matmul__(self, other)
     |
     |  __ne__(self, other)
     |      Return self!=value.
     |
     |  __neg__(self)
     |
     |  __nonzero__ = __bool__(self)
     |
     |  __radd__(self, other)
     |
     |  __rdiv__(self, other)
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __rmatmul__(self, other)
     |
     |  __round__(self, ndigits=0)
     |
     |  __rsub__(self, other)
     |
     |  __rtruediv__(self, other)
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  asformat(self, format, copy=False)
     |      Return this array/matrix in the passed format.
     |
     |      Parameters
     |      ----------
     |      format : {str, None}
     |          The desired sparse format ("csr", "csc", "lil", "dok", "array", ...)
     |          or None for no conversion.
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : This array/matrix in the passed format.
     |
     |  astype(self, dtype, casting='unsafe', copy=True)
     |      Cast the array/matrix elements to a specified type.
     |
     |      Parameters
     |      ----------
     |      dtype : string or numpy dtype
     |          Typecode or data-type to which to cast the data.
     |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
     |          Controls what kind of data casting may occur.
     |          Defaults to 'unsafe' for backwards compatibility.
     |          'no' means the data types should not be cast at all.
     |          'equiv' means only byte-order changes are allowed.
     |          'safe' means only casts which can preserve values are allowed.
     |          'same_kind' means only safe casts or casts within a kind,
     |          like float64 to float32, are allowed.
     |          'unsafe' means any data conversions may be done.
     |      copy : bool, optional
     |          If `copy` is `False`, the result might share some memory with this
     |          array/matrix. If `copy` is `True`, it is guaranteed that the result and
     |          this array/matrix do not share any memory.
     |
     |  conj(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  conjugate(self, copy=True)
     |      Element-wise complex conjugation.
     |
     |      If the array/matrix is of non-complex data type and `copy` is False,
     |      this method does nothing and the data is not copied.
     |
     |      Parameters
     |      ----------
     |      copy : bool, optional
     |          If True, the result is guaranteed to not share data with self.
     |
     |      Returns
     |      -------
     |      A : The element-wise complex conjugate.
     |
     |  diagonal(self, k=0)
     |      Returns the kth diagonal of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      k : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+k].
     |          Default: 0 (the main diagonal).
     |
     |          .. versionadded:: 1.0
     |
     |      See also
     |      --------
     |      numpy.diagonal : Equivalent numpy function.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> A.diagonal()
     |      array([1, 0, 5])
     |      >>> A.diagonal(k=1)
     |      array([2, 3])
     |
     |  dot(self, other)
     |      Ordinary dot product
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1, 2, 0], [0, 0, 3], [4, 0, 5]])
     |      >>> v = np.array([1, 0, -1])
     |      >>> A.dot(v)
     |      array([ 1, -3, -1], dtype=int64)
     |
     |  maximum(self, other)
     |      Element-wise maximum between this and another array/matrix.
     |
     |  mean(self, axis=None, dtype=None, out=None)
     |      Compute the arithmetic mean along the specified axis.
     |
     |      Returns the average of the array/matrix elements. The average is taken
     |      over all elements in the array/matrix by default, otherwise over the
     |      specified axis. `float64` intermediate and return values are used
     |      for integer inputs.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the mean is computed. The default is to compute
     |          the mean of all elements in the array/matrix (i.e., `axis` = `None`).
     |      dtype : data-type, optional
     |          Type to use in computing the mean. For integer inputs, the default
     |          is `float64`; for floating point inputs, it is the same as the
     |          input dtype.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      m : np.matrix
     |
     |      See Also
     |      --------
     |      numpy.matrix.mean : NumPy's implementation of 'mean' for matrices
     |
     |  minimum(self, other)
     |      Element-wise minimum between this and another array/matrix.
     |
     |  multiply(self, other)
     |      Point-wise multiplication by another array/matrix.
     |
     |  nonzero(self)
     |      Nonzero indices of the array/matrix.
     |
     |      Returns a tuple of arrays (row,col) containing the indices
     |      of the non-zero elements of the array.
     |
     |      Examples
     |      --------
     |      >>> from scipy.sparse import csr_array
     |      >>> A = csr_array([[1,2,0],[0,0,3],[4,0,5]])
     |      >>> A.nonzero()
     |      (array([0, 0, 1, 2, 2]), array([0, 1, 2, 0, 2]))
     |
     |  power(self, n, dtype=None)
     |      Element-wise power.
     |
     |  setdiag(self, values, k=0)
     |      Set diagonal or off-diagonal elements of the array/matrix.
     |
     |      Parameters
     |      ----------
     |      values : array_like
     |          New values of the diagonal elements.
     |
     |          Values may have any length. If the diagonal is longer than values,
     |          then the remaining diagonal entries will not be set. If values are
     |          longer than the diagonal, then the remaining values are ignored.
     |
     |          If a scalar value is given, all of the diagonal is set to it.
     |
     |      k : int, optional
     |          Which off-diagonal to set, corresponding to elements a[i,i+k].
     |          Default: 0 (the main diagonal).
     |
     |  sum(self, axis=None, dtype=None, out=None)
     |      Sum the array/matrix elements over a given axis.
     |
     |      Parameters
     |      ----------
     |      axis : {-2, -1, 0, 1, None} optional
     |          Axis along which the sum is computed. The default is to
     |          compute the sum of all the array/matrix elements, returning a scalar
     |          (i.e., `axis` = `None`).
     |      dtype : dtype, optional
     |          The type of the returned array/matrix and of the accumulator in which
     |          the elements are summed.  The dtype of `a` is used by default
     |          unless `a` has an integer dtype of less precision than the default
     |          platform integer.  In that case, if `a` is signed then the platform
     |          integer is used while if `a` is unsigned then an unsigned integer
     |          of the same precision as the platform integer is used.
     |
     |          .. versionadded:: 0.18.0
     |
     |      out : np.matrix, optional
     |          Alternative output matrix in which to place the result. It must
     |          have the same shape as the expected output, but the type of the
     |          output values will be cast if necessary.
     |
     |          .. versionadded:: 0.18.0
     |
     |      Returns
     |      -------
     |      sum_along_axis : np.matrix
     |          A matrix with the same shape as `self`, with the specified
     |          axis removed.
     |
     |      See Also
     |      --------
     |      numpy.matrix.sum : NumPy's implementation of 'sum' for matrices
     |
     |  tobsr(self, blocksize=None, copy=False)
     |      Convert this array/matrix to Block Sparse Row format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant bsr_array/matrix.
     |
     |      When blocksize=(R, C) is provided, it will be used for construction of
     |      the bsr_array/matrix.
     |
     |  tocoo(self, copy=False)
     |      Convert this array/matrix to COOrdinate format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant coo_array/matrix.
     |
     |  tocsc(self, copy=False)
     |      Convert this array/matrix to Compressed Sparse Column format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant csc_array/matrix.
     |
     |  todense(self, order=None, out=None)
     |      Return a dense representation of this sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      order : {'C', 'F'}, optional
     |          Whether to store multi-dimensional data in C (row-major)
     |          or Fortran (column-major) order in memory. The default
     |          is 'None', which provides no ordering guarantees.
     |          Cannot be specified in conjunction with the `out`
     |          argument.
     |
     |      out : ndarray, 2-D, optional
     |          If specified, uses this array (or `numpy.matrix`) as the
     |          output buffer instead of allocating a new array to
     |          return. The provided array must have the same shape and
     |          dtype as the sparse array/matrix on which you are calling the
     |          method.
     |
     |      Returns
     |      -------
     |      arr : numpy.matrix, 2-D
     |          A NumPy matrix object with the same shape and containing
     |          the same data represented by the sparse array/matrix, with the
     |          requested memory order. If `out` was passed and was an
     |          array (rather than a `numpy.matrix`), it will be filled
     |          with the appropriate values and returned wrapped in a
     |          `numpy.matrix` object that shares the same memory.
     |
     |  todia(self, copy=False)
     |      Convert this array/matrix to sparse DIAgonal format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dia_array/matrix.
     |
     |  todok(self, copy=False)
     |      Convert this array/matrix to Dictionary Of Keys format.
     |
     |      With copy=False, the data/indices may be shared between this array/matrix and
     |      the resultant dok_array/matrix.
     |
     |  trace(self, offset=0)
     |      Returns the sum along diagonals of the sparse array/matrix.
     |
     |      Parameters
     |      ----------
     |      offset : int, optional
     |          Which diagonal to get, corresponding to elements a[i, i+offset].
     |          Default: 0 (the main diagonal).
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from scipy.sparse._base._spbase:
     |
     |  T
     |      Transpose.
     |
     |  format
     |      Format string for matrix.
     |
     |  imag
     |
     |  ndim
     |
     |  nnz
     |      Number of stored values, including explicit zeros.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero entries
     |
     |  real
     |
     |  size
     |      Number of stored values.
     |
     |      See also
     |      --------
     |      count_nonzero : Number of non-zero values.
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.sparse._base._spbase:
     |
     |  __array_priority__ = 10.1
     |
     |  __hash__ = None

    class sparray(builtins.object)
     |  This class provides a base class for all sparse arrays.  It
     |  cannot be instantiated.  Most of the work is provided by subclasses.
     |
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class spmatrix(builtins.object)
     |  This class provides a base class for all sparse matrix classes.
     |
     |  It cannot be instantiated.  Most of the work is provided by subclasses.
     |
     |  Methods defined here:
     |
     |  __mul__(self, other)
     |      # Restore matrix multiplication
     |
     |  __pow__(self, power)
     |      # Restore matrix power
     |
     |  __rmul__(self, other)
     |
     |  asfptype(self)
     |      Upcast matrix to a floating point format (if necessary)
     |
     |  getH(self)
     |      Return the Hermitian transpose of this matrix.
     |
     |      See Also
     |      --------
     |      numpy.matrix.getH : NumPy's implementation of `getH` for matrices
     |
     |  get_shape(self)
     |      Get the shape of the matrix
     |
     |  getcol(self, j)
     |      Returns a copy of column j of the matrix, as an (m x 1) sparse
     |      matrix (column vector).
     |
     |  getformat(self)
     |      Matrix storage format
     |
     |  getmaxprint(self)
     |      Maximum number of elements to display when printed.
     |
     |  getnnz(self, axis=None)
     |      Number of stored values, including explicit zeros.
     |
     |      Parameters
     |      ----------
     |      axis : None, 0, or 1
     |          Select between the number of values across the whole array, in
     |          each column, or in each row.
     |
     |  getrow(self, i)
     |      Returns a copy of row i of the matrix, as a (1 x n) sparse
     |      matrix (row vector).
     |
     |  set_shape(self, shape)
     |      Set the shape of the matrix in-place
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  shape
     |      Shape of the matrix

FUNCTIONS
    block_array(blocks, *, format=None, dtype=None)
        Build a sparse array from sparse sub-blocks

        Parameters
        ----------
        blocks : array_like
            Grid of sparse arrays with compatible shapes.
            An entry of None implies an all-zero array.
        format : {'bsr', 'coo', 'csc', 'csr', 'dia', 'dok', 'lil'}, optional
            The sparse format of the result (e.g. "csr"). By default an
            appropriate sparse array format is returned.
            This choice is subject to change.
        dtype : dtype, optional
            The data-type of the output array. If not given, the dtype is
            determined from that of `blocks`.

        Returns
        -------
        block : sparse array

        See Also
        --------
        block_diag : specify blocks along the main diagonals
        diags : specify (possibly offset) diagonals

        Examples
        --------
        >>> from scipy.sparse import coo_array, block_array
        >>> A = coo_array([[1, 2], [3, 4]])
        >>> B = coo_array([[5], [6]])
        >>> C = coo_array([[7]])
        >>> block_array([[A, B], [None, C]]).toarray()
        array([[1, 2, 5],
               [3, 4, 6],
               [0, 0, 7]])

        >>> block_array([[A, None], [None, C]]).toarray()
        array([[1, 2, 0],
               [3, 4, 0],
               [0, 0, 7]])

    block_diag(mats, format=None, dtype=None)
        Build a block diagonal sparse matrix or array from provided matrices.

        Parameters
        ----------
        mats : sequence of matrices or arrays
            Input matrices or arrays.
        format : str, optional
            The sparse format of the result (e.g., "csr"). If not given, the result
            is returned in "coo" format.
        dtype : dtype specifier, optional
            The data-type of the output. If not given, the dtype is
            determined from that of `blocks`.

        Returns
        -------
        res : sparse matrix or array
            If at least one input is a sparse array, the output is a sparse array.
            Otherwise the output is a sparse matrix.

        Notes
        -----

        .. versionadded:: 0.11.0

        See Also
        --------
        block_array
        diags_array

        Examples
        --------
        >>> from scipy.sparse import coo_array, block_diag
        >>> A = coo_array([[1, 2], [3, 4]])
        >>> B = coo_array([[5], [6]])
        >>> C = coo_array([[7]])
        >>> block_diag((A, B, C)).toarray()
        array([[1, 2, 0, 0],
               [3, 4, 0, 0],
               [0, 0, 5, 0],
               [0, 0, 6, 0],
               [0, 0, 0, 7]])

    bmat(blocks, format=None, dtype=None)
        Build a sparse array or matrix from sparse sub-blocks

        Note: `block_array` is preferred over `bmat`. They are the same function
        except that `bmat` can return a deprecated sparse matrix.
        `bmat` returns a coo_matrix if none of the inputs are a sparse array.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``block_array`` to take advantage
            of the sparse array functionality.

        Parameters
        ----------
        blocks : array_like
            Grid of sparse matrices with compatible shapes.
            An entry of None implies an all-zero matrix.
        format : {'bsr', 'coo', 'csc', 'csr', 'dia', 'dok', 'lil'}, optional
            The sparse format of the result (e.g. "csr"). By default an
            appropriate sparse matrix format is returned.
            This choice is subject to change.
        dtype : dtype, optional
            The data-type of the output matrix. If not given, the dtype is
            determined from that of `blocks`.

        Returns
        -------
        bmat : sparse matrix or array
            If any block in blocks is a sparse array, return a sparse array.
            Otherwise return a sparse matrix.

            If you want a sparse array built from blocks that are not sparse
            arrays, use `block_array()`.

        See Also
        --------
        block_array

        Examples
        --------
        >>> from scipy.sparse import coo_array, bmat
        >>> A = coo_array([[1, 2], [3, 4]])
        >>> B = coo_array([[5], [6]])
        >>> C = coo_array([[7]])
        >>> bmat([[A, B], [None, C]]).toarray()
        array([[1, 2, 5],
               [3, 4, 6],
               [0, 0, 7]])

        >>> bmat([[A, None], [None, C]]).toarray()
        array([[1, 2, 0],
               [3, 4, 0],
               [0, 0, 7]])

    diags(diagonals, offsets=0, shape=None, format=None, dtype=None)
        Construct a sparse matrix from diagonals.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``diags_array`` to take advantage
            of the sparse array functionality.

        Parameters
        ----------
        diagonals : sequence of array_like
            Sequence of arrays containing the matrix diagonals,
            corresponding to `offsets`.
        offsets : sequence of int or an int, optional
            Diagonals to set:
              - k = 0  the main diagonal (default)
              - k > 0  the kth upper diagonal
              - k < 0  the kth lower diagonal
        shape : tuple of int, optional
            Shape of the result. If omitted, a square matrix large enough
            to contain the diagonals is returned.
        format : {"dia", "csr", "csc", "lil", ...}, optional
            Matrix format of the result. By default (format=None) an
            appropriate sparse matrix format is returned. This choice is
            subject to change.
        dtype : dtype, optional
            Data type of the matrix.

        See Also
        --------
        spdiags : construct matrix from diagonals
        diags_array : construct sparse array instead of sparse matrix

        Notes
        -----
        This function differs from `spdiags` in the way it handles
        off-diagonals.

        The result from `diags` is the sparse equivalent of::

            np.diag(diagonals[0], offsets[0])
            + ...
            + np.diag(diagonals[k], offsets[k])

        Repeated diagonal offsets are disallowed.

        .. versionadded:: 0.11

        Examples
        --------
        >>> from scipy.sparse import diags
        >>> diagonals = [[1, 2, 3, 4], [1, 2, 3], [1, 2]]
        >>> diags(diagonals, [0, -1, 2]).toarray()
        array([[1, 0, 1, 0],
               [1, 2, 0, 2],
               [0, 2, 3, 0],
               [0, 0, 3, 4]])

        Broadcasting of scalars is supported (but shape needs to be
        specified):

        >>> diags([1, -2, 1], [-1, 0, 1], shape=(4, 4)).toarray()
        array([[-2.,  1.,  0.,  0.],
               [ 1., -2.,  1.,  0.],
               [ 0.,  1., -2.,  1.],
               [ 0.,  0.,  1., -2.]])


        If only one diagonal is wanted (as in `numpy.diag`), the following
        works as well:

        >>> diags([1, 2, 3], 1).toarray()
        array([[ 0.,  1.,  0.,  0.],
               [ 0.,  0.,  2.,  0.],
               [ 0.,  0.,  0.,  3.],
               [ 0.,  0.,  0.,  0.]])

    diags_array(diagonals, /, *, offsets=0, shape=None, format=None, dtype=None)
        Construct a sparse array from diagonals.

        Parameters
        ----------
        diagonals : sequence of array_like
            Sequence of arrays containing the array diagonals,
            corresponding to `offsets`.
        offsets : sequence of int or an int, optional
            Diagonals to set:
              - k = 0  the main diagonal (default)
              - k > 0  the kth upper diagonal
              - k < 0  the kth lower diagonal
        shape : tuple of int, optional
            Shape of the result. If omitted, a square array large enough
            to contain the diagonals is returned.
        format : {"dia", "csr", "csc", "lil", ...}, optional
            Matrix format of the result. By default (format=None) an
            appropriate sparse array format is returned. This choice is
            subject to change.
        dtype : dtype, optional
            Data type of the array.

        Notes
        -----
        The result from `diags_array` is the sparse equivalent of::

            np.diag(diagonals[0], offsets[0])
            + ...
            + np.diag(diagonals[k], offsets[k])

        Repeated diagonal offsets are disallowed.

        .. versionadded:: 1.11

        Examples
        --------
        >>> from scipy.sparse import diags_array
        >>> diagonals = [[1, 2, 3, 4], [1, 2, 3], [1, 2]]
        >>> diags_array(diagonals, offsets=[0, -1, 2]).toarray()
        array([[1, 0, 1, 0],
               [1, 2, 0, 2],
               [0, 2, 3, 0],
               [0, 0, 3, 4]])

        Broadcasting of scalars is supported (but shape needs to be
        specified):

        >>> diags_array([1, -2, 1], offsets=[-1, 0, 1], shape=(4, 4)).toarray()
        array([[-2.,  1.,  0.,  0.],
               [ 1., -2.,  1.,  0.],
               [ 0.,  1., -2.,  1.],
               [ 0.,  0.,  1., -2.]])


        If only one diagonal is wanted (as in `numpy.diag`), the following
        works as well:

        >>> diags_array([1, 2, 3], offsets=1).toarray()
        array([[ 0.,  1.,  0.,  0.],
               [ 0.,  0.,  2.,  0.],
               [ 0.,  0.,  0.,  3.],
               [ 0.,  0.,  0.,  0.]])

    eye(m, n=None, k=0, dtype=<class 'float'>, format=None)
        Sparse matrix with ones on diagonal

        Returns a sparse matrix (m x n) where the kth diagonal
        is all ones and everything else is zeros.

        Parameters
        ----------
        m : int
            Number of rows in the matrix.
        n : int, optional
            Number of columns. Default: `m`.
        k : int, optional
            Diagonal to place ones on. Default: 0 (main diagonal).
        dtype : dtype, optional
            Data type of the matrix.
        format : str, optional
            Sparse format of the result, e.g., format="csr", etc.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``eye_array`` to take advantage
            of the sparse array functionality.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy as sp
        >>> sp.sparse.eye(3).toarray()
        array([[ 1.,  0.,  0.],
               [ 0.,  1.,  0.],
               [ 0.,  0.,  1.]])
        >>> sp.sparse.eye(3, dtype=np.int8)
        <DIAgonal sparse matrix of dtype 'int8'
            with 3 stored elements (1 diagonals) and shape (3, 3)>

    eye_array(m, n=None, *, k=0, dtype=<class 'float'>, format=None)
        Identity matrix in sparse array format

        Return a sparse array with ones on diagonal.
        Specifically a sparse array (m x n) where the kth diagonal
        is all ones and everything else is zeros.

        Parameters
        ----------
        m : int or tuple of ints
            Number of rows requested.
        n : int, optional
            Number of columns. Default: `m`.
        k : int, optional
            Diagonal to place ones on. Default: 0 (main diagonal).
        dtype : dtype, optional
            Data type of the array
        format : str, optional (default: "dia")
            Sparse format of the result, e.g., format="csr", etc.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy as sp
        >>> sp.sparse.eye_array(3).toarray()
        array([[ 1.,  0.,  0.],
               [ 0.,  1.,  0.],
               [ 0.,  0.,  1.]])
        >>> sp.sparse.eye_array(3, dtype=np.int8)
        <DIAgonal sparse array of dtype 'int8'
            with 3 stored elements (1 diagonals) and shape (3, 3)>

    find(A)
        Return the indices and values of the nonzero elements of a matrix

        Parameters
        ----------
        A : dense or sparse array or matrix
            Matrix whose nonzero elements are desired.

        Returns
        -------
        (I,J,V) : tuple of arrays
            I,J, and V contain the row indices, column indices, and values
            of the nonzero entries.


        Examples
        --------
        >>> from scipy.sparse import csr_array, find
        >>> A = csr_array([[7.0, 8.0, 0],[0, 0, 9.0]])
        >>> find(A)
        (array([0, 0, 1], dtype=int32),
         array([0, 1, 2], dtype=int32),
         array([ 7.,  8.,  9.]))

    hstack(blocks, format=None, dtype=None)
        Stack sparse matrices horizontally (column wise)

        Parameters
        ----------
        blocks
            sequence of sparse matrices with compatible shapes
        format : str
            sparse format of the result (e.g., "csr")
            by default an appropriate sparse matrix format is returned.
            This choice is subject to change.
        dtype : dtype, optional
            The data-type of the output matrix. If not given, the dtype is
            determined from that of `blocks`.

        Returns
        -------
        new_array : sparse matrix or array
            If any block in blocks is a sparse array, return a sparse array.
            Otherwise return a sparse matrix.

            If you want a sparse array built from blocks that are not sparse
            arrays, use `block(hstack(blocks))` or convert one block
            e.g. `blocks[0] = csr_array(blocks[0])`.

        See Also
        --------
        vstack : stack sparse matrices vertically (row wise)

        Examples
        --------
        >>> from scipy.sparse import coo_matrix, hstack
        >>> A = coo_matrix([[1, 2], [3, 4]])
        >>> B = coo_matrix([[5], [6]])
        >>> hstack([A,B]).toarray()
        array([[1, 2, 5],
               [3, 4, 6]])

    identity(n, dtype='d', format=None)
        Identity matrix in sparse format

        Returns an identity matrix with shape (n,n) using a given
        sparse format and dtype. This differs from `eye_array` in
        that it has a square shape with ones only on the main diagonal.
        It is thus the multiplicative identity. `eye_array` allows
        rectangular shapes and the diagonal can be offset from the main one.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``eye_array`` to take advantage
            of the sparse array functionality.

        Parameters
        ----------
        n : int
            Shape of the identity matrix.
        dtype : dtype, optional
            Data type of the matrix
        format : str, optional
            Sparse format of the result, e.g., format="csr", etc.

        Examples
        --------
        >>> import scipy as sp
        >>> sp.sparse.identity(3).toarray()
        array([[ 1.,  0.,  0.],
               [ 0.,  1.,  0.],
               [ 0.,  0.,  1.]])
        >>> sp.sparse.identity(3, dtype='int8', format='dia')
        <DIAgonal sparse matrix of dtype 'int8'
            with 3 stored elements (1 diagonals) and shape (3, 3)>
        >>> sp.sparse.eye_array(3, dtype='int8', format='dia')
        <DIAgonal sparse array of dtype 'int8'
            with 3 stored elements (1 diagonals) and shape (3, 3)>

    issparse(x)
        Is `x` of a sparse array or sparse matrix type?

        Parameters
        ----------
        x
            object to check for being a sparse array or sparse matrix

        Returns
        -------
        bool
            True if `x` is a sparse array or a sparse matrix, False otherwise

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.sparse import csr_array, csr_matrix, issparse
        >>> issparse(csr_matrix([[5]]))
        True
        >>> issparse(csr_array([[5]]))
        True
        >>> issparse(np.array([[5]]))
        False
        >>> issparse(5)
        False

    isspmatrix(x)
        Is `x` of a sparse matrix type?

        Parameters
        ----------
        x
            object to check for being a sparse matrix

        Returns
        -------
        bool
            True if `x` is a sparse matrix, False otherwise

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.sparse import csr_array, csr_matrix, isspmatrix
        >>> isspmatrix(csr_matrix([[5]]))
        True
        >>> isspmatrix(csr_array([[5]]))
        False
        >>> isspmatrix(np.array([[5]]))
        False
        >>> isspmatrix(5)
        False

    isspmatrix_bsr(x)
        Is `x` of a bsr_matrix type?

        Parameters
        ----------
        x
            object to check for being a bsr matrix

        Returns
        -------
        bool
            True if `x` is a bsr matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import bsr_array, bsr_matrix, csr_matrix, isspmatrix_bsr
        >>> isspmatrix_bsr(bsr_matrix([[5]]))
        True
        >>> isspmatrix_bsr(bsr_array([[5]]))
        False
        >>> isspmatrix_bsr(csr_matrix([[5]]))
        False

    isspmatrix_coo(x)
        Is `x` of coo_matrix type?

        Parameters
        ----------
        x
            object to check for being a coo matrix

        Returns
        -------
        bool
            True if `x` is a coo matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import coo_array, coo_matrix, csr_matrix, isspmatrix_coo
        >>> isspmatrix_coo(coo_matrix([[5]]))
        True
        >>> isspmatrix_coo(coo_array([[5]]))
        False
        >>> isspmatrix_coo(csr_matrix([[5]]))
        False

    isspmatrix_csc(x)
        Is `x` of csc_matrix type?

        Parameters
        ----------
        x
            object to check for being a csc matrix

        Returns
        -------
        bool
            True if `x` is a csc matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import csc_array, csc_matrix, coo_matrix, isspmatrix_csc
        >>> isspmatrix_csc(csc_matrix([[5]]))
        True
        >>> isspmatrix_csc(csc_array([[5]]))
        False
        >>> isspmatrix_csc(coo_matrix([[5]]))
        False

    isspmatrix_csr(x)
        Is `x` of csr_matrix type?

        Parameters
        ----------
        x
            object to check for being a csr matrix

        Returns
        -------
        bool
            True if `x` is a csr matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import csr_array, csr_matrix, coo_matrix, isspmatrix_csr
        >>> isspmatrix_csr(csr_matrix([[5]]))
        True
        >>> isspmatrix_csr(csr_array([[5]]))
        False
        >>> isspmatrix_csr(coo_matrix([[5]]))
        False

    isspmatrix_dia(x)
        Is `x` of dia_matrix type?

        Parameters
        ----------
        x
            object to check for being a dia matrix

        Returns
        -------
        bool
            True if `x` is a dia matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import dia_array, dia_matrix, coo_matrix, isspmatrix_dia
        >>> isspmatrix_dia(dia_matrix([[5]]))
        True
        >>> isspmatrix_dia(dia_array([[5]]))
        False
        >>> isspmatrix_dia(coo_matrix([[5]]))
        False

    isspmatrix_dok(x)
        Is `x` of dok_array type?

        Parameters
        ----------
        x
            object to check for being a dok matrix

        Returns
        -------
        bool
            True if `x` is a dok matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import dok_array, dok_matrix, coo_matrix, isspmatrix_dok
        >>> isspmatrix_dok(dok_matrix([[5]]))
        True
        >>> isspmatrix_dok(dok_array([[5]]))
        False
        >>> isspmatrix_dok(coo_matrix([[5]]))
        False

    isspmatrix_lil(x)
        Is `x` of lil_matrix type?

        Parameters
        ----------
        x
            object to check for being a lil matrix

        Returns
        -------
        bool
            True if `x` is a lil matrix, False otherwise

        Examples
        --------
        >>> from scipy.sparse import lil_array, lil_matrix, coo_matrix, isspmatrix_lil
        >>> isspmatrix_lil(lil_matrix([[5]]))
        True
        >>> isspmatrix_lil(lil_array([[5]]))
        False
        >>> isspmatrix_lil(coo_matrix([[5]]))
        False

    kron(A, B, format=None)
        kronecker product of sparse matrices A and B

        Parameters
        ----------
        A : sparse or dense matrix
            first matrix of the product
        B : sparse or dense matrix
            second matrix of the product
        format : str, optional (default: 'bsr' or 'coo')
            format of the result (e.g. "csr")
            If None, choose 'bsr' for relatively dense array and 'coo' for others

        Returns
        -------
        kronecker product in a sparse format.
        Returns a sparse matrix unless either A or B is a
        sparse array in which case returns a sparse array.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy as sp
        >>> A = sp.sparse.csr_array(np.array([[0, 2], [5, 0]]))
        >>> B = sp.sparse.csr_array(np.array([[1, 2], [3, 4]]))
        >>> sp.sparse.kron(A, B).toarray()
        array([[ 0,  0,  2,  4],
               [ 0,  0,  6,  8],
               [ 5, 10,  0,  0],
               [15, 20,  0,  0]])

        >>> sp.sparse.kron(A, [[1, 2], [3, 4]]).toarray()
        array([[ 0,  0,  2,  4],
               [ 0,  0,  6,  8],
               [ 5, 10,  0,  0],
               [15, 20,  0,  0]])

    kronsum(A, B, format=None)
        kronecker sum of square sparse matrices A and B

        Kronecker sum of two sparse matrices is a sum of two Kronecker
        products kron(I_n,A) + kron(B,I_m) where A has shape (m,m)
        and B has shape (n,n) and I_m and I_n are identity matrices
        of shape (m,m) and (n,n), respectively.

        Parameters
        ----------
        A
            square matrix
        B
            square matrix
        format : str
            format of the result (e.g. "csr")

        Returns
        -------
        kronecker sum in a sparse matrix format

    load_npz(file)
        Load a sparse array/matrix from a file using ``.npz`` format.

        Parameters
        ----------
        file : str or file-like object
            Either the file name (string) or an open file (file-like object)
            where the data will be loaded.

        Returns
        -------
        result : csc_array, csr_array, bsr_array, dia_array or coo_array
            A sparse array/matrix containing the loaded data.

        Raises
        ------
        OSError
            If the input file does not exist or cannot be read.

        See Also
        --------
        scipy.sparse.save_npz: Save a sparse array/matrix to a file using ``.npz`` format.
        numpy.load: Load several arrays from a ``.npz`` archive.

        Examples
        --------
        Store sparse array/matrix to disk, and load it again:

        >>> import numpy as np
        >>> import scipy as sp
        >>> sparse_array = sp.sparse.csc_array([[0, 0, 3], [4, 0, 0]])
        >>> sparse_array
        <Compressed Sparse Column sparse array of dtype 'int64'
            with 2 stored elements and shape (2, 3)>
        >>> sparse_array.toarray()
        array([[0, 0, 3],
               [4, 0, 0]], dtype=int64)

        >>> sp.sparse.save_npz('/tmp/sparse_array.npz', sparse_array)
        >>> sparse_array = sp.sparse.load_npz('/tmp/sparse_array.npz')

        >>> sparse_array
        <Compressed Sparse Column sparse array of dtype 'int64'
            with 2 stored elements and shape (2, 3)>
        >>> sparse_array.toarray()
        array([[0, 0, 3],
               [4, 0, 0]], dtype=int64)

        In this example we force the result to be csr_array from csr_matrix
        >>> sparse_matrix = sp.sparse.csc_matrix([[0, 0, 3], [4, 0, 0]])
        >>> sp.sparse.save_npz('/tmp/sparse_matrix.npz', sparse_matrix)
        >>> tmp = sp.sparse.load_npz('/tmp/sparse_matrix.npz')
        >>> sparse_array = sp.sparse.csr_array(tmp)

    rand(m, n, density=0.01, format='coo', dtype=None, random_state=None)
        Generate a sparse matrix of the given shape and density with uniformly
        distributed values.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``random_array`` to take advantage
            of the sparse array functionality.

        Parameters
        ----------
        m, n : int
            shape of the matrix
        density : real, optional
            density of the generated matrix: density equal to one means a full
            matrix, density of 0 means a matrix with no non-zero items.
        format : str, optional
            sparse matrix format.
        dtype : dtype, optional
            type of the returned matrix values.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

        Returns
        -------
        res : sparse matrix

        Notes
        -----
        Only float types are supported for now.

        See Also
        --------
        random : Similar function allowing a custom random data sampler
        random_array : Similar to random() but returns a sparse array

        Examples
        --------
        >>> from scipy.sparse import rand
        >>> matrix = rand(3, 4, density=0.25, format="csr", random_state=42)
        >>> matrix
        <Compressed Sparse Row sparse matrix of dtype 'float64'
            with 3 stored elements and shape (3, 4)>
        >>> matrix.toarray()
        array([[0.05641158, 0.        , 0.        , 0.65088847],  # random
               [0.        , 0.        , 0.        , 0.14286682],
               [0.        , 0.        , 0.        , 0.        ]])

    random(m, n, density=0.01, format='coo', dtype=None, random_state=None, data_rvs=None)
        Generate a sparse matrix of the given shape and density with randomly
        distributed values.

        .. warning::

            Since numpy 1.17, passing a ``np.random.Generator`` (e.g.
            ``np.random.default_rng``) for ``random_state`` will lead to much
            faster execution times.

            A much slower implementation is used by default for backwards
            compatibility.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``random_array`` to take advantage of the
            sparse array functionality.

        Parameters
        ----------
        m, n : int
            shape of the matrix
        density : real, optional
            density of the generated matrix: density equal to one means a full
            matrix, density of 0 means a matrix with no non-zero items.
        format : str, optional
            sparse matrix format.
        dtype : dtype, optional
            type of the returned matrix values.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            - If `seed` is None (or `np.random`), the `numpy.random.RandomState`
              singleton is used.
            - If `seed` is an int, a new ``RandomState`` instance is used,
              seeded with `seed`.
            - If `seed` is already a ``Generator`` or ``RandomState`` instance then
              that instance is used.

            This random state will be used for sampling the sparsity structure, but
            not necessarily for sampling the values of the structurally nonzero
            entries of the matrix.
        data_rvs : callable, optional
            Samples a requested number of random values.
            This function should take a single argument specifying the length
            of the ndarray that it will return. The structurally nonzero entries
            of the sparse random matrix will be taken from the array sampled
            by this function. By default, uniform [0, 1) random values will be
            sampled using the same random state as is used for sampling
            the sparsity structure.

        Returns
        -------
        res : sparse matrix

        See Also
        --------
        random_array : constructs sparse arrays instead of sparse matrices

        Examples
        --------

        Passing a ``np.random.Generator`` instance for better performance:

        >>> import scipy as sp
        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng)

        Providing a sampler for the values:

        >>> rvs = sp.stats.poisson(25, loc=10).rvs
        >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng, data_rvs=rvs)
        >>> S.toarray()
        array([[ 36.,   0.,  33.,   0.],   # random
               [  0.,   0.,   0.,   0.],
               [  0.,   0.,  36.,   0.]])

        Building a custom distribution.
        This example builds a squared normal from np.random:

        >>> def np_normal_squared(size=None, random_state=rng):
        ...     return random_state.standard_normal(size) ** 2
        >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng,
        ...                      data_rvs=np_normal_squared)

        Or we can build it from sp.stats style rvs functions:

        >>> def sp_stats_normal_squared(size=None, random_state=rng):
        ...     std_normal = sp.stats.distributions.norm_gen().rvs
        ...     return std_normal(size=size, random_state=random_state) ** 2
        >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng,
        ...                      data_rvs=sp_stats_normal_squared)

        Or we can subclass sp.stats rv_continous or rv_discrete:

        >>> class NormalSquared(sp.stats.rv_continuous):
        ...     def _rvs(self,  size=None, random_state=rng):
        ...         return random_state.standard_normal(size) ** 2
        >>> X = NormalSquared()
        >>> Y = X()  # get a frozen version of the distribution
        >>> S = sp.sparse.random(3, 4, density=0.25, random_state=rng, data_rvs=Y.rvs)

    random_array(shape, *, density=0.01, format='coo', dtype=None, random_state=None, data_sampler=None)
        Return a sparse array of uniformly random numbers in [0, 1)

        Returns a sparse array with the given shape and density
        where values are generated uniformly randomly in the range [0, 1).

        .. warning::

            Since numpy 1.17, passing a ``np.random.Generator`` (e.g.
            ``np.random.default_rng``) for ``random_state`` will lead to much
            faster execution times.

            A much slower implementation is used by default for backwards
            compatibility.

        Parameters
        ----------
        shape : int or tuple of ints
            shape of the array
        density : real, optional (default: 0.01)
            density of the generated matrix: density equal to one means a full
            matrix, density of 0 means a matrix with no non-zero items.
        format : str, optional (default: 'coo')
            sparse matrix format.
        dtype : dtype, optional (default: np.float64)
            type of the returned matrix values.
        random_state : {None, int, `Generator`, `RandomState`}, optional
            A random number generator to determine nonzero structure. We recommend using
            a `numpy.random.Generator` manually provided for every call as it is much
            faster than RandomState.

            - If `None` (or `np.random`), the `numpy.random.RandomState`
              singleton is used.
            - If an int, a new ``Generator`` instance is used,
              seeded with the int.
            - If a ``Generator`` or ``RandomState`` instance then
              that instance is used.

            This random state will be used for sampling `indices` (the sparsity
            structure), and by default for the data values too (see `data_sampler`).

        data_sampler : callable, optional (default depends on dtype)
            Sampler of random data values with keyword arg `size`.
            This function should take a single keyword argument `size` specifying
            the length of its returned ndarray. It is used to generate the nonzero
            values in the matrix after the locations of those values are chosen.
            By default, uniform [0, 1) random values are used unless `dtype` is
            an integer (default uniform integers from that dtype) or
            complex (default uniform over the unit square in the complex plane).
            For these, the `random_state` rng is used e.g. `rng.uniform(size=size)`.

        Returns
        -------
        res : sparse array

        Examples
        --------

        Passing a ``np.random.Generator`` instance for better performance:

        >>> import numpy as np
        >>> import scipy as sp
        >>> rng = np.random.default_rng()

        Default sampling uniformly from [0, 1):

        >>> S = sp.sparse.random_array((3, 4), density=0.25, random_state=rng)

        Providing a sampler for the values:

        >>> rvs = sp.stats.poisson(25, loc=10).rvs
        >>> S = sp.sparse.random_array((3, 4), density=0.25,
        ...                            random_state=rng, data_sampler=rvs)
        >>> S.toarray()
        array([[ 36.,   0.,  33.,   0.],   # random
               [  0.,   0.,   0.,   0.],
               [  0.,   0.,  36.,   0.]])

        Building a custom distribution.
        This example builds a squared normal from np.random:

        >>> def np_normal_squared(size=None, random_state=rng):
        ...     return random_state.standard_normal(size) ** 2
        >>> S = sp.sparse.random_array((3, 4), density=0.25, random_state=rng,
        ...                      data_sampler=np_normal_squared)

        Or we can build it from sp.stats style rvs functions:

        >>> def sp_stats_normal_squared(size=None, random_state=rng):
        ...     std_normal = sp.stats.distributions.norm_gen().rvs
        ...     return std_normal(size=size, random_state=random_state) ** 2
        >>> S = sp.sparse.random_array((3, 4), density=0.25, random_state=rng,
        ...                      data_sampler=sp_stats_normal_squared)

        Or we can subclass sp.stats rv_continous or rv_discrete:

        >>> class NormalSquared(sp.stats.rv_continuous):
        ...     def _rvs(self,  size=None, random_state=rng):
        ...         return random_state.standard_normal(size) ** 2
        >>> X = NormalSquared()
        >>> Y = X().rvs
        >>> S = sp.sparse.random_array((3, 4), density=0.25,
        ...                            random_state=rng, data_sampler=Y)

    save_npz(file, matrix, compressed=True)
        Save a sparse matrix or array to a file using ``.npz`` format.

        Parameters
        ----------
        file : str or file-like object
            Either the file name (string) or an open file (file-like object)
            where the data will be saved. If file is a string, the ``.npz``
            extension will be appended to the file name if it is not already
            there.
        matrix: spmatrix or sparray
            The sparse matrix or array to save.
            Supported formats: ``csc``, ``csr``, ``bsr``, ``dia`` or ``coo``.
        compressed : bool, optional
            Allow compressing the file. Default: True

        See Also
        --------
        scipy.sparse.load_npz: Load a sparse matrix from a file using ``.npz`` format.
        numpy.savez: Save several arrays into a ``.npz`` archive.
        numpy.savez_compressed : Save several arrays into a compressed ``.npz`` archive.

        Examples
        --------
        Store sparse matrix to disk, and load it again:

        >>> import numpy as np
        >>> import scipy as sp
        >>> sparse_matrix = sp.sparse.csc_matrix([[0, 0, 3], [4, 0, 0]])
        >>> sparse_matrix
        <Compressed Sparse Column sparse matrix of dtype 'int64'
            with 2 stored elements and shape (2, 3)>
        >>> sparse_matrix.toarray()
        array([[0, 0, 3],
               [4, 0, 0]], dtype=int64)

        >>> sp.sparse.save_npz('/tmp/sparse_matrix.npz', sparse_matrix)
        >>> sparse_matrix = sp.sparse.load_npz('/tmp/sparse_matrix.npz')

        >>> sparse_matrix
        <Compressed Sparse Column sparse matrix of dtype 'int64'
            with 2 stored elements and shape (2, 3)>
        >>> sparse_matrix.toarray()
        array([[0, 0, 3],
               [4, 0, 0]], dtype=int64)

    spdiags(data, diags, m=None, n=None, format=None)
        Return a sparse matrix from diagonals.

        Parameters
        ----------
        data : array_like
            Matrix diagonals stored row-wise
        diags : sequence of int or an int
            Diagonals to set:

            * k = 0  the main diagonal
            * k > 0  the kth upper diagonal
            * k < 0  the kth lower diagonal
        m, n : int, tuple, optional
            Shape of the result. If `n` is None and `m` is a given tuple,
            the shape is this tuple. If omitted, the matrix is square and
            its shape is len(data[0]).
        format : str, optional
            Format of the result. By default (format=None) an appropriate sparse
            matrix format is returned. This choice is subject to change.

        .. warning::

            This function returns a sparse matrix -- not a sparse array.
            You are encouraged to use ``diags_array`` to take advantage
            of the sparse array functionality.

        See Also
        --------
        diags_array : more convenient form of this function
        diags : matrix version of diags_array
        dia_matrix : the sparse DIAgonal format.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.sparse import spdiags
        >>> data = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
        >>> diags = np.array([0, -1, 2])
        >>> spdiags(data, diags, 4, 4).toarray()
        array([[1, 0, 3, 0],
               [1, 2, 0, 4],
               [0, 2, 3, 0],
               [0, 0, 3, 4]])

    tril(A, k=0, format=None)
        Return the lower triangular portion of a sparse array or matrix

        Returns the elements on or below the k-th diagonal of A.
            - k = 0 corresponds to the main diagonal
            - k > 0 is above the main diagonal
            - k < 0 is below the main diagonal

        Parameters
        ----------
        A : dense or sparse array or matrix
            Matrix whose lower trianglar portion is desired.
        k : integer : optional
            The top-most diagonal of the lower triangle.
        format : string
            Sparse format of the result, e.g. format="csr", etc.

        Returns
        -------
        L : sparse matrix
            Lower triangular portion of A in sparse format.

        See Also
        --------
        triu : upper triangle in sparse format

        Examples
        --------
        >>> from scipy.sparse import csr_array, tril
        >>> A = csr_array([[1, 2, 0, 0, 3], [4, 5, 0, 6, 7], [0, 0, 8, 9, 0]],
        ...               dtype='int32')
        >>> A.toarray()
        array([[1, 2, 0, 0, 3],
               [4, 5, 0, 6, 7],
               [0, 0, 8, 9, 0]])
        >>> tril(A).toarray()
        array([[1, 0, 0, 0, 0],
               [4, 5, 0, 0, 0],
               [0, 0, 8, 0, 0]])
        >>> tril(A).nnz
        4
        >>> tril(A, k=1).toarray()
        array([[1, 2, 0, 0, 0],
               [4, 5, 0, 0, 0],
               [0, 0, 8, 9, 0]])
        >>> tril(A, k=-1).toarray()
        array([[0, 0, 0, 0, 0],
               [4, 0, 0, 0, 0],
               [0, 0, 0, 0, 0]])
        >>> tril(A, format='csc')
        <Compressed Sparse Column sparse array of dtype 'int32'
            with 4 stored elements and shape (3, 5)>

    triu(A, k=0, format=None)
        Return the upper triangular portion of a sparse array or matrix

        Returns the elements on or above the k-th diagonal of A.
            - k = 0 corresponds to the main diagonal
            - k > 0 is above the main diagonal
            - k < 0 is below the main diagonal

        Parameters
        ----------
        A : dense or sparse array or matrix
            Matrix whose upper trianglar portion is desired.
        k : integer : optional
            The bottom-most diagonal of the upper triangle.
        format : string
            Sparse format of the result, e.g. format="csr", etc.

        Returns
        -------
        L : sparse array or matrix
            Upper triangular portion of A in sparse format.
            Sparse array if A is a sparse array, otherwise matrix.

        See Also
        --------
        tril : lower triangle in sparse format

        Examples
        --------
        >>> from scipy.sparse import csr_array, triu
        >>> A = csr_array([[1, 2, 0, 0, 3], [4, 5, 0, 6, 7], [0, 0, 8, 9, 0]],
        ...                dtype='int32')
        >>> A.toarray()
        array([[1, 2, 0, 0, 3],
               [4, 5, 0, 6, 7],
               [0, 0, 8, 9, 0]])
        >>> triu(A).toarray()
        array([[1, 2, 0, 0, 3],
               [0, 5, 0, 6, 7],
               [0, 0, 8, 9, 0]])
        >>> triu(A).nnz
        8
        >>> triu(A, k=1).toarray()
        array([[0, 2, 0, 0, 3],
               [0, 0, 0, 6, 7],
               [0, 0, 0, 9, 0]])
        >>> triu(A, k=-1).toarray()
        array([[1, 2, 0, 0, 3],
               [4, 5, 0, 6, 7],
               [0, 0, 8, 9, 0]])
        >>> triu(A, format='csc')
        <Compressed Sparse Column sparse array of dtype 'int32'
            with 8 stored elements and shape (3, 5)>

    vstack(blocks, format=None, dtype=None)
        Stack sparse arrays vertically (row wise)

        Parameters
        ----------
        blocks
            sequence of sparse arrays with compatible shapes
        format : str, optional
            sparse format of the result (e.g., "csr")
            by default an appropriate sparse array format is returned.
            This choice is subject to change.
        dtype : dtype, optional
            The data-type of the output array. If not given, the dtype is
            determined from that of `blocks`.

        Returns
        -------
        new_array : sparse matrix or array
            If any block in blocks is a sparse array, return a sparse array.
            Otherwise return a sparse matrix.

            If you want a sparse array built from blocks that are not sparse
            arrays, use `block(vstack(blocks))` or convert one block
            e.g. `blocks[0] = csr_array(blocks[0])`.

        See Also
        --------
        hstack : stack sparse matrices horizontally (column wise)

        Examples
        --------
        >>> from scipy.sparse import coo_array, vstack
        >>> A = coo_array([[1, 2], [3, 4]])
        >>> B = coo_array([[5, 6]])
        >>> vstack([A, B]).toarray()
        array([[1, 2],
               [3, 4],
               [5, 6]])

DATA
    __all__ = ['SparseEfficiencyWarning', 'SparseWarning', 'base', 'block_...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\sparse\__init__.py

scipy.spatial
Python Library Documentation: package scipy.spatial in scipy

NAME
    scipy.spatial

DESCRIPTION
    =============================================================
    Spatial algorithms and data structures (:mod:`scipy.spatial`)
    =============================================================

    .. currentmodule:: scipy.spatial

    .. toctree::
       :hidden:

       spatial.distance

    Spatial transformations
    =======================

    These are contained in the `scipy.spatial.transform` submodule.

    Nearest-neighbor queries
    ========================
    .. autosummary::
       :toctree: generated/

       KDTree      -- class for efficient nearest-neighbor queries
       cKDTree     -- class for efficient nearest-neighbor queries (faster implementation)
       Rectangle

    Distance metrics
    ================

    Distance metrics are contained in the :mod:`scipy.spatial.distance` submodule.

    Delaunay triangulation, convex hulls, and Voronoi diagrams
    ==========================================================

    .. autosummary::
       :toctree: generated/

       Delaunay    -- compute Delaunay triangulation of input points
       ConvexHull  -- compute a convex hull for input points
       Voronoi     -- compute a Voronoi diagram hull from input points
       SphericalVoronoi -- compute a Voronoi diagram from input points on the surface of a sphere
       HalfspaceIntersection -- compute the intersection points of input halfspaces

    Plotting helpers
    ================

    .. autosummary::
       :toctree: generated/

       delaunay_plot_2d     -- plot 2-D triangulation
       convex_hull_plot_2d  -- plot 2-D convex hull
       voronoi_plot_2d      -- plot 2-D Voronoi diagram

    .. seealso:: :ref:`Tutorial <qhulltutorial>`


    Simplex representation
    ======================
    The simplices (triangles, tetrahedra, etc.) appearing in the Delaunay
    tessellation (N-D simplices), convex hull facets, and Voronoi ridges
    (N-1-D simplices) are represented in the following scheme::

        tess = Delaunay(points)
        hull = ConvexHull(points)
        voro = Voronoi(points)

        # coordinates of the jth vertex of the ith simplex
        tess.points[tess.simplices[i, j], :]        # tessellation element
        hull.points[hull.simplices[i, j], :]        # convex hull facet
        voro.vertices[voro.ridge_vertices[i, j], :] # ridge between Voronoi cells

    For Delaunay triangulations and convex hulls, the neighborhood
    structure of the simplices satisfies the condition:
    ``tess.neighbors[i,j]`` is the neighboring simplex of the ith
    simplex, opposite to the ``j``-vertex. It is -1 in case of no neighbor.

    Convex hull facets also define a hyperplane equation::

        (hull.equations[i,:-1] * coord).sum() + hull.equations[i,-1] == 0

    Similar hyperplane equations for the Delaunay triangulation correspond
    to the convex hull facets on the corresponding N+1-D
    paraboloid.

    The Delaunay triangulation objects offer a method for locating the
    simplex containing a given point, and barycentric coordinate
    computations.

    Functions
    ---------

    .. autosummary::
       :toctree: generated/

       tsearch
       distance_matrix
       minkowski_distance
       minkowski_distance_p
       procrustes
       geometric_slerp

    Warnings / Errors used in :mod:`scipy.spatial`
    ----------------------------------------------
    .. autosummary::
       :toctree: generated/

       QhullError

PACKAGE CONTENTS
    _ckdtree
    _distance_pybind
    _distance_wrap
    _geometric_slerp
    _hausdorff
    _kdtree
    _plotutils
    _procrustes
    _qhull
    _spherical_voronoi
    _voronoi
    ckdtree
    distance
    kdtree
    qhull
    tests (package)
    transform (package)

CLASSES
    builtins.RuntimeError(builtins.Exception)
        scipy.spatial._qhull.QhullError
    builtins.object
        scipy.spatial._ckdtree.cKDTree
            scipy.spatial._kdtree.KDTree
        scipy.spatial._kdtree.Rectangle
        scipy.spatial._spherical_voronoi.SphericalVoronoi
    scipy.spatial._qhull._QhullUser(builtins.object)
        scipy.spatial._qhull.ConvexHull
        scipy.spatial._qhull.Delaunay
        scipy.spatial._qhull.HalfspaceIntersection
        scipy.spatial._qhull.Voronoi

    class ConvexHull(_QhullUser)
     |  ConvexHull(points, incremental=False, qhull_options=None)
     |
     |  ConvexHull(points, incremental=False, qhull_options=None)
     |
     |  Convex hulls in N dimensions.
     |
     |  .. versionadded:: 0.12.0
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndim)
     |      Coordinates of points to construct a convex hull from
     |  incremental : bool, optional
     |      Allow adding new points incrementally. This takes up some additional
     |      resources.
     |  qhull_options : str, optional
     |      Additional options to pass to Qhull. See Qhull manual
     |      for details. (Default: "Qx" for ndim > 4 and "" otherwise)
     |      Option "Qt" is always enabled.
     |
     |  Attributes
     |  ----------
     |  points : ndarray of double, shape (npoints, ndim)
     |      Coordinates of input points.
     |  vertices : ndarray of ints, shape (nvertices,)
     |      Indices of points forming the vertices of the convex hull.
     |      For 2-D convex hulls, the vertices are in counterclockwise order.
     |      For other dimensions, they are in input order.
     |  simplices : ndarray of ints, shape (nfacet, ndim)
     |      Indices of points forming the simplical facets of the convex hull.
     |  neighbors : ndarray of ints, shape (nfacet, ndim)
     |      Indices of neighbor facets for each facet.
     |      The kth neighbor is opposite to the kth vertex.
     |      -1 denotes no neighbor.
     |  equations : ndarray of double, shape (nfacet, ndim+1)
     |      [normal, offset] forming the hyperplane equation of the facet
     |      (see `Qhull documentation <http://www.qhull.org/>`__  for more).
     |  coplanar : ndarray of int, shape (ncoplanar, 3)
     |      Indices of coplanar points and the corresponding indices of
     |      the nearest facets and nearest vertex indices.  Coplanar
     |      points are input points which were *not* included in the
     |      triangulation due to numerical precision issues.
     |
     |      If option "Qc" is not specified, this list is not computed.
     |  good : ndarray of bool or None
     |      A one-dimensional Boolean array indicating which facets are
     |      good. Used with options that compute good facets, e.g. QGn
     |      and QG-n. Good facets are defined as those that are
     |      visible (n) or invisible (-n) from point n, where
     |      n is the nth point in 'points'. The 'good' attribute may be
     |      used as an index into 'simplices' to return the good (visible)
     |      facets: simplices[good]. A facet is visible from the outside
     |      of the hull only, and neither coplanarity nor degeneracy count
     |      as cases of visibility.
     |
     |      If a "QGn" or "QG-n" option is not specified, None is returned.
     |
     |      .. versionadded:: 1.3.0
     |  area : float
     |      Surface area of the convex hull when input dimension > 2.
     |      When input `points` are 2-dimensional, this is the perimeter of the convex hull.
     |
     |      .. versionadded:: 0.17.0
     |  volume : float
     |      Volume of the convex hull when input dimension > 2.
     |      When input `points` are 2-dimensional, this is the area of the convex hull.
     |
     |      .. versionadded:: 0.17.0
     |
     |  Raises
     |  ------
     |  QhullError
     |      Raised when Qhull encounters an error condition, such as
     |      geometrical degeneracy when options to resolve are not enabled.
     |  ValueError
     |      Raised if an incompatible array is given as input.
     |
     |  Notes
     |  -----
     |  The convex hull is computed using the
     |  `Qhull library <http://www.qhull.org/>`__.
     |
     |  Examples
     |  --------
     |
     |  Convex hull of a random set of points:
     |
     |  >>> from scipy.spatial import ConvexHull, convex_hull_plot_2d
     |  >>> import numpy as np
     |  >>> rng = np.random.default_rng()
     |  >>> points = rng.random((30, 2))   # 30 random points in 2-D
     |  >>> hull = ConvexHull(points)
     |
     |  Plot it:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> plt.plot(points[:,0], points[:,1], 'o')
     |  >>> for simplex in hull.simplices:
     |  ...     plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
     |
     |  We could also have directly used the vertices of the hull, which
     |  for 2-D are guaranteed to be in counterclockwise order:
     |
     |  >>> plt.plot(points[hull.vertices,0], points[hull.vertices,1], 'r--', lw=2)
     |  >>> plt.plot(points[hull.vertices[0],0], points[hull.vertices[0],1], 'ro')
     |  >>> plt.show()
     |
     |  Facets visible from a point:
     |
     |  Create a square and add a point above the square.
     |
     |  >>> generators = np.array([[0.2, 0.2],
     |  ...                        [0.2, 0.4],
     |  ...                        [0.4, 0.4],
     |  ...                        [0.4, 0.2],
     |  ...                        [0.3, 0.6]])
     |
     |  Call ConvexHull with the QG option. QG4 means
     |  compute the portions of the hull not including
     |  point 4, indicating the facets that are visible
     |  from point 4.
     |
     |  >>> hull = ConvexHull(points=generators,
     |  ...                   qhull_options='QG4')
     |
     |  The "good" array indicates which facets are
     |  visible from point 4.
     |
     |  >>> print(hull.simplices)
     |      [[1 0]
     |       [1 2]
     |       [3 0]
     |       [3 2]]
     |  >>> print(hull.good)
     |      [False  True False False]
     |
     |  Now plot it, highlighting the visible facets.
     |
     |  >>> fig = plt.figure()
     |  >>> ax = fig.add_subplot(1,1,1)
     |  >>> for visible_facet in hull.simplices[hull.good]:
     |  ...     ax.plot(hull.points[visible_facet, 0],
     |  ...             hull.points[visible_facet, 1],
     |  ...             color='violet',
     |  ...             lw=6)
     |  >>> convex_hull_plot_2d(hull, ax=ax)
     |      <Figure size 640x480 with 1 Axes> # may vary
     |  >>> plt.show()
     |
     |  References
     |  ----------
     |  .. [Qhull] http://www.qhull.org/
     |
     |  Method resolution order:
     |      ConvexHull
     |      _QhullUser
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, points, incremental=False, qhull_options=None)
     |
     |  add_points(self, points, restart=False)
     |      add_points(points, restart=False)
     |
     |      Process a set of additional new points.
     |
     |      Parameters
     |      ----------
     |      points : ndarray
     |          New points to add. The dimensionality should match that of the
     |          initial points.
     |      restart : bool, optional
     |          Whether to restart processing from scratch, rather than
     |          adding points incrementally.
     |
     |      Raises
     |      ------
     |      QhullError
     |          Raised when Qhull encounters an error condition, such as
     |          geometrical degeneracy when options to resolve are not enabled.
     |
     |      See Also
     |      --------
     |      close
     |
     |      Notes
     |      -----
     |      You need to specify ``incremental=True`` when constructing the
     |      object to be able to add points incrementally. Incremental addition
     |      of points is also not possible after `close` has been called.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  points
     |
     |  vertices
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _QhullUser:
     |
     |  __del__(self)
     |
     |  close(self)
     |      close()
     |
     |      Finish incremental processing.
     |
     |      Call this to free resources taken up by Qhull, when using the
     |      incremental mode. After calling this, adding more points is no
     |      longer possible.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _QhullUser:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class Delaunay(_QhullUser)
     |  Delaunay(points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  Delaunay(points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  Delaunay tessellation in N dimensions.
     |
     |  .. versionadded:: 0.9
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndim)
     |      Coordinates of points to triangulate
     |  furthest_site : bool, optional
     |      Whether to compute a furthest-site Delaunay triangulation.
     |      Default: False
     |
     |      .. versionadded:: 0.12.0
     |  incremental : bool, optional
     |      Allow adding new points incrementally. This takes up some additional
     |      resources.
     |  qhull_options : str, optional
     |      Additional options to pass to Qhull. See Qhull manual for
     |      details. Option "Qt" is always enabled.
     |      Default:"Qbb Qc Qz Qx Q12" for ndim > 4 and "Qbb Qc Qz Q12" otherwise.
     |      Incremental mode omits "Qz".
     |
     |      .. versionadded:: 0.12.0
     |
     |  Attributes
     |  ----------
     |  points : ndarray of double, shape (npoints, ndim)
     |      Coordinates of input points.
     |  simplices : ndarray of ints, shape (nsimplex, ndim+1)
     |      Indices of the points forming the simplices in the triangulation.
     |      For 2-D, the points are oriented counterclockwise.
     |  neighbors : ndarray of ints, shape (nsimplex, ndim+1)
     |      Indices of neighbor simplices for each simplex.
     |      The kth neighbor is opposite to the kth vertex.
     |      For simplices at the boundary, -1 denotes no neighbor.
     |  equations : ndarray of double, shape (nsimplex, ndim+2)
     |      [normal, offset] forming the hyperplane equation of the facet
     |      on the paraboloid
     |      (see `Qhull documentation <http://www.qhull.org/>`__ for more).
     |  paraboloid_scale, paraboloid_shift : float
     |      Scale and shift for the extra paraboloid dimension
     |      (see `Qhull documentation <http://www.qhull.org/>`__ for more).
     |  transform : ndarray of double, shape (nsimplex, ndim+1, ndim)
     |      Affine transform from ``x`` to the barycentric coordinates ``c``.
     |      This is defined by::
     |
     |          T c = x - r
     |
     |      At vertex ``j``, ``c_j = 1`` and the other coordinates zero.
     |
     |      For simplex ``i``, ``transform[i,:ndim,:ndim]`` contains
     |      inverse of the matrix ``T``, and ``transform[i,ndim,:]``
     |      contains the vector ``r``.
     |
     |      If the simplex is degenerate or nearly degenerate, its
     |      barycentric transform contains NaNs.
     |  vertex_to_simplex : ndarray of int, shape (npoints,)
     |      Lookup array, from a vertex, to some simplex which it is a part of.
     |      If qhull option "Qc" was not specified, the list will contain -1
     |      for points that are not vertices of the tessellation.
     |  convex_hull : ndarray of int, shape (nfaces, ndim)
     |      Vertices of facets forming the convex hull of the point set.
     |      The array contains the indices of the points belonging to
     |      the (N-1)-dimensional facets that form the convex hull
     |      of the triangulation.
     |
     |      .. note::
     |
     |         Computing convex hulls via the Delaunay triangulation is
     |         inefficient and subject to increased numerical instability.
     |         Use `ConvexHull` instead.
     |  coplanar : ndarray of int, shape (ncoplanar, 3)
     |      Indices of coplanar points and the corresponding indices of
     |      the nearest facet and the nearest vertex.  Coplanar
     |      points are input points which were *not* included in the
     |      triangulation due to numerical precision issues.
     |
     |      If option "Qc" is not specified, this list is not computed.
     |
     |      .. versionadded:: 0.12.0
     |  vertex_neighbor_vertices : tuple of two ndarrays of int; (indptr, indices)
     |      Neighboring vertices of vertices. The indices of neighboring
     |      vertices of vertex `k` are ``indices[indptr[k]:indptr[k+1]]``.
     |  furthest_site
     |      True if this was a furthest site triangulation and False if not.
     |
     |      .. versionadded:: 1.4.0
     |
     |  Raises
     |  ------
     |  QhullError
     |      Raised when Qhull encounters an error condition, such as
     |      geometrical degeneracy when options to resolve are not enabled.
     |  ValueError
     |      Raised if an incompatible array is given as input.
     |
     |  Notes
     |  -----
     |  The tessellation is computed using the Qhull library
     |  `Qhull library <http://www.qhull.org/>`__.
     |
     |  .. note::
     |
     |     Unless you pass in the Qhull option "QJ", Qhull does not
     |     guarantee that each input point appears as a vertex in the
     |     Delaunay triangulation. Omitted points are listed in the
     |     `coplanar` attribute.
     |
     |  Examples
     |  --------
     |  Triangulation of a set of points:
     |
     |  >>> import numpy as np
     |  >>> points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1]])
     |  >>> from scipy.spatial import Delaunay
     |  >>> tri = Delaunay(points)
     |
     |  We can plot it:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> plt.triplot(points[:,0], points[:,1], tri.simplices)
     |  >>> plt.plot(points[:,0], points[:,1], 'o')
     |  >>> plt.show()
     |
     |  Point indices and coordinates for the two triangles forming the
     |  triangulation:
     |
     |  >>> tri.simplices
     |  array([[2, 3, 0],                 # may vary
     |         [3, 1, 0]], dtype=int32)
     |
     |  Note that depending on how rounding errors go, the simplices may
     |  be in a different order than above.
     |
     |  >>> points[tri.simplices]
     |  array([[[ 1. ,  0. ],            # may vary
     |          [ 1. ,  1. ],
     |          [ 0. ,  0. ]],
     |         [[ 1. ,  1. ],
     |          [ 0. ,  1.1],
     |          [ 0. ,  0. ]]])
     |
     |  Triangle 0 is the only neighbor of triangle 1, and it's opposite to
     |  vertex 1 of triangle 1:
     |
     |  >>> tri.neighbors[1]
     |  array([-1,  0, -1], dtype=int32)
     |  >>> points[tri.simplices[1,1]]
     |  array([ 0. ,  1.1])
     |
     |  We can find out which triangle points are in:
     |
     |  >>> p = np.array([(0.1, 0.2), (1.5, 0.5), (0.5, 1.05)])
     |  >>> tri.find_simplex(p)
     |  array([ 1, -1, 1], dtype=int32)
     |
     |  The returned integers in the array are the indices of the simplex the
     |  corresponding point is in. If -1 is returned, the point is in no simplex.
     |  Be aware that the shortcut in the following example only works correctly
     |  for valid points as invalid points result in -1 which is itself a valid
     |  index for the last simplex in the list.
     |
     |  >>> p_valids = np.array([(0.1, 0.2), (0.5, 1.05)])
     |  >>> tri.simplices[tri.find_simplex(p_valids)]
     |  array([[3, 1, 0],                 # may vary
     |         [3, 1, 0]], dtype=int32)
     |
     |  We can also compute barycentric coordinates in triangle 1 for
     |  these points:
     |
     |  >>> b = tri.transform[1,:2].dot(np.transpose(p - tri.transform[1,2]))
     |  >>> np.c_[np.transpose(b), 1 - b.sum(axis=0)]
     |  array([[ 0.1       ,  0.09090909,  0.80909091],
     |         [ 1.5       , -0.90909091,  0.40909091],
     |         [ 0.5       ,  0.5       ,  0.        ]])
     |
     |  The coordinates for the first point are all positive, meaning it
     |  is indeed inside the triangle. The third point is on an edge,
     |  hence its null third coordinate.
     |
     |  Method resolution order:
     |      Delaunay
     |      _QhullUser
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  add_points(self, points, restart=False)
     |      add_points(points, restart=False)
     |
     |      Process a set of additional new points.
     |
     |      Parameters
     |      ----------
     |      points : ndarray
     |          New points to add. The dimensionality should match that of the
     |          initial points.
     |      restart : bool, optional
     |          Whether to restart processing from scratch, rather than
     |          adding points incrementally.
     |
     |      Raises
     |      ------
     |      QhullError
     |          Raised when Qhull encounters an error condition, such as
     |          geometrical degeneracy when options to resolve are not enabled.
     |
     |      See Also
     |      --------
     |      close
     |
     |      Notes
     |      -----
     |      You need to specify ``incremental=True`` when constructing the
     |      object to be able to add points incrementally. Incremental addition
     |      of points is also not possible after `close` has been called.
     |
     |  find_simplex(self, xi, bruteforce=False, tol=None)
     |      find_simplex(self, xi, bruteforce=False, tol=None)
     |
     |      Find the simplices containing the given points.
     |
     |      Parameters
     |      ----------
     |      tri : DelaunayInfo
     |          Delaunay triangulation
     |      xi : ndarray of double, shape (..., ndim)
     |          Points to locate
     |      bruteforce : bool, optional
     |          Whether to only perform a brute-force search
     |      tol : float, optional
     |          Tolerance allowed in the inside-triangle check.
     |          Default is ``100*eps``.
     |
     |      Returns
     |      -------
     |      i : ndarray of int, same shape as `xi`
     |          Indices of simplices containing each point.
     |          Points outside the triangulation get the value -1.
     |
     |      Notes
     |      -----
     |      This uses an algorithm adapted from Qhull's ``qh_findbestfacet``,
     |      which makes use of the connection between a convex hull and a
     |      Delaunay triangulation. After finding the simplex closest to
     |      the point in N+1 dimensions, the algorithm falls back to
     |      directed search in N dimensions.
     |
     |  lift_points(self, x)
     |      lift_points(self, x)
     |
     |      Lift points to the Qhull paraboloid.
     |
     |  plane_distance(self, xi)
     |      plane_distance(self, xi)
     |
     |      Compute hyperplane distances to the point `xi` from all simplices.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  convex_hull
     |      Vertices of facets forming the convex hull of the point set.
     |
     |      :type: *ndarray of int, shape (nfaces, ndim)*
     |
     |      The array contains the indices of the points
     |      belonging to the (N-1)-dimensional facets that form the convex
     |      hull of the triangulation.
     |
     |      .. note::
     |
     |         Computing convex hulls via the Delaunay triangulation is
     |         inefficient and subject to increased numerical instability.
     |         Use `ConvexHull` instead.
     |
     |  points
     |
     |  transform
     |      Affine transform from ``x`` to the barycentric coordinates ``c``.
     |
     |      :type: *ndarray of double, shape (nsimplex, ndim+1, ndim)*
     |
     |      This is defined by::
     |
     |          T c = x - r
     |
     |      At vertex ``j``, ``c_j = 1`` and the other coordinates zero.
     |
     |      For simplex ``i``, ``transform[i,:ndim,:ndim]`` contains
     |      inverse of the matrix ``T``, and ``transform[i,ndim,:]``
     |      contains the vector ``r``.
     |
     |  vertex_neighbor_vertices
     |      Neighboring vertices of vertices.
     |
     |      Tuple of two ndarrays of int: (indptr, indices). The indices of
     |      neighboring vertices of vertex `k` are
     |      ``indices[indptr[k]:indptr[k+1]]``.
     |
     |  vertex_to_simplex
     |      Lookup array, from a vertex, to some simplex which it is a part of.
     |
     |      :type: *ndarray of int, shape (npoints,)*
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _QhullUser:
     |
     |  __del__(self)
     |
     |  close(self)
     |      close()
     |
     |      Finish incremental processing.
     |
     |      Call this to free resources taken up by Qhull, when using the
     |      incremental mode. After calling this, adding more points is no
     |      longer possible.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _QhullUser:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class HalfspaceIntersection(_QhullUser)
     |  HalfspaceIntersection(halfspaces, interior_point, incremental=False, qhull_options=None)
     |
     |  HalfspaceIntersection(halfspaces, interior_point, incremental=False, qhull_options=None)
     |
     |  Halfspace intersections in N dimensions.
     |
     |  .. versionadded:: 0.19.0
     |
     |  Parameters
     |  ----------
     |  halfspaces : ndarray of floats, shape (nineq, ndim+1)
     |      Stacked Inequalities of the form Ax + b <= 0 in format [A; b]
     |  interior_point : ndarray of floats, shape (ndim,)
     |      Point clearly inside the region defined by halfspaces. Also called a feasible
     |      point, it can be obtained by linear programming.
     |  incremental : bool, optional
     |      Allow adding new halfspaces incrementally. This takes up some additional
     |      resources.
     |  qhull_options : str, optional
     |      Additional options to pass to Qhull. See Qhull manual
     |      for details. (Default: "Qx" for ndim > 4 and "" otherwise)
     |      Option "H" is always enabled.
     |
     |  Attributes
     |  ----------
     |  halfspaces : ndarray of double, shape (nineq, ndim+1)
     |      Input halfspaces.
     |  interior_point :ndarray of floats, shape (ndim,)
     |      Input interior point.
     |  intersections : ndarray of double, shape (ninter, ndim)
     |      Intersections of all halfspaces.
     |  dual_points : ndarray of double, shape (nineq, ndim)
     |      Dual points of the input halfspaces.
     |  dual_facets : list of lists of ints
     |      Indices of points forming the (non necessarily simplicial) facets of
     |      the dual convex hull.
     |  dual_vertices : ndarray of ints, shape (nvertices,)
     |      Indices of halfspaces forming the vertices of the dual convex hull.
     |      For 2-D convex hulls, the vertices are in counterclockwise order.
     |      For other dimensions, they are in input order.
     |  dual_equations : ndarray of double, shape (nfacet, ndim+1)
     |      [normal, offset] forming the hyperplane equation of the dual facet
     |      (see `Qhull documentation <http://www.qhull.org/>`__  for more).
     |  dual_area : float
     |      Area of the dual convex hull
     |  dual_volume : float
     |      Volume of the dual convex hull
     |
     |  Raises
     |  ------
     |  QhullError
     |      Raised when Qhull encounters an error condition, such as
     |      geometrical degeneracy when options to resolve are not enabled.
     |  ValueError
     |      Raised if an incompatible array is given as input.
     |
     |  Notes
     |  -----
     |  The intersections are computed using the
     |  `Qhull library <http://www.qhull.org/>`__.
     |  This reproduces the "qhalf" functionality of Qhull.
     |
     |  Examples
     |  --------
     |
     |  Halfspace intersection of planes forming some polygon
     |
     |  >>> from scipy.spatial import HalfspaceIntersection
     |  >>> import numpy as np
     |  >>> halfspaces = np.array([[-1, 0., 0.],
     |  ...                        [0., -1., 0.],
     |  ...                        [2., 1., -4.],
     |  ...                        [-0.5, 1., -2.]])
     |  >>> feasible_point = np.array([0.5, 0.5])
     |  >>> hs = HalfspaceIntersection(halfspaces, feasible_point)
     |
     |  Plot halfspaces as filled regions and intersection points:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig = plt.figure()
     |  >>> ax = fig.add_subplot(1, 1, 1, aspect='equal')
     |  >>> xlim, ylim = (-1, 3), (-1, 3)
     |  >>> ax.set_xlim(xlim)
     |  >>> ax.set_ylim(ylim)
     |  >>> x = np.linspace(-1, 3, 100)
     |  >>> symbols = ['-', '+', 'x', '*']
     |  >>> signs = [0, 0, -1, -1]
     |  >>> fmt = {"color": None, "edgecolor": "b", "alpha": 0.5}
     |  >>> for h, sym, sign in zip(halfspaces, symbols, signs):
     |  ...     hlist = h.tolist()
     |  ...     fmt["hatch"] = sym
     |  ...     if h[1]== 0:
     |  ...         ax.axvline(-h[2]/h[0], label='{}x+{}y+{}=0'.format(*hlist))
     |  ...         xi = np.linspace(xlim[sign], -h[2]/h[0], 100)
     |  ...         ax.fill_between(xi, ylim[0], ylim[1], **fmt)
     |  ...     else:
     |  ...         ax.plot(x, (-h[2]-h[0]*x)/h[1], label='{}x+{}y+{}=0'.format(*hlist))
     |  ...         ax.fill_between(x, (-h[2]-h[0]*x)/h[1], ylim[sign], **fmt)
     |  >>> x, y = zip(*hs.intersections)
     |  >>> ax.plot(x, y, 'o', markersize=8)
     |
     |  By default, qhull does not provide with a way to compute an interior point.
     |  This can easily be computed using linear programming. Considering halfspaces
     |  of the form :math:`Ax + b \leq 0`, solving the linear program:
     |
     |  .. math::
     |
     |      max \: y
     |
     |      s.t. Ax + y ||A_i|| \leq -b
     |
     |  With :math:`A_i` being the rows of A, i.e. the normals to each plane.
     |
     |  Will yield a point x that is furthest inside the convex polyhedron. To
     |  be precise, it is the center of the largest hypersphere of radius y
     |  inscribed in the polyhedron. This point is called the Chebyshev center
     |  of the polyhedron (see [1]_ 4.3.1, pp148-149). The
     |  equations outputted by Qhull are always normalized.
     |
     |  >>> from scipy.optimize import linprog
     |  >>> from matplotlib.patches import Circle
     |  >>> norm_vector = np.reshape(np.linalg.norm(halfspaces[:, :-1], axis=1),
     |  ...     (halfspaces.shape[0], 1))
     |  >>> c = np.zeros((halfspaces.shape[1],))
     |  >>> c[-1] = -1
     |  >>> A = np.hstack((halfspaces[:, :-1], norm_vector))
     |  >>> b = - halfspaces[:, -1:]
     |  >>> res = linprog(c, A_ub=A, b_ub=b, bounds=(None, None))
     |  >>> x = res.x[:-1]
     |  >>> y = res.x[-1]
     |  >>> circle = Circle(x, radius=y, alpha=0.3)
     |  >>> ax.add_patch(circle)
     |  >>> plt.legend(bbox_to_anchor=(1.6, 1.0))
     |  >>> plt.show()
     |
     |  References
     |  ----------
     |  .. [Qhull] http://www.qhull.org/
     |  .. [1] S. Boyd, L. Vandenberghe, Convex Optimization, available
     |         at http://stanford.edu/~boyd/cvxbook/
     |
     |  Method resolution order:
     |      HalfspaceIntersection
     |      _QhullUser
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, halfspaces, interior_point, incremental=False, qhull_options=None)
     |
     |  add_halfspaces(self, halfspaces, restart=False)
     |      add_halfspaces(halfspaces, restart=False)
     |
     |      Process a set of additional new halfspaces.
     |
     |      Parameters
     |      ----------
     |      halfspaces : ndarray
     |          New halfspaces to add. The dimensionality should match that of the
     |          initial halfspaces.
     |      restart : bool, optional
     |          Whether to restart processing from scratch, rather than
     |          adding halfspaces incrementally.
     |
     |      Raises
     |      ------
     |      QhullError
     |          Raised when Qhull encounters an error condition, such as
     |          geometrical degeneracy when options to resolve are not enabled.
     |
     |      See Also
     |      --------
     |      close
     |
     |      Notes
     |      -----
     |      You need to specify ``incremental=True`` when constructing the
     |      object to be able to add halfspaces incrementally. Incremental addition
     |      of halfspaces is also not possible after `close` has been called.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  dual_vertices
     |
     |  halfspaces
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _QhullUser:
     |
     |  __del__(self)
     |
     |  close(self)
     |      close()
     |
     |      Finish incremental processing.
     |
     |      Call this to free resources taken up by Qhull, when using the
     |      incremental mode. After calling this, adding more points is no
     |      longer possible.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _QhullUser:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class KDTree(scipy.spatial._ckdtree.cKDTree)
     |  KDTree(data, leafsize=10, compact_nodes=True, copy_data=False, balanced_tree=True, boxsize=None)
     |
     |  kd-tree for quick nearest-neighbor lookup.
     |
     |  This class provides an index into a set of k-dimensional points
     |  which can be used to rapidly look up the nearest neighbors of any
     |  point.
     |
     |  Parameters
     |  ----------
     |  data : array_like, shape (n,m)
     |      The n data points of dimension m to be indexed. This array is
     |      not copied unless this is necessary to produce a contiguous
     |      array of doubles, and so modifying this data will result in
     |      bogus results. The data are also copied if the kd-tree is built
     |      with copy_data=True.
     |  leafsize : positive int, optional
     |      The number of points at which the algorithm switches over to
     |      brute-force.  Default: 10.
     |  compact_nodes : bool, optional
     |      If True, the kd-tree is built to shrink the hyperrectangles to
     |      the actual data range. This usually gives a more compact tree that
     |      is robust against degenerated input data and gives faster queries
     |      at the expense of longer build time. Default: True.
     |  copy_data : bool, optional
     |      If True the data is always copied to protect the kd-tree against
     |      data corruption. Default: False.
     |  balanced_tree : bool, optional
     |      If True, the median is used to split the hyperrectangles instead of
     |      the midpoint. This usually gives a more compact tree and
     |      faster queries at the expense of longer build time. Default: True.
     |  boxsize : array_like or scalar, optional
     |      Apply a m-d toroidal topology to the KDTree.. The topology is generated
     |      by :math:`x_i + n_i L_i` where :math:`n_i` are integers and :math:`L_i`
     |      is the boxsize along i-th dimension. The input data shall be wrapped
     |      into :math:`[0, L_i)`. A ValueError is raised if any of the data is
     |      outside of this bound.
     |
     |  Notes
     |  -----
     |  The algorithm used is described in Maneewongvatana and Mount 1999.
     |  The general idea is that the kd-tree is a binary tree, each of whose
     |  nodes represents an axis-aligned hyperrectangle. Each node specifies
     |  an axis and splits the set of points based on whether their coordinate
     |  along that axis is greater than or less than a particular value.
     |
     |  During construction, the axis and splitting point are chosen by the
     |  "sliding midpoint" rule, which ensures that the cells do not all
     |  become long and thin.
     |
     |  The tree can be queried for the r closest neighbors of any given point
     |  (optionally returning only those within some maximum distance of the
     |  point). It can also be queried, with a substantial gain in efficiency,
     |  for the r approximate closest neighbors.
     |
     |  For large dimensions (20 is already large) do not expect this to run
     |  significantly faster than brute force. High-dimensional nearest-neighbor
     |  queries are a substantial open problem in computer science.
     |
     |  Attributes
     |  ----------
     |  data : ndarray, shape (n,m)
     |      The n data points of dimension m to be indexed. This array is
     |      not copied unless this is necessary to produce a contiguous
     |      array of doubles. The data are also copied if the kd-tree is built
     |      with `copy_data=True`.
     |  leafsize : positive int
     |      The number of points at which the algorithm switches over to
     |      brute-force.
     |  m : int
     |      The dimension of a single data-point.
     |  n : int
     |      The number of data points.
     |  maxes : ndarray, shape (m,)
     |      The maximum value in each dimension of the n data points.
     |  mins : ndarray, shape (m,)
     |      The minimum value in each dimension of the n data points.
     |  size : int
     |      The number of nodes in the tree.
     |
     |  Method resolution order:
     |      KDTree
     |      scipy.spatial._ckdtree.cKDTree
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, data, leafsize=10, compact_nodes=True, copy_data=False, balanced_tree=True, boxsize=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  count_neighbors(self, other, r, p=2.0, weights=None, cumulative=True)
     |      Count how many nearby pairs can be formed.
     |
     |      Count the number of pairs ``(x1,x2)`` can be formed, with ``x1`` drawn
     |      from ``self`` and ``x2`` drawn from ``other``, and where
     |      ``distance(x1, x2, p) <= r``.
     |
     |      Data points on ``self`` and ``other`` are optionally weighted by the
     |      ``weights`` argument. (See below)
     |
     |      This is adapted from the "two-point correlation" algorithm described by
     |      Gray and Moore [1]_.  See notes for further discussion.
     |
     |      Parameters
     |      ----------
     |      other : KDTree
     |          The other tree to draw points from, can be the same tree as self.
     |      r : float or one-dimensional array of floats
     |          The radius to produce a count for. Multiple radii are searched with
     |          a single tree traversal.
     |          If the count is non-cumulative(``cumulative=False``), ``r`` defines
     |          the edges of the bins, and must be non-decreasing.
     |      p : float, optional
     |          1<=p<=infinity.
     |          Which Minkowski p-norm to use.
     |          Default 2.0.
     |          A finite large p may cause a ValueError if overflow can occur.
     |      weights : tuple, array_like, or None, optional
     |          If None, the pair-counting is unweighted.
     |          If given as a tuple, weights[0] is the weights of points in
     |          ``self``, and weights[1] is the weights of points in ``other``;
     |          either can be None to indicate the points are unweighted.
     |          If given as an array_like, weights is the weights of points in
     |          ``self`` and ``other``. For this to make sense, ``self`` and
     |          ``other`` must be the same tree. If ``self`` and ``other`` are two
     |          different trees, a ``ValueError`` is raised.
     |          Default: None
     |
     |          .. versionadded:: 1.6.0
     |      cumulative : bool, optional
     |          Whether the returned counts are cumulative. When cumulative is set
     |          to ``False`` the algorithm is optimized to work with a large number
     |          of bins (>10) specified by ``r``. When ``cumulative`` is set to
     |          True, the algorithm is optimized to work with a small number of
     |          ``r``. Default: True
     |
     |          .. versionadded:: 1.6.0
     |
     |      Returns
     |      -------
     |      result : scalar or 1-D array
     |          The number of pairs. For unweighted counts, the result is integer.
     |          For weighted counts, the result is float.
     |          If cumulative is False, ``result[i]`` contains the counts with
     |          ``(-inf if i == 0 else r[i-1]) < R <= r[i]``
     |
     |      Notes
     |      -----
     |      Pair-counting is the basic operation used to calculate the two point
     |      correlation functions from a data set composed of position of objects.
     |
     |      Two point correlation function measures the clustering of objects and
     |      is widely used in cosmology to quantify the large scale structure
     |      in our Universe, but it may be useful for data analysis in other fields
     |      where self-similar assembly of objects also occur.
     |
     |      The Landy-Szalay estimator for the two point correlation function of
     |      ``D`` measures the clustering signal in ``D``. [2]_
     |
     |      For example, given the position of two sets of objects,
     |
     |      - objects ``D`` (data) contains the clustering signal, and
     |
     |      - objects ``R`` (random) that contains no signal,
     |
     |      .. math::
     |
     |           \xi(r) = \frac{<D, D> - 2 f <D, R> + f^2<R, R>}{f^2<R, R>},
     |
     |      where the brackets represents counting pairs between two data sets
     |      in a finite bin around ``r`` (distance), corresponding to setting
     |      `cumulative=False`, and ``f = float(len(D)) / float(len(R))`` is the
     |      ratio between number of objects from data and random.
     |
     |      The algorithm implemented here is loosely based on the dual-tree
     |      algorithm described in [1]_. We switch between two different
     |      pair-cumulation scheme depending on the setting of ``cumulative``.
     |      The computing time of the method we use when for
     |      ``cumulative == False`` does not scale with the total number of bins.
     |      The algorithm for ``cumulative == True`` scales linearly with the
     |      number of bins, though it is slightly faster when only
     |      1 or 2 bins are used. [5]_.
     |
     |      As an extension to the naive pair-counting,
     |      weighted pair-counting counts the product of weights instead
     |      of number of pairs.
     |      Weighted pair-counting is used to estimate marked correlation functions
     |      ([3]_, section 2.2),
     |      or to properly calculate the average of data per distance bin
     |      (e.g. [4]_, section 2.1 on redshift).
     |
     |      .. [1] Gray and Moore,
     |             "N-body problems in statistical learning",
     |             Mining the sky, 2000,
     |             https://arxiv.org/abs/astro-ph/0012333
     |
     |      .. [2] Landy and Szalay,
     |             "Bias and variance of angular correlation functions",
     |             The Astrophysical Journal, 1993,
     |             http://adsabs.harvard.edu/abs/1993ApJ...412...64L
     |
     |      .. [3] Sheth, Connolly and Skibba,
     |             "Marked correlations in galaxy formation models",
     |             Arxiv e-print, 2005,
     |             https://arxiv.org/abs/astro-ph/0511773
     |
     |      .. [4] Hawkins, et al.,
     |             "The 2dF Galaxy Redshift Survey: correlation functions,
     |             peculiar velocities and the matter density of the Universe",
     |             Monthly Notices of the Royal Astronomical Society, 2002,
     |             http://adsabs.harvard.edu/abs/2003MNRAS.346...78H
     |
     |      .. [5] https://github.com/scipy/scipy/pull/5647#issuecomment-168474926
     |
     |      Examples
     |      --------
     |      You can count neighbors number between two kd-trees within a distance:
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import KDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((5, 2))
     |      >>> points2 = rng.random((5, 2))
     |      >>> kd_tree1 = KDTree(points1)
     |      >>> kd_tree2 = KDTree(points2)
     |      >>> kd_tree1.count_neighbors(kd_tree2, 0.2)
     |      1
     |
     |      This number is same as the total pair number calculated by
     |      `query_ball_tree`:
     |
     |      >>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
     |      >>> sum([len(i) for i in indexes])
     |      1
     |
     |  query(self, x, k=1, eps=0, p=2, distance_upper_bound=inf, workers=1)
     |      Query the kd-tree for nearest neighbors.
     |
     |      Parameters
     |      ----------
     |      x : array_like, last dimension self.m
     |          An array of points to query.
     |      k : int or Sequence[int], optional
     |          Either the number of nearest neighbors to return, or a list of the
     |          k-th nearest neighbors to return, starting from 1.
     |      eps : nonnegative float, optional
     |          Return approximate nearest neighbors; the kth returned value
     |          is guaranteed to be no further than (1+eps) times the
     |          distance to the real kth nearest neighbor.
     |      p : float, 1<=p<=infinity, optional
     |          Which Minkowski p-norm to use.
     |          1 is the sum-of-absolute-values distance ("Manhattan" distance).
     |          2 is the usual Euclidean distance.
     |          infinity is the maximum-coordinate-difference distance.
     |          A large, finite p may cause a ValueError if overflow can occur.
     |      distance_upper_bound : nonnegative float, optional
     |          Return only neighbors within this distance. This is used to prune
     |          tree searches, so if you are doing a series of nearest-neighbor
     |          queries, it may help to supply the distance to the nearest neighbor
     |          of the most recent point.
     |      workers : int, optional
     |          Number of workers to use for parallel processing. If -1 is given
     |          all CPU threads are used. Default: 1.
     |
     |          .. versionadded:: 1.6.0
     |
     |      Returns
     |      -------
     |      d : float or array of floats
     |          The distances to the nearest neighbors.
     |          If ``x`` has shape ``tuple+(self.m,)``, then ``d`` has shape
     |          ``tuple+(k,)``.
     |          When k == 1, the last dimension of the output is squeezed.
     |          Missing neighbors are indicated with infinite distances.
     |          Hits are sorted by distance (nearest first).
     |
     |          .. versionchanged:: 1.9.0
     |             Previously if ``k=None``, then `d` was an object array of
     |             shape ``tuple``, containing lists of distances. This behavior
     |             has been removed, use `query_ball_point` instead.
     |
     |      i : integer or array of integers
     |          The index of each neighbor in ``self.data``.
     |          ``i`` is the same shape as d.
     |          Missing neighbors are indicated with ``self.n``.
     |
     |      Examples
     |      --------
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import KDTree
     |      >>> x, y = np.mgrid[0:5, 2:8]
     |      >>> tree = KDTree(np.c_[x.ravel(), y.ravel()])
     |
     |      To query the nearest neighbours and return squeezed result, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=1)
     |      >>> print(dd, ii, sep='\n')
     |      [2.         0.2236068]
     |      [ 0 13]
     |
     |      To query the nearest neighbours and return unsqueezed result, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.        ]
     |       [0.2236068]]
     |      [[ 0]
     |       [13]]
     |
     |      To query the second nearest neighbours and return unsqueezed result,
     |      use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[2])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.23606798]
     |       [0.80622577]]
     |      [[ 6]
     |       [19]]
     |
     |      To query the first and second nearest neighbours, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=2)
     |      >>> print(dd, ii, sep='\n')
     |      [[2.         2.23606798]
     |       [0.2236068  0.80622577]]
     |      [[ 0  6]
     |       [13 19]]
     |
     |      or, be more specific
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1, 2])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.         2.23606798]
     |       [0.2236068  0.80622577]]
     |      [[ 0  6]
     |       [13 19]]
     |
     |  query_ball_point(self, x, r, p=2.0, eps=0, workers=1, return_sorted=None, return_length=False)
     |      Find all points within distance r of point(s) x.
     |
     |      Parameters
     |      ----------
     |      x : array_like, shape tuple + (self.m,)
     |          The point or points to search for neighbors of.
     |      r : array_like, float
     |          The radius of points to return, must broadcast to the length of x.
     |      p : float, optional
     |          Which Minkowski p-norm to use.  Should be in the range [1, inf].
     |          A finite large p may cause a ValueError if overflow can occur.
     |      eps : nonnegative float, optional
     |          Approximate search. Branches of the tree are not explored if their
     |          nearest points are further than ``r / (1 + eps)``, and branches are
     |          added in bulk if their furthest points are nearer than
     |          ``r * (1 + eps)``.
     |      workers : int, optional
     |          Number of jobs to schedule for parallel processing. If -1 is given
     |          all processors are used. Default: 1.
     |
     |          .. versionadded:: 1.6.0
     |      return_sorted : bool, optional
     |          Sorts returned indices if True and does not sort them if False. If
     |          None, does not sort single point queries, but does sort
     |          multi-point queries which was the behavior before this option
     |          was added.
     |
     |          .. versionadded:: 1.6.0
     |      return_length : bool, optional
     |          Return the number of points inside the radius instead of a list
     |          of the indices.
     |
     |          .. versionadded:: 1.6.0
     |
     |      Returns
     |      -------
     |      results : list or array of lists
     |          If `x` is a single point, returns a list of the indices of the
     |          neighbors of `x`. If `x` is an array of points, returns an object
     |          array of shape tuple containing lists of neighbors.
     |
     |      Notes
     |      -----
     |      If you have many points whose neighbors you want to find, you may save
     |      substantial amounts of time by putting them in a KDTree and using
     |      query_ball_tree.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy import spatial
     |      >>> x, y = np.mgrid[0:5, 0:5]
     |      >>> points = np.c_[x.ravel(), y.ravel()]
     |      >>> tree = spatial.KDTree(points)
     |      >>> sorted(tree.query_ball_point([2, 0], 1))
     |      [5, 10, 11, 15]
     |
     |      Query multiple points and plot the results:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> points = np.asarray(points)
     |      >>> plt.plot(points[:,0], points[:,1], '.')
     |      >>> for results in tree.query_ball_point(([2, 0], [3, 3]), 1):
     |      ...     nearby_points = points[results]
     |      ...     plt.plot(nearby_points[:,0], nearby_points[:,1], 'o')
     |      >>> plt.margins(0.1, 0.1)
     |      >>> plt.show()
     |
     |  query_ball_tree(self, other, r, p=2.0, eps=0)
     |      Find all pairs of points between `self` and `other` whose distance is
     |      at most r.
     |
     |      Parameters
     |      ----------
     |      other : KDTree instance
     |          The tree containing points to search against.
     |      r : float
     |          The maximum distance, has to be positive.
     |      p : float, optional
     |          Which Minkowski norm to use.  `p` has to meet the condition
     |          ``1 <= p <= infinity``.
     |      eps : float, optional
     |          Approximate search.  Branches of the tree are not explored
     |          if their nearest points are further than ``r/(1+eps)``, and
     |          branches are added in bulk if their furthest points are nearer
     |          than ``r * (1+eps)``.  `eps` has to be non-negative.
     |
     |      Returns
     |      -------
     |      results : list of lists
     |          For each element ``self.data[i]`` of this tree, ``results[i]`` is a
     |          list of the indices of its neighbors in ``other.data``.
     |
     |      Examples
     |      --------
     |      You can search all pairs of points between two kd-trees within a distance:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> import numpy as np
     |      >>> from scipy.spatial import KDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((15, 2))
     |      >>> points2 = rng.random((15, 2))
     |      >>> plt.figure(figsize=(6, 6))
     |      >>> plt.plot(points1[:, 0], points1[:, 1], "xk", markersize=14)
     |      >>> plt.plot(points2[:, 0], points2[:, 1], "og", markersize=14)
     |      >>> kd_tree1 = KDTree(points1)
     |      >>> kd_tree2 = KDTree(points2)
     |      >>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
     |      >>> for i in range(len(indexes)):
     |      ...     for j in indexes[i]:
     |      ...         plt.plot([points1[i, 0], points2[j, 0]],
     |      ...             [points1[i, 1], points2[j, 1]], "-r")
     |      >>> plt.show()
     |
     |  query_pairs(self, r, p=2.0, eps=0, output_type='set')
     |      Find all pairs of points in `self` whose distance is at most r.
     |
     |      Parameters
     |      ----------
     |      r : positive float
     |          The maximum distance.
     |      p : float, optional
     |          Which Minkowski norm to use.  `p` has to meet the condition
     |          ``1 <= p <= infinity``.
     |      eps : float, optional
     |          Approximate search.  Branches of the tree are not explored
     |          if their nearest points are further than ``r/(1+eps)``, and
     |          branches are added in bulk if their furthest points are nearer
     |          than ``r * (1+eps)``.  `eps` has to be non-negative.
     |      output_type : string, optional
     |          Choose the output container, 'set' or 'ndarray'. Default: 'set'
     |
     |          .. versionadded:: 1.6.0
     |
     |      Returns
     |      -------
     |      results : set or ndarray
     |          Set of pairs ``(i,j)``, with ``i < j``, for which the corresponding
     |          positions are close. If output_type is 'ndarray', an ndarry is
     |          returned instead of a set.
     |
     |      Examples
     |      --------
     |      You can search all pairs of points in a kd-tree within a distance:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> import numpy as np
     |      >>> from scipy.spatial import KDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points = rng.random((20, 2))
     |      >>> plt.figure(figsize=(6, 6))
     |      >>> plt.plot(points[:, 0], points[:, 1], "xk", markersize=14)
     |      >>> kd_tree = KDTree(points)
     |      >>> pairs = kd_tree.query_pairs(r=0.2)
     |      >>> for (i, j) in pairs:
     |      ...     plt.plot([points[i, 0], points[j, 0]],
     |      ...             [points[i, 1], points[j, 1]], "-r")
     |      >>> plt.show()
     |
     |  sparse_distance_matrix(self, other, max_distance, p=2.0, output_type='dok_matrix')
     |      Compute a sparse distance matrix.
     |
     |      Computes a distance matrix between two KDTrees, leaving as zero
     |      any distance greater than max_distance.
     |
     |      Parameters
     |      ----------
     |      other : KDTree
     |
     |      max_distance : positive float
     |
     |      p : float, 1<=p<=infinity
     |          Which Minkowski p-norm to use.
     |          A finite large p may cause a ValueError if overflow can occur.
     |
     |      output_type : string, optional
     |          Which container to use for output data. Options: 'dok_matrix',
     |          'coo_matrix', 'dict', or 'ndarray'. Default: 'dok_matrix'.
     |
     |          .. versionadded:: 1.6.0
     |
     |      Returns
     |      -------
     |      result : dok_matrix, coo_matrix, dict or ndarray
     |          Sparse matrix representing the results in "dictionary of keys"
     |          format. If a dict is returned the keys are (i,j) tuples of indices.
     |          If output_type is 'ndarray' a record array with fields 'i', 'j',
     |          and 'v' is returned,
     |
     |      Examples
     |      --------
     |      You can compute a sparse distance matrix between two kd-trees:
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import KDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((5, 2))
     |      >>> points2 = rng.random((5, 2))
     |      >>> kd_tree1 = KDTree(points1)
     |      >>> kd_tree2 = KDTree(points2)
     |      >>> sdm = kd_tree1.sparse_distance_matrix(kd_tree2, 0.3)
     |      >>> sdm.toarray()
     |      array([[0.        , 0.        , 0.12295571, 0.        , 0.        ],
     |         [0.        , 0.        , 0.        , 0.        , 0.        ],
     |         [0.28942611, 0.        , 0.        , 0.2333084 , 0.        ],
     |         [0.        , 0.        , 0.        , 0.        , 0.        ],
     |         [0.24617575, 0.29571802, 0.26836782, 0.        , 0.        ]])
     |
     |      You can check distances above the `max_distance` are zeros:
     |
     |      >>> from scipy.spatial import distance_matrix
     |      >>> distance_matrix(points1, points2)
     |      array([[0.56906522, 0.39923701, 0.12295571, 0.8658745 , 0.79428925],
     |         [0.37327919, 0.7225693 , 0.87665969, 0.32580855, 0.75679479],
     |         [0.28942611, 0.30088013, 0.6395831 , 0.2333084 , 0.33630734],
     |         [0.31994999, 0.72658602, 0.71124834, 0.55396483, 0.90785663],
     |         [0.24617575, 0.29571802, 0.26836782, 0.57714465, 0.6473269 ]])
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  tree
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  innernode = <class 'scipy.spatial._kdtree.KDTree.innernode'>
     |
     |  leafnode = <class 'scipy.spatial._kdtree.KDTree.leafnode'>
     |
     |  node = <class 'scipy.spatial._kdtree.KDTree.node'>
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.spatial._ckdtree.cKDTree:
     |
     |  __getstate__(self)
     |
     |  __reduce_cython__(...)
     |
     |  __setstate__(self, state)
     |
     |  __setstate_cython__(...)
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from scipy.spatial._ckdtree.cKDTree:
     |
     |  __new__(*args, **kwargs) class method of scipy.spatial._ckdtree.cKDTree
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.spatial._ckdtree.cKDTree:
     |
     |  boxsize
     |
     |  data
     |
     |  indices
     |
     |  leafsize
     |
     |  m
     |
     |  maxes
     |
     |  mins
     |
     |  n
     |
     |  size
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from scipy.spatial._ckdtree.cKDTree:
     |
     |  __pyx_vtable__ = <capsule object NULL>

    class QhullError(builtins.RuntimeError)
     |  Method resolution order:
     |      QhullError
     |      builtins.RuntimeError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.RuntimeError:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeError:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeError
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class Rectangle(builtins.object)
     |  Rectangle(maxes, mins)
     |
     |  Hyperrectangle class.
     |
     |  Represents a Cartesian product of intervals.
     |
     |  Methods defined here:
     |
     |  __init__(self, maxes, mins)
     |      Construct a hyperrectangle.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  max_distance_point(self, x, p=2.0)
     |      Return the maximum distance between input and points in the hyperrectangle.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Input array.
     |      p : float, optional
     |          Input.
     |
     |  max_distance_rectangle(self, other, p=2.0)
     |      Compute the maximum distance between points in the two hyperrectangles.
     |
     |      Parameters
     |      ----------
     |      other : hyperrectangle
     |          Input.
     |      p : float, optional
     |          Input.
     |
     |  min_distance_point(self, x, p=2.0)
     |      Return the minimum distance between input and points in the
     |      hyperrectangle.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          Input.
     |      p : float, optional
     |          Input.
     |
     |  min_distance_rectangle(self, other, p=2.0)
     |      Compute the minimum distance between points in the two hyperrectangles.
     |
     |      Parameters
     |      ----------
     |      other : hyperrectangle
     |          Input.
     |      p : float
     |          Input.
     |
     |  split(self, d, split)
     |      Produce two hyperrectangles by splitting.
     |
     |      In general, if you need to compute maximum and minimum
     |      distances to the children, it can be done more efficiently
     |      by updating the maximum and minimum distances to the parent.
     |
     |      Parameters
     |      ----------
     |      d : int
     |          Axis to split hyperrectangle along.
     |      split : float
     |          Position along axis `d` to split at.
     |
     |  volume(self)
     |      Total volume.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class SphericalVoronoi(builtins.object)
     |  SphericalVoronoi(points, radius=1, center=None, threshold=1e-06)
     |
     |  Voronoi diagrams on the surface of a sphere.
     |
     |  .. versionadded:: 0.18.0
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndim)
     |      Coordinates of points from which to construct a spherical
     |      Voronoi diagram.
     |  radius : float, optional
     |      Radius of the sphere (Default: 1)
     |  center : ndarray of floats, shape (ndim,)
     |      Center of sphere (Default: origin)
     |  threshold : float
     |      Threshold for detecting duplicate points and
     |      mismatches between points and sphere parameters.
     |      (Default: 1e-06)
     |
     |  Attributes
     |  ----------
     |  points : double array of shape (npoints, ndim)
     |      the points in `ndim` dimensions to generate the Voronoi diagram from
     |  radius : double
     |      radius of the sphere
     |  center : double array of shape (ndim,)
     |      center of the sphere
     |  vertices : double array of shape (nvertices, ndim)
     |      Voronoi vertices corresponding to points
     |  regions : list of list of integers of shape (npoints, _ )
     |      the n-th entry is a list consisting of the indices
     |      of the vertices belonging to the n-th point in points
     |
     |  Methods
     |  -------
     |  calculate_areas
     |      Calculates the areas of the Voronoi regions. For 2D point sets, the
     |      regions are circular arcs. The sum of the areas is `2 * pi * radius`.
     |      For 3D point sets, the regions are spherical polygons. The sum of the
     |      areas is `4 * pi * radius**2`.
     |
     |  Raises
     |  ------
     |  ValueError
     |      If there are duplicates in `points`.
     |      If the provided `radius` is not consistent with `points`.
     |
     |  Notes
     |  -----
     |  The spherical Voronoi diagram algorithm proceeds as follows. The Convex
     |  Hull of the input points (generators) is calculated, and is equivalent to
     |  their Delaunay triangulation on the surface of the sphere [Caroli]_.
     |  The Convex Hull neighbour information is then used to
     |  order the Voronoi region vertices around each generator. The latter
     |  approach is substantially less sensitive to floating point issues than
     |  angle-based methods of Voronoi region vertex sorting.
     |
     |  Empirical assessment of spherical Voronoi algorithm performance suggests
     |  quadratic time complexity (loglinear is optimal, but algorithms are more
     |  challenging to implement).
     |
     |  References
     |  ----------
     |  .. [Caroli] Caroli et al. Robust and Efficient Delaunay triangulations of
     |              points on or close to a sphere. Research Report RR-7004, 2009.
     |
     |  .. [VanOosterom] Van Oosterom and Strackee. The solid angle of a plane
     |                   triangle. IEEE Transactions on Biomedical Engineering,
     |                   2, 1983, pp 125--126.
     |
     |  See Also
     |  --------
     |  Voronoi : Conventional Voronoi diagrams in N dimensions.
     |
     |  Examples
     |  --------
     |  Do some imports and take some points on a cube:
     |
     |  >>> import numpy as np
     |  >>> import matplotlib.pyplot as plt
     |  >>> from scipy.spatial import SphericalVoronoi, geometric_slerp
     |  >>> from mpl_toolkits.mplot3d import proj3d
     |  >>> # set input data
     |  >>> points = np.array([[0, 0, 1], [0, 0, -1], [1, 0, 0],
     |  ...                    [0, 1, 0], [0, -1, 0], [-1, 0, 0], ])
     |
     |  Calculate the spherical Voronoi diagram:
     |
     |  >>> radius = 1
     |  >>> center = np.array([0, 0, 0])
     |  >>> sv = SphericalVoronoi(points, radius, center)
     |
     |  Generate plot:
     |
     |  >>> # sort vertices (optional, helpful for plotting)
     |  >>> sv.sort_vertices_of_regions()
     |  >>> t_vals = np.linspace(0, 1, 2000)
     |  >>> fig = plt.figure()
     |  >>> ax = fig.add_subplot(111, projection='3d')
     |  >>> # plot the unit sphere for reference (optional)
     |  >>> u = np.linspace(0, 2 * np.pi, 100)
     |  >>> v = np.linspace(0, np.pi, 100)
     |  >>> x = np.outer(np.cos(u), np.sin(v))
     |  >>> y = np.outer(np.sin(u), np.sin(v))
     |  >>> z = np.outer(np.ones(np.size(u)), np.cos(v))
     |  >>> ax.plot_surface(x, y, z, color='y', alpha=0.1)
     |  >>> # plot generator points
     |  >>> ax.scatter(points[:, 0], points[:, 1], points[:, 2], c='b')
     |  >>> # plot Voronoi vertices
     |  >>> ax.scatter(sv.vertices[:, 0], sv.vertices[:, 1], sv.vertices[:, 2],
     |  ...                    c='g')
     |  >>> # indicate Voronoi regions (as Euclidean polygons)
     |  >>> for region in sv.regions:
     |  ...    n = len(region)
     |  ...    for i in range(n):
     |  ...        start = sv.vertices[region][i]
     |  ...        end = sv.vertices[region][(i + 1) % n]
     |  ...        result = geometric_slerp(start, end, t_vals)
     |  ...        ax.plot(result[..., 0],
     |  ...                result[..., 1],
     |  ...                result[..., 2],
     |  ...                c='k')
     |  >>> ax.azim = 10
     |  >>> ax.elev = 40
     |  >>> _ = ax.set_xticks([])
     |  >>> _ = ax.set_yticks([])
     |  >>> _ = ax.set_zticks([])
     |  >>> fig.set_size_inches(4, 4)
     |  >>> plt.show()
     |
     |  Methods defined here:
     |
     |  __init__(self, points, radius=1, center=None, threshold=1e-06)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_areas(self)
     |      Calculates the areas of the Voronoi regions.
     |
     |      For 2D point sets, the regions are circular arcs. The sum of the areas
     |      is `2 * pi * radius`.
     |
     |      For 3D point sets, the regions are spherical polygons. The sum of the
     |      areas is `4 * pi * radius**2`.
     |
     |      .. versionadded:: 1.5.0
     |
     |      Returns
     |      -------
     |      areas : double array of shape (npoints,)
     |          The areas of the Voronoi regions.
     |
     |  sort_vertices_of_regions(self)
     |      Sort indices of the vertices to be (counter-)clockwise ordered.
     |
     |      Raises
     |      ------
     |      TypeError
     |          If the points are not three-dimensional.
     |
     |      Notes
     |      -----
     |      For each region in regions, it sorts the indices of the Voronoi
     |      vertices such that the resulting points are in a clockwise or
     |      counterclockwise order around the generator point.
     |
     |      This is done as follows: Recall that the n-th region in regions
     |      surrounds the n-th generator in points and that the k-th
     |      Voronoi vertex in vertices is the circumcenter of the k-th triangle
     |      in self._simplices.  For each region n, we choose the first triangle
     |      (=Voronoi vertex) in self._simplices and a vertex of that triangle
     |      not equal to the center n. These determine a unique neighbor of that
     |      triangle, which is then chosen as the second triangle. The second
     |      triangle will have a unique vertex not equal to the current vertex or
     |      the center. This determines a unique neighbor of the second triangle,
     |      which is then chosen as the third triangle and so forth. We proceed
     |      through all the triangles (=Voronoi vertices) belonging to the
     |      generator in points and obtain a sorted version of the vertices
     |      of its surrounding region.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class Voronoi(_QhullUser)
     |  Voronoi(points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  Voronoi(points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  Voronoi diagrams in N dimensions.
     |
     |  .. versionadded:: 0.12.0
     |
     |  Parameters
     |  ----------
     |  points : ndarray of floats, shape (npoints, ndim)
     |      Coordinates of points to construct a Voronoi diagram from
     |  furthest_site : bool, optional
     |      Whether to compute a furthest-site Voronoi diagram. Default: False
     |  incremental : bool, optional
     |      Allow adding new points incrementally. This takes up some additional
     |      resources.
     |  qhull_options : str, optional
     |      Additional options to pass to Qhull. See Qhull manual
     |      for details. (Default: "Qbb Qc Qz Qx" for ndim > 4 and
     |      "Qbb Qc Qz" otherwise. Incremental mode omits "Qz".)
     |
     |  Attributes
     |  ----------
     |  points : ndarray of double, shape (npoints, ndim)
     |      Coordinates of input points.
     |  vertices : ndarray of double, shape (nvertices, ndim)
     |      Coordinates of the Voronoi vertices.
     |  ridge_points : ndarray of ints, shape ``(nridges, 2)``
     |      Indices of the points between which each Voronoi ridge lies.
     |  ridge_vertices : list of list of ints, shape ``(nridges, *)``
     |      Indices of the Voronoi vertices forming each Voronoi ridge.
     |  regions : list of list of ints, shape ``(nregions, *)``
     |      Indices of the Voronoi vertices forming each Voronoi region.
     |      -1 indicates vertex outside the Voronoi diagram.
     |      When qhull option "Qz" was specified, an empty sublist
     |      represents the Voronoi region for a point at infinity that
     |      was added internally.
     |  point_region : array of ints, shape (npoints)
     |      Index of the Voronoi region for each input point.
     |      If qhull option "Qc" was not specified, the list will contain -1
     |      for points that are not associated with a Voronoi region.
     |      If qhull option "Qz" was specified, there will be one less
     |      element than the number of regions because an extra point
     |      at infinity is added internally to facilitate computation.
     |  furthest_site
     |      True if this was a furthest site triangulation and False if not.
     |
     |      .. versionadded:: 1.4.0
     |
     |  Raises
     |  ------
     |  QhullError
     |      Raised when Qhull encounters an error condition, such as
     |      geometrical degeneracy when options to resolve are not enabled.
     |  ValueError
     |      Raised if an incompatible array is given as input.
     |
     |  Notes
     |  -----
     |  The Voronoi diagram is computed using the
     |  `Qhull library <http://www.qhull.org/>`__.
     |
     |  Examples
     |  --------
     |  Voronoi diagram for a set of point:
     |
     |  >>> import numpy as np
     |  >>> points = np.array([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2],
     |  ...                    [2, 0], [2, 1], [2, 2]])
     |  >>> from scipy.spatial import Voronoi, voronoi_plot_2d
     |  >>> vor = Voronoi(points)
     |
     |  Plot it:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig = voronoi_plot_2d(vor)
     |  >>> plt.show()
     |
     |  The Voronoi vertices:
     |
     |  >>> vor.vertices
     |  array([[0.5, 0.5],
     |         [0.5, 1.5],
     |         [1.5, 0.5],
     |         [1.5, 1.5]])
     |
     |  There is a single finite Voronoi region, and four finite Voronoi
     |  ridges:
     |
     |  >>> vor.regions
     |  [[], [-1, 0], [-1, 1], [1, -1, 0], [3, -1, 2], [-1, 3], [-1, 2], [0, 1, 3, 2], [2, -1, 0], [3, -1, 1]]
     |  >>> vor.ridge_vertices
     |  [[-1, 0], [-1, 0], [-1, 1], [-1, 1], [0, 1], [-1, 3], [-1, 2], [2, 3], [-1, 3], [-1, 2], [1, 3], [0, 2]]
     |
     |  The ridges are perpendicular between lines drawn between the following
     |  input points:
     |
     |  >>> vor.ridge_points
     |  array([[0, 3],
     |         [0, 1],
     |         [2, 5],
     |         [2, 1],
     |         [1, 4],
     |         [7, 8],
     |         [7, 6],
     |         [7, 4],
     |         [8, 5],
     |         [6, 3],
     |         [4, 5],
     |         [4, 3]], dtype=int32)
     |
     |  Method resolution order:
     |      Voronoi
     |      _QhullUser
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, points, furthest_site=False, incremental=False, qhull_options=None)
     |
     |  add_points(self, points, restart=False)
     |      add_points(points, restart=False)
     |
     |      Process a set of additional new points.
     |
     |      Parameters
     |      ----------
     |      points : ndarray
     |          New points to add. The dimensionality should match that of the
     |          initial points.
     |      restart : bool, optional
     |          Whether to restart processing from scratch, rather than
     |          adding points incrementally.
     |
     |      Raises
     |      ------
     |      QhullError
     |          Raised when Qhull encounters an error condition, such as
     |          geometrical degeneracy when options to resolve are not enabled.
     |
     |      See Also
     |      --------
     |      close
     |
     |      Notes
     |      -----
     |      You need to specify ``incremental=True`` when constructing the
     |      object to be able to add points incrementally. Incremental addition
     |      of points is also not possible after `close` has been called.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  points
     |
     |  ridge_dict
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from _QhullUser:
     |
     |  __del__(self)
     |
     |  close(self)
     |      close()
     |
     |      Finish incremental processing.
     |
     |      Call this to free resources taken up by Qhull, when using the
     |      incremental mode. After calling this, adding more points is no
     |      longer possible.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from _QhullUser:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class cKDTree(builtins.object)
     |  cKDTree(data, leafsize=16, compact_nodes=True, copy_data=False,
     |          balanced_tree=True, boxsize=None)
     |
     |  kd-tree for quick nearest-neighbor lookup
     |
     |  This class provides an index into a set of k-dimensional points
     |  which can be used to rapidly look up the nearest neighbors of any
     |  point.
     |
     |  .. note::
     |     `cKDTree` is functionally identical to `KDTree`. Prior to SciPy
     |     v1.6.0, `cKDTree` had better performance and slightly different
     |     functionality but now the two names exist only for
     |     backward-compatibility reasons. If compatibility with SciPy < 1.6 is not
     |     a concern, prefer `KDTree`.
     |
     |  Parameters
     |  ----------
     |  data : array_like, shape (n,m)
     |      The n data points of dimension m to be indexed. This array is
     |      not copied unless this is necessary to produce a contiguous
     |      array of doubles, and so modifying this data will result in
     |      bogus results. The data are also copied if the kd-tree is built
     |      with copy_data=True.
     |  leafsize : positive int, optional
     |      The number of points at which the algorithm switches over to
     |      brute-force. Default: 16.
     |  compact_nodes : bool, optional
     |      If True, the kd-tree is built to shrink the hyperrectangles to
     |      the actual data range. This usually gives a more compact tree that
     |      is robust against degenerated input data and gives faster queries
     |      at the expense of longer build time. Default: True.
     |  copy_data : bool, optional
     |      If True the data is always copied to protect the kd-tree against
     |      data corruption. Default: False.
     |  balanced_tree : bool, optional
     |      If True, the median is used to split the hyperrectangles instead of
     |      the midpoint. This usually gives a more compact tree and
     |      faster queries at the expense of longer build time. Default: True.
     |  boxsize : array_like or scalar, optional
     |      Apply a m-d toroidal topology to the KDTree.. The topology is generated
     |      by :math:`x_i + n_i L_i` where :math:`n_i` are integers and :math:`L_i`
     |      is the boxsize along i-th dimension. The input data shall be wrapped
     |      into :math:`[0, L_i)`. A ValueError is raised if any of the data is
     |      outside of this bound.
     |
     |  Notes
     |  -----
     |  The algorithm used is described in Maneewongvatana and Mount 1999.
     |  The general idea is that the kd-tree is a binary tree, each of whose
     |  nodes represents an axis-aligned hyperrectangle. Each node specifies
     |  an axis and splits the set of points based on whether their coordinate
     |  along that axis is greater than or less than a particular value.
     |
     |  During construction, the axis and splitting point are chosen by the
     |  "sliding midpoint" rule, which ensures that the cells do not all
     |  become long and thin.
     |
     |  The tree can be queried for the r closest neighbors of any given point
     |  (optionally returning only those within some maximum distance of the
     |  point). It can also be queried, with a substantial gain in efficiency,
     |  for the r approximate closest neighbors.
     |
     |  For large dimensions (20 is already large) do not expect this to run
     |  significantly faster than brute force. High-dimensional nearest-neighbor
     |  queries are a substantial open problem in computer science.
     |
     |  Attributes
     |  ----------
     |  data : ndarray, shape (n,m)
     |      The n data points of dimension m to be indexed. This array is
     |      not copied unless this is necessary to produce a contiguous
     |      array of doubles. The data are also copied if the kd-tree is built
     |      with `copy_data=True`.
     |  leafsize : positive int
     |      The number of points at which the algorithm switches over to
     |      brute-force.
     |  m : int
     |      The dimension of a single data-point.
     |  n : int
     |      The number of data points.
     |  maxes : ndarray, shape (m,)
     |      The maximum value in each dimension of the n data points.
     |  mins : ndarray, shape (m,)
     |      The minimum value in each dimension of the n data points.
     |  tree : object, class cKDTreeNode
     |      This attribute exposes a Python view of the root node in the cKDTree
     |      object. A full Python view of the kd-tree is created dynamically
     |      on the first access. This attribute allows you to create your own
     |      query functions in Python.
     |  size : int
     |      The number of nodes in the tree.
     |
     |  Methods defined here:
     |
     |  __getstate__(self)
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __reduce_cython__(...)
     |
     |  __setstate__(self, state)
     |
     |  __setstate_cython__(...)
     |
     |  count_neighbors(self, other, r, p=2.0, weights=None, cumulative=True)
     |      count_neighbors(self, other, r, p=2., weights=None, cumulative=True)
     |
     |      Count how many nearby pairs can be formed.
     |
     |      Count the number of pairs ``(x1,x2)`` can be formed, with ``x1`` drawn
     |      from ``self`` and ``x2`` drawn from ``other``, and where
     |      ``distance(x1, x2, p) <= r``.
     |
     |      Data points on ``self`` and ``other`` are optionally weighted by the
     |      ``weights`` argument. (See below)
     |
     |      This is adapted from the "two-point correlation" algorithm described by
     |      Gray and Moore [1]_.  See notes for further discussion.
     |
     |      Parameters
     |      ----------
     |      other : cKDTree instance
     |          The other tree to draw points from, can be the same tree as self.
     |      r : float or one-dimensional array of floats
     |          The radius to produce a count for. Multiple radii are searched with
     |          a single tree traversal.
     |          If the count is non-cumulative(``cumulative=False``), ``r`` defines
     |          the edges of the bins, and must be non-decreasing.
     |      p : float, optional
     |          1<=p<=infinity.
     |          Which Minkowski p-norm to use.
     |          Default 2.0.
     |          A finite large p may cause a ValueError if overflow can occur.
     |      weights : tuple, array_like, or None, optional
     |          If None, the pair-counting is unweighted.
     |          If given as a tuple, weights[0] is the weights of points in ``self``, and
     |          weights[1] is the weights of points in ``other``; either can be None to
     |          indicate the points are unweighted.
     |          If given as an array_like, weights is the weights of points in ``self``
     |          and ``other``. For this to make sense, ``self`` and ``other`` must be the
     |          same tree. If ``self`` and ``other`` are two different trees, a ``ValueError``
     |          is raised.
     |          Default: None
     |      cumulative : bool, optional
     |          Whether the returned counts are cumulative. When cumulative is set to ``False``
     |          the algorithm is optimized to work with a large number of bins (>10) specified
     |          by ``r``. When ``cumulative`` is set to True, the algorithm is optimized to work
     |          with a small number of ``r``. Default: True
     |
     |      Returns
     |      -------
     |      result : scalar or 1-D array
     |          The number of pairs. For unweighted counts, the result is integer.
     |          For weighted counts, the result is float.
     |          If cumulative is False, ``result[i]`` contains the counts with
     |          ``(-inf if i == 0 else r[i-1]) < R <= r[i]``
     |
     |      Notes
     |      -----
     |      Pair-counting is the basic operation used to calculate the two point
     |      correlation functions from a data set composed of position of objects.
     |
     |      Two point correlation function measures the clustering of objects and
     |      is widely used in cosmology to quantify the large scale structure
     |      in our Universe, but it may be useful for data analysis in other fields
     |      where self-similar assembly of objects also occur.
     |
     |      The Landy-Szalay estimator for the two point correlation function of
     |      ``D`` measures the clustering signal in ``D``. [2]_
     |
     |      For example, given the position of two sets of objects,
     |
     |      - objects ``D`` (data) contains the clustering signal, and
     |
     |      - objects ``R`` (random) that contains no signal,
     |
     |      .. math::
     |
     |           \xi(r) = \frac{<D, D> - 2 f <D, R> + f^2<R, R>}{f^2<R, R>},
     |
     |      where the brackets represents counting pairs between two data sets
     |      in a finite bin around ``r`` (distance), corresponding to setting
     |      `cumulative=False`, and ``f = float(len(D)) / float(len(R))`` is the
     |      ratio between number of objects from data and random.
     |
     |      The algorithm implemented here is loosely based on the dual-tree
     |      algorithm described in [1]_. We switch between two different
     |      pair-cumulation scheme depending on the setting of ``cumulative``.
     |      The computing time of the method we use when for
     |      ``cumulative == False`` does not scale with the total number of bins.
     |      The algorithm for ``cumulative == True`` scales linearly with the
     |      number of bins, though it is slightly faster when only
     |      1 or 2 bins are used. [5]_.
     |
     |      As an extension to the naive pair-counting,
     |      weighted pair-counting counts the product of weights instead
     |      of number of pairs.
     |      Weighted pair-counting is used to estimate marked correlation functions
     |      ([3]_, section 2.2),
     |      or to properly calculate the average of data per distance bin
     |      (e.g. [4]_, section 2.1 on redshift).
     |
     |      .. [1] Gray and Moore,
     |             "N-body problems in statistical learning",
     |             Mining the sky, 2000, :arxiv:`astro-ph/0012333`
     |
     |      .. [2] Landy and Szalay,
     |             "Bias and variance of angular correlation functions",
     |             The Astrophysical Journal, 1993, :doi:`10.1086/172900`
     |
     |      .. [3] Sheth, Connolly and Skibba,
     |             "Marked correlations in galaxy formation models",
     |             2005, :arxiv:`astro-ph/0511773`
     |
     |      .. [4] Hawkins, et al.,
     |             "The 2dF Galaxy Redshift Survey: correlation functions,
     |             peculiar velocities and the matter density of the Universe",
     |             Monthly Notices of the Royal Astronomical Society, 2002,
     |             :doi:`10.1046/j.1365-2966.2003.07063.x`
     |
     |      .. [5] https://github.com/scipy/scipy/pull/5647#issuecomment-168474926
     |
     |      Examples
     |      --------
     |      You can count neighbors number between two kd-trees within a distance:
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import cKDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((5, 2))
     |      >>> points2 = rng.random((5, 2))
     |      >>> kd_tree1 = cKDTree(points1)
     |      >>> kd_tree2 = cKDTree(points2)
     |      >>> kd_tree1.count_neighbors(kd_tree2, 0.2)
     |      1
     |
     |      This number is same as the total pair number calculated by
     |      `query_ball_tree`:
     |
     |      >>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
     |      >>> sum([len(i) for i in indexes])
     |      1
     |
     |  query(self, x, k=1, eps=0.0, p=2.0, distance_upper_bound=inf, workers=None, **kwargs)
     |      query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf, workers=1)
     |
     |      Query the kd-tree for nearest neighbors
     |
     |      Parameters
     |      ----------
     |      x : array_like, last dimension self.m
     |          An array of points to query.
     |      k : list of integer or integer
     |          The list of k-th nearest neighbors to return. If k is an
     |          integer it is treated as a list of [1, ... k] (range(1, k+1)).
     |          Note that the counting starts from 1.
     |      eps : non-negative float
     |          Return approximate nearest neighbors; the k-th returned value
     |          is guaranteed to be no further than (1+eps) times the
     |          distance to the real k-th nearest neighbor.
     |      p : float, 1<=p<=infinity
     |          Which Minkowski p-norm to use.
     |          1 is the sum-of-absolute-values "Manhattan" distance
     |          2 is the usual Euclidean distance
     |          infinity is the maximum-coordinate-difference distance
     |          A finite large p may cause a ValueError if overflow can occur.
     |      distance_upper_bound : nonnegative float
     |          Return only neighbors within this distance.  This is used to prune
     |          tree searches, so if you are doing a series of nearest-neighbor
     |          queries, it may help to supply the distance to the nearest neighbor
     |          of the most recent point.
     |      workers : int, optional
     |          Number of workers to use for parallel processing. If -1 is given
     |          all CPU threads are used. Default: 1.
     |
     |          .. versionchanged:: 1.9.0
     |             The "n_jobs" argument was renamed "workers". The old name
     |             "n_jobs" was deprecated in SciPy 1.6.0 and was removed in
     |             SciPy 1.9.0.
     |
     |      Returns
     |      -------
     |      d : array of floats
     |          The distances to the nearest neighbors.
     |          If ``x`` has shape ``tuple+(self.m,)``, then ``d`` has shape ``tuple+(k,)``.
     |          When k == 1, the last dimension of the output is squeezed.
     |          Missing neighbors are indicated with infinite distances.
     |      i : ndarray of ints
     |          The index of each neighbor in ``self.data``.
     |          If ``x`` has shape ``tuple+(self.m,)``, then ``i`` has shape ``tuple+(k,)``.
     |          When k == 1, the last dimension of the output is squeezed.
     |          Missing neighbors are indicated with ``self.n``.
     |
     |      Notes
     |      -----
     |      If the KD-Tree is periodic, the position ``x`` is wrapped into the
     |      box.
     |
     |      When the input k is a list, a query for arange(max(k)) is performed, but
     |      only columns that store the requested values of k are preserved. This is
     |      implemented in a manner that reduces memory usage.
     |
     |      Examples
     |      --------
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import cKDTree
     |      >>> x, y = np.mgrid[0:5, 2:8]
     |      >>> tree = cKDTree(np.c_[x.ravel(), y.ravel()])
     |
     |      To query the nearest neighbours and return squeezed result, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=1)
     |      >>> print(dd, ii, sep='\n')
     |      [2.         0.2236068]
     |      [ 0 13]
     |
     |      To query the nearest neighbours and return unsqueezed result, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.        ]
     |       [0.2236068]]
     |      [[ 0]
     |       [13]]
     |
     |      To query the second nearest neighbours and return unsqueezed result,
     |      use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[2])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.23606798]
     |       [0.80622577]]
     |      [[ 6]
     |       [19]]
     |
     |      To query the first and second nearest neighbours, use
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=2)
     |      >>> print(dd, ii, sep='\n')
     |      [[2.         2.23606798]
     |       [0.2236068  0.80622577]]
     |      [[ 0  6]
     |       [13 19]]
     |
     |      or, be more specific
     |
     |      >>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1, 2])
     |      >>> print(dd, ii, sep='\n')
     |      [[2.         2.23606798]
     |       [0.2236068  0.80622577]]
     |      [[ 0  6]
     |       [13 19]]
     |
     |  query_ball_point(self, x, r, p=2.0, eps=0.0, workers=None, return_sorted=None, return_length=False, **kwargs)
     |      query_ball_point(self, x, r, p=2., eps=0, workers=1, return_sorted=None,
     |                       return_length=False)
     |
     |      Find all points within distance r of point(s) x.
     |
     |      Parameters
     |      ----------
     |      x : array_like, shape tuple + (self.m,)
     |          The point or points to search for neighbors of.
     |      r : array_like, float
     |          The radius of points to return, shall broadcast to the length of x.
     |      p : float, optional
     |          Which Minkowski p-norm to use.  Should be in the range [1, inf].
     |          A finite large p may cause a ValueError if overflow can occur.
     |      eps : nonnegative float, optional
     |          Approximate search. Branches of the tree are not explored if their
     |          nearest points are further than ``r / (1 + eps)``, and branches are
     |          added in bulk if their furthest points are nearer than
     |          ``r * (1 + eps)``.
     |      workers : int, optional
     |          Number of jobs to schedule for parallel processing. If -1 is given
     |          all processors are used. Default: 1.
     |
     |          .. versionchanged:: 1.9.0
     |             The "n_jobs" argument was renamed "workers". The old name
     |             "n_jobs" was deprecated in SciPy 1.6.0 and was removed in
     |             SciPy 1.9.0.
     |
     |      return_sorted : bool, optional
     |          Sorts returned indices if True and does not sort them if False. If
     |          None, does not sort single point queries, but does sort
     |          multi-point queries which was the behavior before this option
     |          was added.
     |
     |          .. versionadded:: 1.2.0
     |      return_length: bool, optional
     |          Return the number of points inside the radius instead of a list
     |          of the indices.
     |          .. versionadded:: 1.3.0
     |
     |      Returns
     |      -------
     |      results : list or array of lists
     |          If `x` is a single point, returns a list of the indices of the
     |          neighbors of `x`. If `x` is an array of points, returns an object
     |          array of shape tuple containing lists of neighbors.
     |
     |      Notes
     |      -----
     |      If you have many points whose neighbors you want to find, you may save
     |      substantial amounts of time by putting them in a cKDTree and using
     |      query_ball_tree.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy import spatial
     |      >>> x, y = np.mgrid[0:4, 0:4]
     |      >>> points = np.c_[x.ravel(), y.ravel()]
     |      >>> tree = spatial.cKDTree(points)
     |      >>> tree.query_ball_point([2, 0], 1)
     |      [4, 8, 9, 12]
     |
     |      Query multiple points and plot the results:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> points = np.asarray(points)
     |      >>> plt.plot(points[:,0], points[:,1], '.')
     |      >>> for results in tree.query_ball_point(([2, 0], [3, 3]), 1):
     |      ...     nearby_points = points[results]
     |      ...     plt.plot(nearby_points[:,0], nearby_points[:,1], 'o')
     |      >>> plt.margins(0.1, 0.1)
     |      >>> plt.show()
     |
     |  query_ball_tree(self, other, r, p=2.0, eps=0.0)
     |      query_ball_tree(self, other, r, p=2., eps=0)
     |
     |      Find all pairs of points between `self` and `other` whose distance is at most r
     |
     |      Parameters
     |      ----------
     |      other : cKDTree instance
     |          The tree containing points to search against.
     |      r : float
     |          The maximum distance, has to be positive.
     |      p : float, optional
     |          Which Minkowski norm to use.  `p` has to meet the condition
     |          ``1 <= p <= infinity``.
     |          A finite large p may cause a ValueError if overflow can occur.
     |      eps : float, optional
     |          Approximate search.  Branches of the tree are not explored
     |          if their nearest points are further than ``r/(1+eps)``, and
     |          branches are added in bulk if their furthest points are nearer
     |          than ``r * (1+eps)``.  `eps` has to be non-negative.
     |
     |      Returns
     |      -------
     |      results : list of lists
     |          For each element ``self.data[i]`` of this tree, ``results[i]`` is a
     |          list of the indices of its neighbors in ``other.data``.
     |
     |      Examples
     |      --------
     |      You can search all pairs of points between two kd-trees within a distance:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> import numpy as np
     |      >>> from scipy.spatial import cKDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((15, 2))
     |      >>> points2 = rng.random((15, 2))
     |      >>> plt.figure(figsize=(6, 6))
     |      >>> plt.plot(points1[:, 0], points1[:, 1], "xk", markersize=14)
     |      >>> plt.plot(points2[:, 0], points2[:, 1], "og", markersize=14)
     |      >>> kd_tree1 = cKDTree(points1)
     |      >>> kd_tree2 = cKDTree(points2)
     |      >>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
     |      >>> for i in range(len(indexes)):
     |      ...     for j in indexes[i]:
     |      ...         plt.plot([points1[i, 0], points2[j, 0]],
     |      ...             [points1[i, 1], points2[j, 1]], "-r")
     |      >>> plt.show()
     |
     |  query_pairs(self, r, p=2.0, eps=0.0, output_type='set')
     |      query_pairs(self, r, p=2., eps=0, output_type='set')
     |
     |      Find all pairs of points in `self` whose distance is at most r.
     |
     |      Parameters
     |      ----------
     |      r : positive float
     |          The maximum distance.
     |      p : float, optional
     |          Which Minkowski norm to use.  ``p`` has to meet the condition
     |          ``1 <= p <= infinity``.
     |          A finite large p may cause a ValueError if overflow can occur.
     |      eps : float, optional
     |          Approximate search.  Branches of the tree are not explored
     |          if their nearest points are further than ``r/(1+eps)``, and
     |          branches are added in bulk if their furthest points are nearer
     |          than ``r * (1+eps)``.  `eps` has to be non-negative.
     |      output_type : string, optional
     |          Choose the output container, 'set' or 'ndarray'. Default: 'set'
     |
     |      Returns
     |      -------
     |      results : set or ndarray
     |          Set of pairs ``(i,j)``, with ``i < j``, for which the corresponding
     |          positions are close. If output_type is 'ndarray', an ndarry is
     |          returned instead of a set.
     |
     |      Examples
     |      --------
     |      You can search all pairs of points in a kd-tree within a distance:
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> import numpy as np
     |      >>> from scipy.spatial import cKDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points = rng.random((20, 2))
     |      >>> plt.figure(figsize=(6, 6))
     |      >>> plt.plot(points[:, 0], points[:, 1], "xk", markersize=14)
     |      >>> kd_tree = cKDTree(points)
     |      >>> pairs = kd_tree.query_pairs(r=0.2)
     |      >>> for (i, j) in pairs:
     |      ...     plt.plot([points[i, 0], points[j, 0]],
     |      ...             [points[i, 1], points[j, 1]], "-r")
     |      >>> plt.show()
     |
     |  sparse_distance_matrix(self, other, max_distance, p=2.0, output_type='dok_matrix')
     |      sparse_distance_matrix(self, other, max_distance, p=2.)
     |
     |      Compute a sparse distance matrix
     |
     |      Computes a distance matrix between two cKDTrees, leaving as zero
     |      any distance greater than max_distance.
     |
     |      Parameters
     |      ----------
     |      other : cKDTree
     |
     |      max_distance : positive float
     |
     |      p : float, 1<=p<=infinity
     |          Which Minkowski p-norm to use.
     |          A finite large p may cause a ValueError if overflow can occur.
     |
     |      output_type : string, optional
     |          Which container to use for output data. Options: 'dok_matrix',
     |          'coo_matrix', 'dict', or 'ndarray'. Default: 'dok_matrix'.
     |
     |      Returns
     |      -------
     |      result : dok_matrix, coo_matrix, dict or ndarray
     |          Sparse matrix representing the results in "dictionary of keys"
     |          format. If a dict is returned the keys are (i,j) tuples of indices.
     |          If output_type is 'ndarray' a record array with fields 'i', 'j',
     |          and 'v' is returned,
     |
     |      Examples
     |      --------
     |      You can compute a sparse distance matrix between two kd-trees:
     |
     |      >>> import numpy as np
     |      >>> from scipy.spatial import cKDTree
     |      >>> rng = np.random.default_rng()
     |      >>> points1 = rng.random((5, 2))
     |      >>> points2 = rng.random((5, 2))
     |      >>> kd_tree1 = cKDTree(points1)
     |      >>> kd_tree2 = cKDTree(points2)
     |      >>> sdm = kd_tree1.sparse_distance_matrix(kd_tree2, 0.3)
     |      >>> sdm.toarray()
     |      array([[0.        , 0.        , 0.12295571, 0.        , 0.        ],
     |         [0.        , 0.        , 0.        , 0.        , 0.        ],
     |         [0.28942611, 0.        , 0.        , 0.2333084 , 0.        ],
     |         [0.        , 0.        , 0.        , 0.        , 0.        ],
     |         [0.24617575, 0.29571802, 0.26836782, 0.        , 0.        ]])
     |
     |      You can check distances above the `max_distance` are zeros:
     |
     |      >>> from scipy.spatial import distance_matrix
     |      >>> distance_matrix(points1, points2)
     |      array([[0.56906522, 0.39923701, 0.12295571, 0.8658745 , 0.79428925],
     |         [0.37327919, 0.7225693 , 0.87665969, 0.32580855, 0.75679479],
     |         [0.28942611, 0.30088013, 0.6395831 , 0.2333084 , 0.33630734],
     |         [0.31994999, 0.72658602, 0.71124834, 0.55396483, 0.90785663],
     |         [0.24617575, 0.29571802, 0.26836782, 0.57714465, 0.6473269 ]])
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(*args, **kwargs)
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  boxsize
     |
     |  data
     |
     |  indices
     |
     |  leafsize
     |
     |  m
     |
     |  maxes
     |
     |  mins
     |
     |  n
     |
     |  size
     |
     |  tree
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __pyx_vtable__ = <capsule object NULL>

FUNCTIONS
    convex_hull_plot_2d(hull, ax=None)
        Plot the given convex hull diagram in 2-D

        Parameters
        ----------
        hull : scipy.spatial.ConvexHull instance
            Convex hull to plot
        ax : matplotlib.axes.Axes instance, optional
            Axes to plot on

        Returns
        -------
        fig : matplotlib.figure.Figure instance
            Figure for the plot

        See Also
        --------
        ConvexHull

        Notes
        -----
        Requires Matplotlib.


        Examples
        --------

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.spatial import ConvexHull, convex_hull_plot_2d

        The convex hull of a random set of points:

        >>> rng = np.random.default_rng()
        >>> points = rng.random((30, 2))
        >>> hull = ConvexHull(points)

        Plot it:

        >>> _ = convex_hull_plot_2d(hull)
        >>> plt.show()

    delaunay_plot_2d(tri, ax=None)
        Plot the given Delaunay triangulation in 2-D

        Parameters
        ----------
        tri : scipy.spatial.Delaunay instance
            Triangulation to plot
        ax : matplotlib.axes.Axes instance, optional
            Axes to plot on

        Returns
        -------
        fig : matplotlib.figure.Figure instance
            Figure for the plot

        See Also
        --------
        Delaunay
        matplotlib.pyplot.triplot

        Notes
        -----
        Requires Matplotlib.

        Examples
        --------

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.spatial import Delaunay, delaunay_plot_2d

        The Delaunay triangulation of a set of random points:

        >>> rng = np.random.default_rng()
        >>> points = rng.random((30, 2))
        >>> tri = Delaunay(points)

        Plot it:

        >>> _ = delaunay_plot_2d(tri)
        >>> plt.show()

    distance_matrix(x, y, p=2, threshold=1000000)
        Compute the distance matrix.

        Returns the matrix of all pair-wise distances.

        Parameters
        ----------
        x : (M, K) array_like
            Matrix of M vectors in K dimensions.
        y : (N, K) array_like
            Matrix of N vectors in K dimensions.
        p : float, 1 <= p <= infinity
            Which Minkowski p-norm to use.
        threshold : positive int
            If ``M * N * K`` > `threshold`, algorithm uses a Python loop instead
            of large temporary arrays.

        Returns
        -------
        result : (M, N) ndarray
            Matrix containing the distance from every vector in `x` to every vector
            in `y`.

        Examples
        --------
        >>> from scipy.spatial import distance_matrix
        >>> distance_matrix([[0,0],[0,1]], [[1,0],[1,1]])
        array([[ 1.        ,  1.41421356],
               [ 1.41421356,  1.        ]])

    geometric_slerp(start: 'npt.ArrayLike', end: 'npt.ArrayLike', t: 'npt.ArrayLike', tol: 'float' = 1e-07) -> 'np.ndarray'
        Geometric spherical linear interpolation.

        The interpolation occurs along a unit-radius
        great circle arc in arbitrary dimensional space.

        Parameters
        ----------
        start : (n_dimensions, ) array-like
            Single n-dimensional input coordinate in a 1-D array-like
            object. `n` must be greater than 1.
        end : (n_dimensions, ) array-like
            Single n-dimensional input coordinate in a 1-D array-like
            object. `n` must be greater than 1.
        t : float or (n_points,) 1D array-like
            A float or 1D array-like of doubles representing interpolation
            parameters, with values required in the inclusive interval
            between 0 and 1. A common approach is to generate the array
            with ``np.linspace(0, 1, n_pts)`` for linearly spaced points.
            Ascending, descending, and scrambled orders are permitted.
        tol : float
            The absolute tolerance for determining if the start and end
            coordinates are antipodes.

        Returns
        -------
        result : (t.size, D)
            An array of doubles containing the interpolated
            spherical path and including start and
            end when 0 and 1 t are used. The
            interpolated values should correspond to the
            same sort order provided in the t array. The result
            may be 1-dimensional if ``t`` is a float.

        Raises
        ------
        ValueError
            If ``start`` and ``end`` are antipodes, not on the
            unit n-sphere, or for a variety of degenerate conditions.

        See Also
        --------
        scipy.spatial.transform.Slerp : 3-D Slerp that works with quaternions

        Notes
        -----
        The implementation is based on the mathematical formula provided in [1]_,
        and the first known presentation of this algorithm, derived from study of
        4-D geometry, is credited to Glenn Davis in a footnote of the original
        quaternion Slerp publication by Ken Shoemake [2]_.

        .. versionadded:: 1.5.0

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Slerp#Geometric_Slerp
        .. [2] Ken Shoemake (1985) Animating rotation with quaternion curves.
               ACM SIGGRAPH Computer Graphics, 19(3): 245-254.

        Examples
        --------
        Interpolate four linearly-spaced values on the circumference of
        a circle spanning 90 degrees:

        >>> import numpy as np
        >>> from scipy.spatial import geometric_slerp
        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> start = np.array([1, 0])
        >>> end = np.array([0, 1])
        >>> t_vals = np.linspace(0, 1, 4)
        >>> result = geometric_slerp(start,
        ...                          end,
        ...                          t_vals)

        The interpolated results should be at 30 degree intervals
        recognizable on the unit circle:

        >>> ax.scatter(result[...,0], result[...,1], c='k')
        >>> circle = plt.Circle((0, 0), 1, color='grey')
        >>> ax.add_artist(circle)
        >>> ax.set_aspect('equal')
        >>> plt.show()

        Attempting to interpolate between antipodes on a circle is
        ambiguous because there are two possible paths, and on a
        sphere there are infinite possible paths on the geodesic surface.
        Nonetheless, one of the ambiguous paths is returned along
        with a warning:

        >>> opposite_pole = np.array([-1, 0])
        >>> with np.testing.suppress_warnings() as sup:
        ...     sup.filter(UserWarning)
        ...     geometric_slerp(start,
        ...                     opposite_pole,
        ...                     t_vals)
        array([[ 1.00000000e+00,  0.00000000e+00],
               [ 5.00000000e-01,  8.66025404e-01],
               [-5.00000000e-01,  8.66025404e-01],
               [-1.00000000e+00,  1.22464680e-16]])

        Extend the original example to a sphere and plot interpolation
        points in 3D:

        >>> from mpl_toolkits.mplot3d import proj3d
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111, projection='3d')

        Plot the unit sphere for reference (optional):

        >>> u = np.linspace(0, 2 * np.pi, 100)
        >>> v = np.linspace(0, np.pi, 100)
        >>> x = np.outer(np.cos(u), np.sin(v))
        >>> y = np.outer(np.sin(u), np.sin(v))
        >>> z = np.outer(np.ones(np.size(u)), np.cos(v))
        >>> ax.plot_surface(x, y, z, color='y', alpha=0.1)

        Interpolating over a larger number of points
        may provide the appearance of a smooth curve on
        the surface of the sphere, which is also useful
        for discretized integration calculations on a
        sphere surface:

        >>> start = np.array([1, 0, 0])
        >>> end = np.array([0, 0, 1])
        >>> t_vals = np.linspace(0, 1, 200)
        >>> result = geometric_slerp(start,
        ...                          end,
        ...                          t_vals)
        >>> ax.plot(result[...,0],
        ...         result[...,1],
        ...         result[...,2],
        ...         c='k')
        >>> plt.show()

    minkowski_distance(x, y, p=2)
        Compute the L**p distance between two arrays.

        The last dimensions of `x` and `y` must be the same length.  Any
        other dimensions must be compatible for broadcasting.

        Parameters
        ----------
        x : (..., K) array_like
            Input array.
        y : (..., K) array_like
            Input array.
        p : float, 1 <= p <= infinity
            Which Minkowski p-norm to use.

        Returns
        -------
        dist : ndarray
            Distance between the input arrays.

        Examples
        --------
        >>> from scipy.spatial import minkowski_distance
        >>> minkowski_distance([[0, 0], [0, 0]], [[1, 1], [0, 1]])
        array([ 1.41421356,  1.        ])

    minkowski_distance_p(x, y, p=2)
        Compute the pth power of the L**p distance between two arrays.

        For efficiency, this function computes the L**p distance but does
        not extract the pth root. If `p` is 1 or infinity, this is equal to
        the actual L**p distance.

        The last dimensions of `x` and `y` must be the same length.  Any
        other dimensions must be compatible for broadcasting.

        Parameters
        ----------
        x : (..., K) array_like
            Input array.
        y : (..., K) array_like
            Input array.
        p : float, 1 <= p <= infinity
            Which Minkowski p-norm to use.

        Returns
        -------
        dist : ndarray
            pth power of the distance between the input arrays.

        Examples
        --------
        >>> from scipy.spatial import minkowski_distance_p
        >>> minkowski_distance_p([[0, 0], [0, 0]], [[1, 1], [0, 1]])
        array([2, 1])

    procrustes(data1, data2)
        Procrustes analysis, a similarity test for two data sets.

        Each input matrix is a set of points or vectors (the rows of the matrix).
        The dimension of the space is the number of columns of each matrix. Given
        two identically sized matrices, procrustes standardizes both such that:

        - :math:`tr(AA^{T}) = 1`.

        - Both sets of points are centered around the origin.

        Procrustes ([1]_, [2]_) then applies the optimal transform to the second
        matrix (including scaling/dilation, rotations, and reflections) to minimize
        :math:`M^{2}=\sum(data1-data2)^{2}`, or the sum of the squares of the
        pointwise differences between the two input datasets.

        This function was not designed to handle datasets with different numbers of
        datapoints (rows).  If two data sets have different dimensionality
        (different number of columns), simply add columns of zeros to the smaller
        of the two.

        Parameters
        ----------
        data1 : array_like
            Matrix, n rows represent points in k (columns) space `data1` is the
            reference data, after it is standardised, the data from `data2` will be
            transformed to fit the pattern in `data1` (must have >1 unique points).
        data2 : array_like
            n rows of data in k space to be fit to `data1`.  Must be the  same
            shape ``(numrows, numcols)`` as data1 (must have >1 unique points).

        Returns
        -------
        mtx1 : array_like
            A standardized version of `data1`.
        mtx2 : array_like
            The orientation of `data2` that best fits `data1`. Centered, but not
            necessarily :math:`tr(AA^{T}) = 1`.
        disparity : float
            :math:`M^{2}` as defined above.

        Raises
        ------
        ValueError
            If the input arrays are not two-dimensional.
            If the shape of the input arrays is different.
            If the input arrays have zero columns or zero rows.

        See Also
        --------
        scipy.linalg.orthogonal_procrustes
        scipy.spatial.distance.directed_hausdorff : Another similarity test
          for two data sets

        Notes
        -----
        - The disparity should not depend on the order of the input matrices, but
          the output matrices will, as only the first output matrix is guaranteed
          to be scaled such that :math:`tr(AA^{T}) = 1`.

        - Duplicate data points are generally ok, duplicating a data point will
          increase its effect on the procrustes fit.

        - The disparity scales as the number of points per input matrix.

        References
        ----------
        .. [1] Krzanowski, W. J. (2000). "Principles of Multivariate analysis".
        .. [2] Gower, J. C. (1975). "Generalized procrustes analysis".

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.spatial import procrustes

        The matrix ``b`` is a rotated, shifted, scaled and mirrored version of
        ``a`` here:

        >>> a = np.array([[1, 3], [1, 2], [1, 1], [2, 1]], 'd')
        >>> b = np.array([[4, -2], [4, -4], [4, -6], [2, -6]], 'd')
        >>> mtx1, mtx2, disparity = procrustes(a, b)
        >>> round(disparity)
        0.0

    tsearch(tri, xi)
        tsearch(tri, xi)

        Find simplices containing the given points. This function does the
        same thing as `Delaunay.find_simplex`.

        Parameters
        ----------
        tri : DelaunayInfo
            Delaunay triangulation
        xi : ndarray of double, shape (..., ndim)
            Points to locate

        Returns
        -------
        i : ndarray of int, same shape as `xi`
            Indices of simplices containing each point.
            Points outside the triangulation get the value -1.

        See Also
        --------
        Delaunay.find_simplex

        Notes
        -----
        .. versionadded:: 0.9

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.spatial import Delaunay, delaunay_plot_2d, tsearch
        >>> rng = np.random.default_rng()

        The Delaunay triangulation of a set of random points:

        >>> pts = rng.random((20, 2))
        >>> tri = Delaunay(pts)
        >>> _ = delaunay_plot_2d(tri)

        Find the simplices containing a given set of points:

        >>> loc = rng.uniform(0.2, 0.8, (5, 2))
        >>> s = tsearch(tri, loc)
        >>> plt.triplot(pts[:, 0], pts[:, 1], tri.simplices[s], 'b-', mask=s==-1)
        >>> plt.scatter(loc[:, 0], loc[:, 1], c='r', marker='x')
        >>> plt.show()

    voronoi_plot_2d(vor, ax=None, **kw)
        Plot the given Voronoi diagram in 2-D

        Parameters
        ----------
        vor : scipy.spatial.Voronoi instance
            Diagram to plot
        ax : matplotlib.axes.Axes instance, optional
            Axes to plot on
        show_points : bool, optional
            Add the Voronoi points to the plot.
        show_vertices : bool, optional
            Add the Voronoi vertices to the plot.
        line_colors : string, optional
            Specifies the line color for polygon boundaries
        line_width : float, optional
            Specifies the line width for polygon boundaries
        line_alpha : float, optional
            Specifies the line alpha for polygon boundaries
        point_size : float, optional
            Specifies the size of points

        Returns
        -------
        fig : matplotlib.figure.Figure instance
            Figure for the plot

        See Also
        --------
        Voronoi

        Notes
        -----
        Requires Matplotlib.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.spatial import Voronoi, voronoi_plot_2d

        Create a set of points for the example:

        >>> rng = np.random.default_rng()
        >>> points = rng.random((10,2))

        Generate the Voronoi diagram for the points:

        >>> vor = Voronoi(points)

        Use `voronoi_plot_2d` to plot the diagram:

        >>> fig = voronoi_plot_2d(vor)

        Use `voronoi_plot_2d` to plot the diagram again, with some settings
        customized:

        >>> fig = voronoi_plot_2d(vor, show_vertices=False, line_colors='orange',
        ...                       line_width=2, line_alpha=0.6, point_size=2)
        >>> plt.show()

DATA
    __all__ = ['ConvexHull', 'Delaunay', 'HalfspaceIntersection', 'KDTree'...

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\spatial\__init__.py

scipy.special
Python Library Documentation: package scipy.special in scipy

NAME
    scipy.special

DESCRIPTION
    ========================================
    Special functions (:mod:`scipy.special`)
    ========================================

    .. currentmodule:: scipy.special

    Almost all of the functions below accept NumPy arrays as input
    arguments as well as single numbers. This means they follow
    broadcasting and automatic array-looping rules. Technically,
    they are `NumPy universal functions
    <https://numpy.org/doc/stable/user/basics.ufuncs.html#ufuncs-basics>`_.
    Functions which do not accept NumPy arrays are marked by a warning
    in the section description.

    .. seealso::

       `scipy.special.cython_special` -- Typed Cython versions of special functions


    Error handling
    ==============

    Errors are handled by returning NaNs or other appropriate values.
    Some of the special function routines can emit warnings or raise
    exceptions when an error occurs. By default this is disabled; to
    query and control the current error handling state the following
    functions are provided.

    .. autosummary::
       :toctree: generated/

       geterr                 -- Get the current way of handling special-function errors.
       seterr                 -- Set how special-function errors are handled.
       errstate               -- Context manager for special-function error handling.
       SpecialFunctionWarning -- Warning that can be emitted by special functions.
       SpecialFunctionError   -- Exception that can be raised by special functions.

    Available functions
    ===================

    Airy functions
    --------------

    .. autosummary::
       :toctree: generated/

       airy     -- Airy functions and their derivatives.
       airye    -- Exponentially scaled Airy functions and their derivatives.
       ai_zeros -- Compute `nt` zeros and values of the Airy function Ai and its derivative.
       bi_zeros -- Compute `nt` zeros and values of the Airy function Bi and its derivative.
       itairy   -- Integrals of Airy functions


    Elliptic functions and integrals
    --------------------------------

    .. autosummary::
       :toctree: generated/

       ellipj    -- Jacobian elliptic functions.
       ellipk    -- Complete elliptic integral of the first kind.
       ellipkm1  -- Complete elliptic integral of the first kind around `m` = 1.
       ellipkinc -- Incomplete elliptic integral of the first kind.
       ellipe    -- Complete elliptic integral of the second kind.
       ellipeinc -- Incomplete elliptic integral of the second kind.
       elliprc   -- Degenerate symmetric integral RC.
       elliprd   -- Symmetric elliptic integral of the second kind.
       elliprf   -- Completely-symmetric elliptic integral of the first kind.
       elliprg   -- Completely-symmetric elliptic integral of the second kind.
       elliprj   -- Symmetric elliptic integral of the third kind.

    Bessel functions
    ----------------

    .. autosummary::
       :toctree: generated/

       jv                -- Bessel function of the first kind of real order and                         complex argument.
       jve               -- Exponentially scaled Bessel function of order `v`.
       yn                -- Bessel function of the second kind of integer order and                         real argument.
       yv                -- Bessel function of the second kind of real order and                         complex argument.
       yve               -- Exponentially scaled Bessel function of the second kind                         of real order.
       kn                -- Modified Bessel function of the second kind of integer                         order `n`
       kv                -- Modified Bessel function of the second kind of real order                         `v`
       kve               -- Exponentially scaled modified Bessel function of the                         second kind.
       iv                -- Modified Bessel function of the first kind of real order.
       ive               -- Exponentially scaled modified Bessel function of the                         first kind.
       hankel1           -- Hankel function of the first kind.
       hankel1e          -- Exponentially scaled Hankel function of the first kind.
       hankel2           -- Hankel function of the second kind.
       hankel2e          -- Exponentially scaled Hankel function of the second kind.
       wright_bessel     -- Wright's generalized Bessel function.
       log_wright_bessel -- Logarithm of Wright's generalized Bessel function.

    The following function does not accept NumPy arrays (it is not a
    universal function):

    .. autosummary::
       :toctree: generated/

       lmbda -- Jahnke-Emden Lambda function, Lambdav(x).

    Zeros of Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^^

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       jnjnp_zeros -- Compute zeros of integer-order Bessel functions Jn and Jn'.
       jnyn_zeros  -- Compute nt zeros of Bessel functions Jn(x), Jn'(x), Yn(x), and Yn'(x).
       jn_zeros    -- Compute zeros of integer-order Bessel function Jn(x).
       jnp_zeros   -- Compute zeros of integer-order Bessel function derivative Jn'(x).
       yn_zeros    -- Compute zeros of integer-order Bessel function Yn(x).
       ynp_zeros   -- Compute zeros of integer-order Bessel function derivative Yn'(x).
       y0_zeros    -- Compute nt zeros of Bessel function Y0(z), and derivative at each zero.
       y1_zeros    -- Compute nt zeros of Bessel function Y1(z), and derivative at each zero.
       y1p_zeros   -- Compute nt zeros of Bessel derivative Y1'(z), and value at each zero.

    Faster versions of common Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       j0  -- Bessel function of the first kind of order 0.
       j1  -- Bessel function of the first kind of order 1.
       y0  -- Bessel function of the second kind of order 0.
       y1  -- Bessel function of the second kind of order 1.
       i0  -- Modified Bessel function of order 0.
       i0e -- Exponentially scaled modified Bessel function of order 0.
       i1  -- Modified Bessel function of order 1.
       i1e -- Exponentially scaled modified Bessel function of order 1.
       k0  -- Modified Bessel function of the second kind of order 0, :math:`K_0`.
       k0e -- Exponentially scaled modified Bessel function K of order 0
       k1  -- Modified Bessel function of the second kind of order 1, :math:`K_1(x)`.
       k1e -- Exponentially scaled modified Bessel function K of order 1.

    Integrals of Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       itj0y0     -- Integrals of Bessel functions of order 0.
       it2j0y0    -- Integrals related to Bessel functions of order 0.
       iti0k0     -- Integrals of modified Bessel functions of order 0.
       it2i0k0    -- Integrals related to modified Bessel functions of order 0.
       besselpoly -- Weighted integral of a Bessel function.

    Derivatives of Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       jvp  -- Compute nth derivative of Bessel function Jv(z) with respect to `z`.
       yvp  -- Compute nth derivative of Bessel function Yv(z) with respect to `z`.
       kvp  -- Compute nth derivative of real-order modified Bessel function Kv(z)
       ivp  -- Compute nth derivative of modified Bessel function Iv(z) with respect to `z`.
       h1vp -- Compute nth derivative of Hankel function H1v(z) with respect to `z`.
       h2vp -- Compute nth derivative of Hankel function H2v(z) with respect to `z`.

    Spherical Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       spherical_jn -- Spherical Bessel function of the first kind or its derivative.
       spherical_yn -- Spherical Bessel function of the second kind or its derivative.
       spherical_in -- Modified spherical Bessel function of the first kind or its derivative.
       spherical_kn -- Modified spherical Bessel function of the second kind or its derivative.

    Riccati-Bessel functions
    ^^^^^^^^^^^^^^^^^^^^^^^^

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       riccati_jn -- Compute Ricatti-Bessel function of the first kind and its derivative.
       riccati_yn -- Compute Ricatti-Bessel function of the second kind and its derivative.

    Struve functions
    ----------------

    .. autosummary::
       :toctree: generated/

       struve       -- Struve function.
       modstruve    -- Modified Struve function.
       itstruve0    -- Integral of the Struve function of order 0.
       it2struve0   -- Integral related to the Struve function of order 0.
       itmodstruve0 -- Integral of the modified Struve function of order 0.


    Raw statistical functions
    -------------------------

    .. seealso:: :mod:`scipy.stats`: Friendly versions of these functions.

    Binomial distribution
    ^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       bdtr         -- Binomial distribution cumulative distribution function.
       bdtrc        -- Binomial distribution survival function.
       bdtri        -- Inverse function to `bdtr` with respect to `p`.
       bdtrik       -- Inverse function to `bdtr` with respect to `k`.
       bdtrin       -- Inverse function to `bdtr` with respect to `n`.

    Beta distribution
    ^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       btdtr        -- Cumulative distribution function of the beta distribution.
       btdtri       -- The `p`-th quantile of the beta distribution.
       btdtria      -- Inverse of `btdtr` with respect to `a`.
       btdtrib      -- btdtria(a, p, x).

    F distribution
    ^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       fdtr         -- F cumulative distribution function.
       fdtrc        -- F survival function.
       fdtri        -- The `p`-th quantile of the F-distribution.
       fdtridfd     -- Inverse to `fdtr` vs dfd.

    Gamma distribution
    ^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       gdtr         -- Gamma distribution cumulative distribution function.
       gdtrc        -- Gamma distribution survival function.
       gdtria       -- Inverse of `gdtr` vs a.
       gdtrib       -- Inverse of `gdtr` vs b.
       gdtrix       -- Inverse of `gdtr` vs x.

    Negative binomial distribution
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       nbdtr        -- Negative binomial cumulative distribution function.
       nbdtrc       -- Negative binomial survival function.
       nbdtri       -- Inverse of `nbdtr` vs `p`.
       nbdtrik      -- Inverse of `nbdtr` vs `k`.
       nbdtrin      -- Inverse of `nbdtr` vs `n`.

    Noncentral F distribution
    ^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       ncfdtr       -- Cumulative distribution function of the non-central F distribution.
       ncfdtridfd   -- Calculate degrees of freedom (denominator) for the noncentral F-distribution.
       ncfdtridfn   -- Calculate degrees of freedom (numerator) for the noncentral F-distribution.
       ncfdtri      -- Inverse cumulative distribution function of the non-central F distribution.
       ncfdtrinc    -- Calculate non-centrality parameter for non-central F distribution.

    Noncentral t distribution
    ^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       nctdtr       -- Cumulative distribution function of the non-central `t` distribution.
       nctdtridf    -- Calculate degrees of freedom for non-central t distribution.
       nctdtrit     -- Inverse cumulative distribution function of the non-central t distribution.
       nctdtrinc    -- Calculate non-centrality parameter for non-central t distribution.

    Normal distribution
    ^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       nrdtrimn     -- Calculate mean of normal distribution given other params.
       nrdtrisd     -- Calculate standard deviation of normal distribution given other params.
       ndtr         -- Normal cumulative distribution function.
       log_ndtr     -- Logarithm of normal cumulative distribution function.
       ndtri        -- Inverse of `ndtr` vs x.
       ndtri_exp    -- Inverse of `log_ndtr` vs x.

    Poisson distribution
    ^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       pdtr         -- Poisson cumulative distribution function.
       pdtrc        -- Poisson survival function.
       pdtri        -- Inverse to `pdtr` vs m.
       pdtrik       -- Inverse to `pdtr` vs k.

    Student t distribution
    ^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       stdtr        -- Student t distribution cumulative distribution function.
       stdtridf     -- Inverse of `stdtr` vs df.
       stdtrit      -- Inverse of `stdtr` vs `t`.

    Chi square distribution
    ^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       chdtr        -- Chi square cumulative distribution function.
       chdtrc       -- Chi square survival function.
       chdtri       -- Inverse to `chdtrc`.
       chdtriv      -- Inverse to `chdtr` vs `v`.

    Non-central chi square distribution
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       chndtr       -- Non-central chi square cumulative distribution function.
       chndtridf    -- Inverse to `chndtr` vs `df`.
       chndtrinc    -- Inverse to `chndtr` vs `nc`.
       chndtrix     -- Inverse to `chndtr` vs `x`.

    Kolmogorov distribution
    ^^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       smirnov      -- Kolmogorov-Smirnov complementary cumulative distribution function.
       smirnovi     -- Inverse to `smirnov`.
       kolmogorov   -- Complementary cumulative distribution function of Kolmogorov distribution.
       kolmogi      -- Inverse function to `kolmogorov`.

    Box-Cox transformation
    ^^^^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       boxcox       -- Compute the Box-Cox transformation.
       boxcox1p     -- Compute the Box-Cox transformation of 1 + `x`.
       inv_boxcox   -- Compute the inverse of the Box-Cox transformation.
       inv_boxcox1p -- Compute the inverse of the Box-Cox transformation.


    Sigmoidal functions
    ^^^^^^^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       logit        -- Logit ufunc for ndarrays.
       expit        -- Logistic sigmoid function.
       log_expit    -- Logarithm of the logistic sigmoid function.

    Miscellaneous
    ^^^^^^^^^^^^^

    .. autosummary::
       :toctree: generated/

       tklmbda      -- Tukey-Lambda cumulative distribution function.
       owens_t      -- Owen's T Function.


    Information Theory functions
    ----------------------------

    .. autosummary::
       :toctree: generated/

       entr         -- Elementwise function for computing entropy.
       rel_entr     -- Elementwise function for computing relative entropy.
       kl_div       -- Elementwise function for computing Kullback-Leibler divergence.
       huber        -- Huber loss function.
       pseudo_huber -- Pseudo-Huber loss function.


    Gamma and related functions
    ---------------------------

    .. autosummary::
       :toctree: generated/

       gamma        -- Gamma function.
       gammaln      -- Logarithm of the absolute value of the Gamma function for real inputs.
       loggamma     -- Principal branch of the logarithm of the Gamma function.
       gammasgn     -- Sign of the gamma function.
       gammainc     -- Regularized lower incomplete gamma function.
       gammaincinv  -- Inverse to `gammainc`.
       gammaincc    -- Regularized upper incomplete gamma function.
       gammainccinv -- Inverse to `gammaincc`.
       beta         -- Beta function.
       betaln       -- Natural logarithm of absolute value of beta function.
       betainc      -- Incomplete beta integral.
       betaincc     -- Complemented incomplete beta integral.
       betaincinv   -- Inverse function to beta integral.
       betainccinv  -- Inverse of the complemented incomplete beta integral.
       psi          -- The digamma function.
       rgamma       -- Gamma function inverted.
       polygamma    -- Polygamma function n.
       multigammaln -- Returns the log of multivariate gamma, also sometimes called the generalized gamma.
       digamma      -- psi(x[, out]).
       poch         -- Rising factorial (z)_m.


    Error function and Fresnel integrals
    ------------------------------------

    .. autosummary::
       :toctree: generated/

       erf           -- Returns the error function of complex argument.
       erfc          -- Complementary error function, ``1 - erf(x)``.
       erfcx         -- Scaled complementary error function, ``exp(x**2) * erfc(x)``.
       erfi          -- Imaginary error function, ``-i erf(i z)``.
       erfinv        -- Inverse function for erf.
       erfcinv       -- Inverse function for erfc.
       wofz          -- Faddeeva function.
       dawsn         -- Dawson's integral.
       fresnel       -- Fresnel sin and cos integrals.
       fresnel_zeros -- Compute nt complex zeros of sine and cosine Fresnel integrals S(z) and C(z).
       modfresnelp   -- Modified Fresnel positive integrals.
       modfresnelm   -- Modified Fresnel negative integrals.
       voigt_profile -- Voigt profile.

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       erf_zeros      -- Compute nt complex zeros of error function erf(z).
       fresnelc_zeros -- Compute nt complex zeros of cosine Fresnel integral C(z).
       fresnels_zeros -- Compute nt complex zeros of sine Fresnel integral S(z).

    Legendre functions
    ------------------

    .. autosummary::
       :toctree: generated/

       lpmv     -- Associated Legendre function of integer order and real degree.
       sph_harm -- Compute spherical harmonics.

    .. autosummary::
       :toctree: generated/

       clpmn -- Associated Legendre function of the first kind for complex arguments.
       lpn   -- Legendre function of the first kind.
       lqn   -- Legendre function of the second kind.
       lpmn  -- Sequence of associated Legendre functions of the first kind.
       lqmn  -- Sequence of associated Legendre functions of the second kind.

    Ellipsoidal harmonics
    ---------------------

    .. autosummary::
       :toctree: generated/

       ellip_harm   -- Ellipsoidal harmonic functions E^p_n(l).
       ellip_harm_2 -- Ellipsoidal harmonic functions F^p_n(l).
       ellip_normal -- Ellipsoidal harmonic normalization constants gamma^p_n.

    Orthogonal polynomials
    ----------------------

    The following functions evaluate values of orthogonal polynomials:

    .. autosummary::
       :toctree: generated/

       assoc_laguerre   -- Compute the generalized (associated) Laguerre polynomial of degree n and order k.
       eval_legendre    -- Evaluate Legendre polynomial at a point.
       eval_chebyt      -- Evaluate Chebyshev polynomial of the first kind at a point.
       eval_chebyu      -- Evaluate Chebyshev polynomial of the second kind at a point.
       eval_chebyc      -- Evaluate Chebyshev polynomial of the first kind on [-2, 2] at a point.
       eval_chebys      -- Evaluate Chebyshev polynomial of the second kind on [-2, 2] at a point.
       eval_jacobi      -- Evaluate Jacobi polynomial at a point.
       eval_laguerre    -- Evaluate Laguerre polynomial at a point.
       eval_genlaguerre -- Evaluate generalized Laguerre polynomial at a point.
       eval_hermite     -- Evaluate physicist's Hermite polynomial at a point.
       eval_hermitenorm -- Evaluate probabilist's (normalized) Hermite polynomial at a point.
       eval_gegenbauer  -- Evaluate Gegenbauer polynomial at a point.
       eval_sh_legendre -- Evaluate shifted Legendre polynomial at a point.
       eval_sh_chebyt   -- Evaluate shifted Chebyshev polynomial of the first kind at a point.
       eval_sh_chebyu   -- Evaluate shifted Chebyshev polynomial of the second kind at a point.
       eval_sh_jacobi   -- Evaluate shifted Jacobi polynomial at a point.

    The following functions compute roots and quadrature weights for
    orthogonal polynomials:

    .. autosummary::
       :toctree: generated/

       roots_legendre    -- Gauss-Legendre quadrature.
       roots_chebyt      -- Gauss-Chebyshev (first kind) quadrature.
       roots_chebyu      -- Gauss-Chebyshev (second kind) quadrature.
       roots_chebyc      -- Gauss-Chebyshev (first kind) quadrature.
       roots_chebys      -- Gauss-Chebyshev (second kind) quadrature.
       roots_jacobi      -- Gauss-Jacobi quadrature.
       roots_laguerre    -- Gauss-Laguerre quadrature.
       roots_genlaguerre -- Gauss-generalized Laguerre quadrature.
       roots_hermite     -- Gauss-Hermite (physicst's) quadrature.
       roots_hermitenorm -- Gauss-Hermite (statistician's) quadrature.
       roots_gegenbauer  -- Gauss-Gegenbauer quadrature.
       roots_sh_legendre -- Gauss-Legendre (shifted) quadrature.
       roots_sh_chebyt   -- Gauss-Chebyshev (first kind, shifted) quadrature.
       roots_sh_chebyu   -- Gauss-Chebyshev (second kind, shifted) quadrature.
       roots_sh_jacobi   -- Gauss-Jacobi (shifted) quadrature.

    The functions below, in turn, return the polynomial coefficients in
    ``orthopoly1d`` objects, which function similarly as `numpy.poly1d`.
    The ``orthopoly1d`` class also has an attribute ``weights``, which returns
    the roots, weights, and total weights for the appropriate form of Gaussian
    quadrature. These are returned in an ``n x 3`` array with roots in the first
    column, weights in the second column, and total weights in the final column.
    Note that ``orthopoly1d`` objects are converted to `~numpy.poly1d` when doing
    arithmetic, and lose information of the original orthogonal polynomial.

    .. autosummary::
       :toctree: generated/

       legendre    -- Legendre polynomial.
       chebyt      -- Chebyshev polynomial of the first kind.
       chebyu      -- Chebyshev polynomial of the second kind.
       chebyc      -- Chebyshev polynomial of the first kind on :math:`[-2, 2]`.
       chebys      -- Chebyshev polynomial of the second kind on :math:`[-2, 2]`.
       jacobi      -- Jacobi polynomial.
       laguerre    -- Laguerre polynomial.
       genlaguerre -- Generalized (associated) Laguerre polynomial.
       hermite     -- Physicist's Hermite polynomial.
       hermitenorm -- Normalized (probabilist's) Hermite polynomial.
       gegenbauer  -- Gegenbauer (ultraspherical) polynomial.
       sh_legendre -- Shifted Legendre polynomial.
       sh_chebyt   -- Shifted Chebyshev polynomial of the first kind.
       sh_chebyu   -- Shifted Chebyshev polynomial of the second kind.
       sh_jacobi   -- Shifted Jacobi polynomial.

    .. warning::

       Computing values of high-order polynomials (around ``order > 20``) using
       polynomial coefficients is numerically unstable. To evaluate polynomial
       values, the ``eval_*`` functions should be used instead.


    Hypergeometric functions
    ------------------------

    .. autosummary::
       :toctree: generated/

       hyp2f1 -- Gauss hypergeometric function 2F1(a, b; c; z).
       hyp1f1 -- Confluent hypergeometric function 1F1(a, b; x).
       hyperu -- Confluent hypergeometric function U(a, b, x) of the second kind.
       hyp0f1 -- Confluent hypergeometric limit function 0F1.


    Parabolic cylinder functions
    ----------------------------

    .. autosummary::
       :toctree: generated/

       pbdv -- Parabolic cylinder function D.
       pbvv -- Parabolic cylinder function V.
       pbwa -- Parabolic cylinder function W.

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       pbdv_seq -- Parabolic cylinder functions Dv(x) and derivatives.
       pbvv_seq -- Parabolic cylinder functions Vv(x) and derivatives.
       pbdn_seq -- Parabolic cylinder functions Dn(z) and derivatives.

    Mathieu and related functions
    -----------------------------

    .. autosummary::
       :toctree: generated/

       mathieu_a -- Characteristic value of even Mathieu functions.
       mathieu_b -- Characteristic value of odd Mathieu functions.

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       mathieu_even_coef -- Fourier coefficients for even Mathieu and modified Mathieu functions.
       mathieu_odd_coef  -- Fourier coefficients for even Mathieu and modified Mathieu functions.

    The following return both function and first derivative:

    .. autosummary::
       :toctree: generated/

       mathieu_cem     -- Even Mathieu function and its derivative.
       mathieu_sem     -- Odd Mathieu function and its derivative.
       mathieu_modcem1 -- Even modified Mathieu function of the first kind and its derivative.
       mathieu_modcem2 -- Even modified Mathieu function of the second kind and its derivative.
       mathieu_modsem1 -- Odd modified Mathieu function of the first kind and its derivative.
       mathieu_modsem2 -- Odd modified Mathieu function of the second kind and its derivative.

    Spheroidal wave functions
    -------------------------

    .. autosummary::
       :toctree: generated/

       pro_ang1   -- Prolate spheroidal angular function of the first kind and its derivative.
       pro_rad1   -- Prolate spheroidal radial function of the first kind and its derivative.
       pro_rad2   -- Prolate spheroidal radial function of the second kind and its derivative.
       obl_ang1   -- Oblate spheroidal angular function of the first kind and its derivative.
       obl_rad1   -- Oblate spheroidal radial function of the first kind and its derivative.
       obl_rad2   -- Oblate spheroidal radial function of the second kind and its derivative.
       pro_cv     -- Characteristic value of prolate spheroidal function.
       obl_cv     -- Characteristic value of oblate spheroidal function.
       pro_cv_seq -- Characteristic values for prolate spheroidal wave functions.
       obl_cv_seq -- Characteristic values for oblate spheroidal wave functions.

    The following functions require pre-computed characteristic value:

    .. autosummary::
       :toctree: generated/

       pro_ang1_cv -- Prolate spheroidal angular function pro_ang1 for precomputed characteristic value.
       pro_rad1_cv -- Prolate spheroidal radial function pro_rad1 for precomputed characteristic value.
       pro_rad2_cv -- Prolate spheroidal radial function pro_rad2 for precomputed characteristic value.
       obl_ang1_cv -- Oblate spheroidal angular function obl_ang1 for precomputed characteristic value.
       obl_rad1_cv -- Oblate spheroidal radial function obl_rad1 for precomputed characteristic value.
       obl_rad2_cv -- Oblate spheroidal radial function obl_rad2 for precomputed characteristic value.

    Kelvin functions
    ----------------

    .. autosummary::
       :toctree: generated/

       kelvin       -- Kelvin functions as complex numbers.
       kelvin_zeros -- Compute nt zeros of all Kelvin functions.
       ber          -- Kelvin function ber.
       bei          -- Kelvin function bei
       berp         -- Derivative of the Kelvin function `ber`.
       beip         -- Derivative of the Kelvin function `bei`.
       ker          -- Kelvin function ker.
       kei          -- Kelvin function ker.
       kerp         -- Derivative of the Kelvin function ker.
       keip         -- Derivative of the Kelvin function kei.

    The following functions do not accept NumPy arrays (they are not
    universal functions):

    .. autosummary::
       :toctree: generated/

       ber_zeros  -- Compute nt zeros of the Kelvin function ber(x).
       bei_zeros  -- Compute nt zeros of the Kelvin function bei(x).
       berp_zeros -- Compute nt zeros of the Kelvin function ber'(x).
       beip_zeros -- Compute nt zeros of the Kelvin function bei'(x).
       ker_zeros  -- Compute nt zeros of the Kelvin function ker(x).
       kei_zeros  -- Compute nt zeros of the Kelvin function kei(x).
       kerp_zeros -- Compute nt zeros of the Kelvin function ker'(x).
       keip_zeros -- Compute nt zeros of the Kelvin function kei'(x).

    Combinatorics
    -------------

    .. autosummary::
       :toctree: generated/

       comb -- The number of combinations of N things taken k at a time.
       perm -- Permutations of N things taken k at a time, i.e., k-permutations of N.
       stirling2 -- Stirling numbers of the second kind.

    Lambert W and related functions
    -------------------------------

    .. autosummary::
       :toctree: generated/

       lambertw    -- Lambert W function.
       wrightomega -- Wright Omega function.

    Other special functions
    -----------------------

    .. autosummary::
       :toctree: generated/

       agm         -- Arithmetic, Geometric Mean.
       bernoulli   -- Bernoulli numbers B0..Bn (inclusive).
       binom       -- Binomial coefficient
       diric       -- Periodic sinc function, also called the Dirichlet function.
       euler       -- Euler numbers E0..En (inclusive).
       expn        -- Exponential integral E_n.
       exp1        -- Exponential integral E_1 of complex argument z.
       expi        -- Exponential integral Ei.
       factorial   -- The factorial of a number or array of numbers.
       factorial2  -- Double factorial.
       factorialk  -- Multifactorial of n of order k, n(!!...!).
       shichi      -- Hyperbolic sine and cosine integrals.
       sici        -- Sine and cosine integrals.
       softmax     -- Softmax function.
       log_softmax -- Logarithm of softmax function.
       spence      -- Spence's function, also known as the dilogarithm.
       zeta        -- Riemann zeta function.
       zetac       -- Riemann zeta function minus 1.

    Convenience functions
    ---------------------

    .. autosummary::
       :toctree: generated/

       cbrt      -- Cube root of `x`.
       exp10     -- 10**x.
       exp2      -- 2**x.
       radian    -- Convert from degrees to radians.
       cosdg     -- Cosine of the angle `x` given in degrees.
       sindg     -- Sine of angle given in degrees.
       tandg     -- Tangent of angle x given in degrees.
       cotdg     -- Cotangent of the angle `x` given in degrees.
       log1p     -- Calculates log(1+x) for use when `x` is near zero.
       expm1     -- ``exp(x) - 1`` for use when `x` is near zero.
       cosm1     -- ``cos(x) - 1`` for use when `x` is near zero.
       powm1     -- ``x**y - 1`` for use when `y` is near zero or `x` is near 1.
       round     -- Round to nearest integer.
       xlogy     -- Compute ``x*log(y)`` so that the result is 0 if ``x = 0``.
       xlog1py   -- Compute ``x*log1p(y)`` so that the result is 0 if ``x = 0``.
       logsumexp -- Compute the log of the sum of exponentials of input elements.
       exprel    -- Relative error exponential, (exp(x)-1)/x, for use when `x` is near zero.
       sinc      -- Return the sinc function.

PACKAGE CONTENTS
    _add_newdocs
    _basic
    _comb
    _ellip_harm
    _ellip_harm_2
    _gufuncs
    _lambertw
    _logsumexp
    _mptestutils
    _orthogonal
    _precompute (package)
    _sf_error
    _specfun
    _special_ufuncs
    _spfun_stats
    _spherical_bessel
    _support_alternative_backends
    _test_internal
    _testutils
    _ufuncs
    _ufuncs_cxx
    add_newdocs
    basic
    cython_special
    orthogonal
    sf_error
    specfun
    spfun_stats
    tests (package)

CLASSES
    builtins.Exception(builtins.BaseException)
        scipy.special._sf_error.SpecialFunctionError
    builtins.Warning(builtins.Exception)
        scipy.special._sf_error.SpecialFunctionWarning
    builtins.object
        scipy.special._ufuncs.errstate

    class SpecialFunctionError(builtins.Exception)
     |  Exception that can be raised by special functions.
     |
     |  Method resolution order:
     |      SpecialFunctionError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Exception:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Exception:
     |
     |  __new__(*args, **kwargs) class method of builtins.Exception
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class SpecialFunctionWarning(builtins.Warning)
     |  Warning that can be emitted by special functions.
     |
     |  Method resolution order:
     |      SpecialFunctionWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.Warning:
     |
     |  __init__(self, /, *args, **kwargs)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.Warning:
     |
     |  __new__(*args, **kwargs) class method of builtins.Warning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class errstate(builtins.object)
     |  errstate(**kwargs)
     |
     |  Context manager for special-function error handling.
     |
     |  Using an instance of `errstate` as a context manager allows
     |  statements in that context to execute with a known error handling
     |  behavior. Upon entering the context the error handling is set with
     |  `seterr`, and upon exiting it is restored to what it was before.
     |
     |  Parameters
     |  ----------
     |  kwargs : {all, singular, underflow, overflow, slow, loss, no_result, domain, arg, other}
     |      Keyword arguments. The valid keywords are possible
     |      special-function errors. Each keyword should have a string
     |      value that defines the treatment for the particular type of
     |      error. Values must be 'ignore', 'warn', or 'other'. See
     |      `seterr` for details.
     |
     |  See Also
     |  --------
     |  geterr : get the current way of handling special-function errors
     |  seterr : set how special-function errors are handled
     |  numpy.errstate : similar numpy function for floating-point errors
     |
     |  Examples
     |  --------
     |  >>> import scipy.special as sc
     |  >>> from pytest import raises
     |  >>> sc.gammaln(0)
     |  inf
     |  >>> with sc.errstate(singular='raise'):
     |  ...     with raises(sc.SpecialFunctionError):
     |  ...         sc.gammaln(0)
     |  ...
     |  >>> sc.gammaln(0)
     |  inf
     |
     |  We can also raise on every category except one.
     |
     |  >>> with sc.errstate(all='raise', singular='ignore'):
     |  ...     sc.gammaln(0)
     |  ...     with raises(sc.SpecialFunctionError):
     |  ...         sc.spence(-1)
     |  ...
     |  inf
     |
     |  Methods defined here:
     |
     |  __enter__(self)
     |
     |  __exit__(self, exc_type, exc_value, traceback)
     |
     |  __init__(self, **kwargs)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

FUNCTIONS
    ai_zeros(nt)
        Compute `nt` zeros and values of the Airy function Ai and its derivative.

        Computes the first `nt` zeros, `a`, of the Airy function Ai(x);
        first `nt` zeros, `ap`, of the derivative of the Airy function Ai'(x);
        the corresponding values Ai(a');
        and the corresponding values Ai'(a).

        Parameters
        ----------
        nt : int
            Number of zeros to compute

        Returns
        -------
        a : ndarray
            First `nt` zeros of Ai(x)
        ap : ndarray
            First `nt` zeros of Ai'(x)
        ai : ndarray
            Values of Ai(x) evaluated at first `nt` zeros of Ai'(x)
        aip : ndarray
            Values of Ai'(x) evaluated at first `nt` zeros of Ai(x)

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        >>> from scipy import special
        >>> a, ap, ai, aip = special.ai_zeros(3)
        >>> a
        array([-2.33810741, -4.08794944, -5.52055983])
        >>> ap
        array([-1.01879297, -3.24819758, -4.82009921])
        >>> ai
        array([ 0.53565666, -0.41901548,  0.38040647])
        >>> aip
        array([ 0.70121082, -0.80311137,  0.86520403])

    assoc_laguerre(x, n, k=0.0)
        Compute the generalized (associated) Laguerre polynomial of degree n and order k.

        The polynomial :math:`L^{(k)}_n(x)` is orthogonal over ``[0, inf)``,
        with weighting function ``exp(-x) * x**k`` with ``k > -1``.

        Parameters
        ----------
        x : float or ndarray
            Points where to evaluate the Laguerre polynomial
        n : int
            Degree of the Laguerre polynomial
        k : int
            Order of the Laguerre polynomial

        Returns
        -------
        assoc_laguerre: float or ndarray
            Associated laguerre polynomial values

        Notes
        -----
        `assoc_laguerre` is a simple wrapper around `eval_genlaguerre`, with
        reversed argument order ``(x, n, k=0.0) --> (n, k, x)``.

    bei_zeros(nt)
        Compute nt zeros of the Kelvin function bei.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the Kelvin function.

        See Also
        --------
        bei

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    beip_zeros(nt)
        Compute nt zeros of the derivative of the Kelvin function bei.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the derivative of the Kelvin function.

        See Also
        --------
        bei, beip

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    ber_zeros(nt)
        Compute nt zeros of the Kelvin function ber.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the Kelvin function.

        See Also
        --------
        ber

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    bernoulli(n)
        Bernoulli numbers B0..Bn (inclusive).

        Parameters
        ----------
        n : int
            Indicated the number of terms in the Bernoulli series to generate.

        Returns
        -------
        ndarray
            The Bernoulli numbers ``[B(0), B(1), ..., B(n)]``.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] "Bernoulli number", Wikipedia, https://en.wikipedia.org/wiki/Bernoulli_number

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import bernoulli, zeta
        >>> bernoulli(4)
        array([ 1.        , -0.5       ,  0.16666667,  0.        , -0.03333333])

        The Wikipedia article ([2]_) points out the relationship between the
        Bernoulli numbers and the zeta function, ``B_n^+ = -n * zeta(1 - n)``
        for ``n > 0``:

        >>> n = np.arange(1, 5)
        >>> -n * zeta(1 - n)
        array([ 0.5       ,  0.16666667, -0.        , -0.03333333])

        Note that, in the notation used in the wikipedia article,
        `bernoulli` computes ``B_n^-`` (i.e. it used the convention that
        ``B_1`` is -1/2).  The relation given above is for ``B_n^+``, so the
        sign of 0.5 does not match the output of ``bernoulli(4)``.

    berp_zeros(nt)
        Compute nt zeros of the derivative of the Kelvin function ber.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the derivative of the Kelvin function.

        See Also
        --------
        ber, berp

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    bi_zeros(nt)
        Compute `nt` zeros and values of the Airy function Bi and its derivative.

        Computes the first `nt` zeros, b, of the Airy function Bi(x);
        first `nt` zeros, b', of the derivative of the Airy function Bi'(x);
        the corresponding values Bi(b');
        and the corresponding values Bi'(b).

        Parameters
        ----------
        nt : int
            Number of zeros to compute

        Returns
        -------
        b : ndarray
            First `nt` zeros of Bi(x)
        bp : ndarray
            First `nt` zeros of Bi'(x)
        bi : ndarray
            Values of Bi(x) evaluated at first `nt` zeros of Bi'(x)
        bip : ndarray
            Values of Bi'(x) evaluated at first `nt` zeros of Bi(x)

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        >>> from scipy import special
        >>> b, bp, bi, bip = special.bi_zeros(3)
        >>> b
        array([-1.17371322, -3.2710933 , -4.83073784])
        >>> bp
        array([-2.29443968, -4.07315509, -5.51239573])
        >>> bi
        array([-0.45494438,  0.39652284, -0.36796916])
        >>> bip
        array([ 0.60195789, -0.76031014,  0.83699101])

    btdtr(*args, **kwargs)
        btdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        btdtr(a, b, x, out=None)

        Cumulative distribution function of the beta distribution.

        Returns the integral from zero to `x` of the beta probability density
        function,

        .. math::
            I = \int_0^x \frac{\Gamma(a + b)}{\Gamma(a)\Gamma(b)} t^{a-1} (1-t)^{b-1}\,dt

        where :math:`\Gamma` is the gamma function.

        .. deprecated:: 1.12.0
            This function is deprecated and will be removed from SciPy 1.14.0.
            Use `scipy.special.betainc` instead.

        Parameters
        ----------
        a : array_like
            Shape parameter (a > 0).
        b : array_like
            Shape parameter (b > 0).
        x : array_like
            Upper limit of integration, in [0, 1].
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            Cumulative distribution function of the beta distribution with
            parameters `a` and `b` at `x`.

        See Also
        --------
        betainc

        Notes
        -----
        This function is identical to the incomplete beta integral function
        `betainc`.

        Wrapper for the Cephes [1]_ routine `btdtr`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    btdtri(*args, **kwargs)
        btdtri(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        btdtri(a, b, p, out=None)

        The `p`-th quantile of the beta distribution.

        This function is the inverse of the beta cumulative distribution function,
        `btdtr`, returning the value of `x` for which `btdtr(a, b, x) = p`, or

        .. math::
            p = \int_0^x \frac{\Gamma(a + b)}{\Gamma(a)\Gamma(b)} t^{a-1} (1-t)^{b-1}\,dt

        .. deprecated:: 1.12.0
            This function is deprecated and will be removed from SciPy 1.14.0.
            Use `scipy.special.betaincinv` instead.

        Parameters
        ----------
        a : array_like
            Shape parameter (`a` > 0).
        b : array_like
            Shape parameter (`b` > 0).
        p : array_like
            Cumulative probability, in [0, 1].
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        x : scalar or ndarray
            The quantile corresponding to `p`.

        See Also
        --------
        betaincinv
        btdtr

        Notes
        -----
        The value of `x` is found by interval halving or Newton iterations.

        Wrapper for the Cephes [1]_ routine `incbi`, which solves the equivalent
        problem of finding the inverse of the incomplete beta integral.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    c_roots = roots_chebyc(n, mu=False)
        Gauss-Chebyshev (first kind) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the first kind, :math:`C_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
        with weight function :math:`w(x) = 1 / \sqrt{1 - (x/2)^2}`. See
        22.2.6 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    cg_roots = roots_gegenbauer(n, alpha, mu=False)
        Gauss-Gegenbauer quadrature.

        Compute the sample points and weights for Gauss-Gegenbauer
        quadrature. The sample points are the roots of the nth degree
        Gegenbauer polynomial, :math:`C^{\alpha}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
        weight function :math:`w(x) = (1 - x^2)^{\alpha - 1/2}`. See
        22.2.3 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -0.5
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    chebyc(n, monic=False)
        Chebyshev polynomial of the first kind on :math:`[-2, 2]`.

        Defined as :math:`C_n(x) = 2T_n(x/2)`, where :math:`T_n` is the
        nth Chebychev polynomial of the first kind.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        C : orthopoly1d
            Chebyshev polynomial of the first kind on :math:`[-2, 2]`.

        See Also
        --------
        chebyt : Chebyshev polynomial of the first kind.

        Notes
        -----
        The polynomials :math:`C_n(x)` are orthogonal over :math:`[-2, 2]`
        with weight function :math:`1/\sqrt{1 - (x/2)^2}`.

        References
        ----------
        .. [1] Abramowitz and Stegun, "Handbook of Mathematical Functions"
               Section 22. National Bureau of Standards, 1972.

    chebys(n, monic=False)
        Chebyshev polynomial of the second kind on :math:`[-2, 2]`.

        Defined as :math:`S_n(x) = U_n(x/2)` where :math:`U_n` is the
        nth Chebychev polynomial of the second kind.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        S : orthopoly1d
            Chebyshev polynomial of the second kind on :math:`[-2, 2]`.

        See Also
        --------
        chebyu : Chebyshev polynomial of the second kind

        Notes
        -----
        The polynomials :math:`S_n(x)` are orthogonal over :math:`[-2, 2]`
        with weight function :math:`\sqrt{1 - (x/2)}^2`.

        References
        ----------
        .. [1] Abramowitz and Stegun, "Handbook of Mathematical Functions"
               Section 22. National Bureau of Standards, 1972.

    chebyt(n, monic=False)
        Chebyshev polynomial of the first kind.

        Defined to be the solution of

        .. math::
            (1 - x^2)\frac{d^2}{dx^2}T_n - x\frac{d}{dx}T_n + n^2T_n = 0;

        :math:`T_n` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        T : orthopoly1d
            Chebyshev polynomial of the first kind.

        See Also
        --------
        chebyu : Chebyshev polynomial of the second kind.

        Notes
        -----
        The polynomials :math:`T_n` are orthogonal over :math:`[-1, 1]`
        with weight function :math:`(1 - x^2)^{-1/2}`.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        Chebyshev polynomials of the first kind of order :math:`n` can
        be obtained as the determinant of specific :math:`n \times n`
        matrices. As an example we can check how the points obtained from
        the determinant of the following :math:`3 \times 3` matrix
        lay exactly on :math:`T_3`:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.linalg import det
        >>> from scipy.special import chebyt
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-2.0, 2.0)
        >>> ax.set_title(r'Chebyshev polynomial $T_3$')
        >>> ax.plot(x, chebyt(3)(x), label=rf'$T_3$')
        >>> for p in np.arange(-1.0, 1.0, 0.1):
        ...     ax.plot(p,
        ...             det(np.array([[p, 1, 0], [1, 2*p, 1], [0, 1, 2*p]])),
        ...             'rx')
        >>> plt.legend(loc='best')
        >>> plt.show()

        They are also related to the Jacobi Polynomials
        :math:`P_n^{(-0.5, -0.5)}` through the relation:

        .. math::
            P_n^{(-0.5, -0.5)}(x) = \frac{1}{4^n} \binom{2n}{n} T_n(x)

        Let's verify it for :math:`n = 3`:

        >>> from scipy.special import binom
        >>> from scipy.special import jacobi
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> np.allclose(jacobi(3, -0.5, -0.5)(x),
        ...             1/64 * binom(6, 3) * chebyt(3)(x))
        True

        We can plot the Chebyshev polynomials :math:`T_n` for some values
        of :math:`n`:

        >>> x = np.arange(-1.5, 1.5, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-4.0, 4.0)
        >>> ax.set_title(r'Chebyshev polynomials $T_n$')
        >>> for n in np.arange(2,5):
        ...     ax.plot(x, chebyt(n)(x), label=rf'$T_n={n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    chebyu(n, monic=False)
        Chebyshev polynomial of the second kind.

        Defined to be the solution of

        .. math::
            (1 - x^2)\frac{d^2}{dx^2}U_n - 3x\frac{d}{dx}U_n
              + n(n + 2)U_n = 0;

        :math:`U_n` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        U : orthopoly1d
            Chebyshev polynomial of the second kind.

        See Also
        --------
        chebyt : Chebyshev polynomial of the first kind.

        Notes
        -----
        The polynomials :math:`U_n` are orthogonal over :math:`[-1, 1]`
        with weight function :math:`(1 - x^2)^{1/2}`.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        Chebyshev polynomials of the second kind of order :math:`n` can
        be obtained as the determinant of specific :math:`n \times n`
        matrices. As an example we can check how the points obtained from
        the determinant of the following :math:`3 \times 3` matrix
        lay exactly on :math:`U_3`:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.linalg import det
        >>> from scipy.special import chebyu
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-2.0, 2.0)
        >>> ax.set_title(r'Chebyshev polynomial $U_3$')
        >>> ax.plot(x, chebyu(3)(x), label=rf'$U_3$')
        >>> for p in np.arange(-1.0, 1.0, 0.1):
        ...     ax.plot(p,
        ...             det(np.array([[2*p, 1, 0], [1, 2*p, 1], [0, 1, 2*p]])),
        ...             'rx')
        >>> plt.legend(loc='best')
        >>> plt.show()

        They satisfy the recurrence relation:

        .. math::
            U_{2n-1}(x) = 2 T_n(x)U_{n-1}(x)

        where the :math:`T_n` are the Chebyshev polynomial of the first kind.
        Let's verify it for :math:`n = 2`:

        >>> from scipy.special import chebyt
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> np.allclose(chebyu(3)(x), 2 * chebyt(2)(x) * chebyu(1)(x))
        True

        We can plot the Chebyshev polynomials :math:`U_n` for some values
        of :math:`n`:

        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-1.5, 1.5)
        >>> ax.set_title(r'Chebyshev polynomials $U_n$')
        >>> for n in np.arange(1,5):
        ...     ax.plot(x, chebyu(n)(x), label=rf'$U_n={n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    clpmn(m, n, z, type=3)
        Associated Legendre function of the first kind for complex arguments.

        Computes the associated Legendre function of the first kind of order m and
        degree n, ``Pmn(z)`` = :math:`P_n^m(z)`, and its derivative, ``Pmn'(z)``.
        Returns two arrays of size ``(m+1, n+1)`` containing ``Pmn(z)`` and
        ``Pmn'(z)`` for all orders from ``0..m`` and degrees from ``0..n``.

        Parameters
        ----------
        m : int
           ``|m| <= n``; the order of the Legendre function.
        n : int
           where ``n >= 0``; the degree of the Legendre function.  Often
           called ``l`` (lower case L) in descriptions of the associated
           Legendre function
        z : array_like, float or complex
            Input value.
        type : int, optional
           takes values 2 or 3
           2: cut on the real axis ``|x| > 1``
           3: cut on the real axis ``-1 < x < 1`` (default)

        Returns
        -------
        Pmn_z : (m+1, n+1) array
           Values for all orders ``0..m`` and degrees ``0..n``
        Pmn_d_z : (m+1, n+1) array
           Derivatives for all orders ``0..m`` and degrees ``0..n``

        See Also
        --------
        lpmn: associated Legendre functions of the first kind for real z

        Notes
        -----
        By default, i.e. for ``type=3``, phase conventions are chosen according
        to [1]_ such that the function is analytic. The cut lies on the interval
        (-1, 1). Approaching the cut from above or below in general yields a phase
        factor with respect to Ferrer's function of the first kind
        (cf. `lpmn`).

        For ``type=2`` a cut at ``|x| > 1`` is chosen. Approaching the real values
        on the interval (-1, 1) in the complex plane yields Ferrer's function
        of the first kind.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/14.21

    comb(N, k, *, exact=False, repetition=False)
        The number of combinations of N things taken k at a time.

        This is often expressed as "N choose k".

        Parameters
        ----------
        N : int, ndarray
            Number of things.
        k : int, ndarray
            Number of elements taken.
        exact : bool, optional
            For integers, if `exact` is False, then floating point precision is
            used, otherwise the result is computed exactly.

            .. deprecated:: 1.14.0
                ``exact=True`` is deprecated for non-integer `N` and `k` and will raise an
                error in SciPy 1.16.0
        repetition : bool, optional
            If `repetition` is True, then the number of combinations with
            repetition is computed.

        Returns
        -------
        val : int, float, ndarray
            The total number of combinations.

        See Also
        --------
        binom : Binomial coefficient considered as a function of two real
                variables.

        Notes
        -----
        - Array arguments accepted only for exact=False case.
        - If N < 0, or k < 0, then 0 is returned.
        - If k > N and repetition=False, then 0 is returned.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import comb
        >>> k = np.array([3, 4])
        >>> n = np.array([10, 10])
        >>> comb(n, k, exact=False)
        array([ 120.,  210.])
        >>> comb(10, 3, exact=True)
        120
        >>> comb(10, 3, exact=True, repetition=True)
        220

    diric(x, n)
        Periodic sinc function, also called the Dirichlet function.

        The Dirichlet function is defined as::

            diric(x, n) = sin(x * n/2) / (n * sin(x / 2)),

        where `n` is a positive integer.

        Parameters
        ----------
        x : array_like
            Input data
        n : int
            Integer defining the periodicity.

        Returns
        -------
        diric : ndarray

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(-8*np.pi, 8*np.pi, num=201)
        >>> plt.figure(figsize=(8, 8));
        >>> for idx, n in enumerate([2, 3, 4, 9]):
        ...     plt.subplot(2, 2, idx+1)
        ...     plt.plot(x, special.diric(x, n))
        ...     plt.title('diric, n={}'.format(n))
        >>> plt.show()

        The following example demonstrates that `diric` gives the magnitudes
        (modulo the sign and scaling) of the Fourier coefficients of a
        rectangular pulse.

        Suppress output of values that are effectively 0:

        >>> np.set_printoptions(suppress=True)

        Create a signal `x` of length `m` with `k` ones:

        >>> m = 8
        >>> k = 3
        >>> x = np.zeros(m)
        >>> x[:k] = 1

        Use the FFT to compute the Fourier transform of `x`, and
        inspect the magnitudes of the coefficients:

        >>> np.abs(np.fft.fft(x))
        array([ 3.        ,  2.41421356,  1.        ,  0.41421356,  1.        ,
                0.41421356,  1.        ,  2.41421356])

        Now find the same values (up to sign) using `diric`. We multiply
        by `k` to account for the different scaling conventions of
        `numpy.fft.fft` and `diric`:

        >>> theta = np.linspace(0, 2*np.pi, m, endpoint=False)
        >>> k * special.diric(theta, k)
        array([ 3.        ,  2.41421356,  1.        , -0.41421356, -1.        ,
               -0.41421356,  1.        ,  2.41421356])

    ellip_harm(h2, k2, n, p, s, signm=1, signn=1)
        Ellipsoidal harmonic functions E^p_n(l)

        These are also known as Lame functions of the first kind, and are
        solutions to the Lame equation:

        .. math:: (s^2 - h^2)(s^2 - k^2)E''(s)
                  + s(2s^2 - h^2 - k^2)E'(s) + (a - q s^2)E(s) = 0

        where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
        returned) corresponding to the solutions.

        Parameters
        ----------
        h2 : float
            ``h**2``
        k2 : float
            ``k**2``; should be larger than ``h**2``
        n : int
            Degree
        s : float
            Coordinate
        p : int
            Order, can range between [1,2n+1]
        signm : {1, -1}, optional
            Sign of prefactor of functions. Can be +/-1. See Notes.
        signn : {1, -1}, optional
            Sign of prefactor of functions. Can be +/-1. See Notes.

        Returns
        -------
        E : float
            the harmonic :math:`E^p_n(s)`

        See Also
        --------
        ellip_harm_2, ellip_normal

        Notes
        -----
        The geometric interpretation of the ellipsoidal functions is
        explained in [2]_, [3]_, [4]_. The `signm` and `signn` arguments control the
        sign of prefactors for functions according to their type::

            K : +1
            L : signm
            M : signn
            N : signm*signn

        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Digital Library of Mathematical Functions 29.12
           https://dlmf.nist.gov/29.12
        .. [2] Bardhan and Knepley, "Computational science and
           re-discovery: open-source implementations of
           ellipsoidal harmonics for problems in potential theory",
           Comput. Sci. Disc. 5, 014006 (2012)
           :doi:`10.1088/1749-4699/5/1/014006`.
        .. [3] David J.and Dechambre P, "Computation of Ellipsoidal
           Gravity Field Harmonics for small solar system bodies"
           pp. 30-36, 2000
        .. [4] George Dassios, "Ellipsoidal Harmonics: Theory and Applications"
           pp. 418, 2012

        Examples
        --------
        >>> from scipy.special import ellip_harm
        >>> w = ellip_harm(5,8,1,1,2.5)
        >>> w
        2.5

        Check that the functions indeed are solutions to the Lame equation:

        >>> import numpy as np
        >>> from scipy.interpolate import UnivariateSpline
        >>> def eigenvalue(f, df, ddf):
        ...     r = (((s**2 - h**2) * (s**2 - k**2) * ddf
        ...           + s * (2*s**2 - h**2 - k**2) * df
        ...           - n * (n + 1)*s**2*f) / f)
        ...     return -r.mean(), r.std()
        >>> s = np.linspace(0.1, 10, 200)
        >>> k, h, n, p = 8.0, 2.2, 3, 2
        >>> E = ellip_harm(h**2, k**2, n, p, s)
        >>> E_spl = UnivariateSpline(s, E)
        >>> a, a_err = eigenvalue(E_spl(s), E_spl(s,1), E_spl(s,2))
        >>> a, a_err
        (583.44366156701483, 6.4580890640310646e-11)

    ellip_harm_2(h2, k2, n, p, s)
        Ellipsoidal harmonic functions F^p_n(l)

        These are also known as Lame functions of the second kind, and are
        solutions to the Lame equation:

        .. math:: (s^2 - h^2)(s^2 - k^2)F''(s)
                  + s(2s^2 - h^2 - k^2)F'(s) + (a - q s^2)F(s) = 0

        where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
        returned) corresponding to the solutions.

        Parameters
        ----------
        h2 : float
            ``h**2``
        k2 : float
            ``k**2``; should be larger than ``h**2``
        n : int
            Degree.
        p : int
            Order, can range between [1,2n+1].
        s : float
            Coordinate

        Returns
        -------
        F : float
            The harmonic :math:`F^p_n(s)`

        See Also
        --------
        ellip_harm, ellip_normal

        Notes
        -----
        Lame functions of the second kind are related to the functions of the first kind:

        .. math::

           F^p_n(s)=(2n + 1)E^p_n(s)\int_{0}^{1/s}
           \frac{du}{(E^p_n(1/u))^2\sqrt{(1-u^2k^2)(1-u^2h^2)}}

        .. versionadded:: 0.15.0

        Examples
        --------
        >>> from scipy.special import ellip_harm_2
        >>> w = ellip_harm_2(5,8,2,1,10)
        >>> w
        0.00108056853382

    ellip_normal(h2, k2, n, p)
        Ellipsoidal harmonic normalization constants gamma^p_n

        The normalization constant is defined as

        .. math::

           \gamma^p_n=8\int_{0}^{h}dx\int_{h}^{k}dy
           \frac{(y^2-x^2)(E^p_n(y)E^p_n(x))^2}{\sqrt((k^2-y^2)(y^2-h^2)(h^2-x^2)(k^2-x^2)}

        Parameters
        ----------
        h2 : float
            ``h**2``
        k2 : float
            ``k**2``; should be larger than ``h**2``
        n : int
            Degree.
        p : int
            Order, can range between [1,2n+1].

        Returns
        -------
        gamma : float
            The normalization constant :math:`\gamma^p_n`

        See Also
        --------
        ellip_harm, ellip_harm_2

        Notes
        -----
        .. versionadded:: 0.15.0

        Examples
        --------
        >>> from scipy.special import ellip_normal
        >>> w = ellip_normal(5,8,3,7)
        >>> w
        1723.38796997

    erf_zeros(nt)
        Compute the first nt zero in the first quadrant, ordered by absolute value.

        Zeros in the other quadrants can be obtained by using the symmetries
        erf(-z) = erf(z) and erf(conj(z)) = conj(erf(z)).


        Parameters
        ----------
        nt : int
            The number of zeros to compute

        Returns
        -------
        The locations of the zeros of erf : ndarray (complex)
            Complex values at which zeros of erf(z)

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        >>> from scipy import special
        >>> special.erf_zeros(1)
        array([1.45061616+1.880943j])

        Check that erf is (close to) zero for the value returned by erf_zeros

        >>> special.erf(special.erf_zeros(1))
        array([4.95159469e-14-1.16407394e-16j])

    euler(n)
        Euler numbers E(0), E(1), ..., E(n).

        The Euler numbers [1]_ are also known as the secant numbers.

        Because ``euler(n)`` returns floating point values, it does not give
        exact values for large `n`.  The first inexact value is E(22).

        Parameters
        ----------
        n : int
            The highest index of the Euler number to be returned.

        Returns
        -------
        ndarray
            The Euler numbers [E(0), E(1), ..., E(n)].
            The odd Euler numbers, which are all zero, are included.

        References
        ----------
        .. [1] Sequence A122045, The On-Line Encyclopedia of Integer Sequences,
               https://oeis.org/A122045
        .. [2] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import euler
        >>> euler(6)
        array([  1.,   0.,  -1.,   0.,   5.,   0., -61.])

        >>> euler(13).astype(np.int64)
        array([      1,       0,      -1,       0,       5,       0,     -61,
                     0,    1385,       0,  -50521,       0, 2702765,       0])

        >>> euler(22)[-1]  # Exact value of E(22) is -69348874393137901.
        -69348874393137976.0

    factorial(n, exact=False)
        The factorial of a number or array of numbers.

        The factorial of non-negative integer `n` is the product of all
        positive integers less than or equal to `n`::

            n! = n * (n - 1) * (n - 2) * ... * 1

        Parameters
        ----------
        n : int or array_like of ints
            Input values.  If ``n < 0``, the return value is 0.
        exact : bool, optional
            If True, calculate the answer exactly using long integer arithmetic.
            If False, result is approximated in floating point rapidly using the
            `gamma` function.
            Default is False.

        Returns
        -------
        nf : float or int or ndarray
            Factorial of `n`, as integer or float depending on `exact`.

        Notes
        -----
        For arrays with ``exact=True``, the factorial is computed only once, for
        the largest input, with each other result computed in the process.
        The output dtype is increased to ``int64`` or ``object`` if necessary.

        With ``exact=False`` the factorial is approximated using the gamma
        function:

        .. math:: n! = \Gamma(n+1)

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import factorial
        >>> arr = np.array([3, 4, 5])
        >>> factorial(arr, exact=False)
        array([   6.,   24.,  120.])
        >>> factorial(arr, exact=True)
        array([  6,  24, 120])
        >>> factorial(5, exact=True)
        120

    factorial2(n, exact=False)
        Double factorial.

        This is the factorial with every second value skipped.  E.g., ``7!! = 7 * 5
        * 3 * 1``.  It can be approximated numerically as::

          n!! = 2 ** (n / 2) * gamma(n / 2 + 1) * sqrt(2 / pi)  n odd
              = 2 ** (n / 2) * gamma(n / 2 + 1)                 n even
              = 2 ** (n / 2) * (n / 2)!                         n even

        Parameters
        ----------
        n : int or array_like
            Calculate ``n!!``.  If ``n < 0``, the return value is 0.
        exact : bool, optional
            The result can be approximated rapidly using the gamma-formula
            above (default).  If `exact` is set to True, calculate the
            answer exactly using integer arithmetic.

        Returns
        -------
        nff : float or int
            Double factorial of `n`, as an int or a float depending on
            `exact`.

        Examples
        --------
        >>> from scipy.special import factorial2
        >>> factorial2(7, exact=False)
        array(105.00000000000001)
        >>> factorial2(7, exact=True)
        105

    factorialk(n, k, exact=None)
        Multifactorial of n of order k, n(!!...!).

        This is the multifactorial of n skipping k values.  For example,

          factorialk(17, 4) = 17!!!! = 17 * 13 * 9 * 5 * 1

        In particular, for any integer ``n``, we have

          factorialk(n, 1) = factorial(n)

          factorialk(n, 2) = factorial2(n)

        Parameters
        ----------
        n : int or array_like
            Calculate multifactorial. If ``n < 0``, the return value is 0.
        k : int
            Order of multifactorial.
        exact : bool, optional
            If exact is set to True, calculate the answer exactly using
            integer arithmetic, otherwise use an approximation (faster,
            but yields floats instead of integers)

            .. warning::
               The default value for ``exact`` will be changed to
               ``False`` in SciPy 1.15.0.

        Returns
        -------
        val : int
            Multifactorial of `n`.

        Examples
        --------
        >>> from scipy.special import factorialk
        >>> factorialk(5, k=1, exact=True)
        120
        >>> factorialk(5, k=3, exact=True)
        10
        >>> factorialk([5, 7, 9], k=3, exact=True)
        array([ 10,  28, 162])
        >>> factorialk([5, 7, 9], k=3, exact=False)
        array([ 10.,  28., 162.])

        Notes
        -----
        While less straight-forward than for the double-factorial, it's possible to
        calculate a general approximation formula of n!(k) by studying ``n`` for a given
        remainder ``r < k`` (thus ``n = m * k + r``, resp. ``r = n % k``), which can be
        put together into something valid for all integer values ``n >= 0`` & ``k > 0``::

          n!(k) = k ** ((n - r)/k) * gamma(n/k + 1) / gamma(r/k + 1) * max(r, 1)

        This is the basis of the approximation when ``exact=False``. Compare also [1].

        References
        ----------
        .. [1] Complex extension to multifactorial
                https://en.wikipedia.org/wiki/Double_factorial#Alternative_extension_of_the_multifactorial

    fresnel_zeros(nt)
        Compute nt complex zeros of sine and cosine Fresnel integrals S(z) and C(z).

        Parameters
        ----------
        nt : int
            Number of zeros to compute

        Returns
        -------
        zeros_sine: ndarray
            Zeros of the sine Fresnel integral
        zeros_cosine : ndarray
            Zeros of the cosine Fresnel integral

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    fresnelc_zeros(nt)
        Compute nt complex zeros of cosine Fresnel integral C(z).

        Parameters
        ----------
        nt : int
            Number of zeros to compute

        Returns
        -------
        fresnelc_zeros: ndarray
            Zeros of the cosine Fresnel integral

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    fresnels_zeros(nt)
        Compute nt complex zeros of sine Fresnel integral S(z).

        Parameters
        ----------
        nt : int
            Number of zeros to compute

        Returns
        -------
        fresnels_zeros: ndarray
            Zeros of the sine Fresnel integral

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    gegenbauer(n, alpha, monic=False)
        Gegenbauer (ultraspherical) polynomial.

        Defined to be the solution of

        .. math::
            (1 - x^2)\frac{d^2}{dx^2}C_n^{(\alpha)}
              - (2\alpha + 1)x\frac{d}{dx}C_n^{(\alpha)}
              + n(n + 2\alpha)C_n^{(\alpha)} = 0

        for :math:`\alpha > -1/2`; :math:`C_n^{(\alpha)}` is a polynomial
        of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        alpha : float
            Parameter, must be greater than -0.5.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        C : orthopoly1d
            Gegenbauer polynomial.

        Notes
        -----
        The polynomials :math:`C_n^{(\alpha)}` are orthogonal over
        :math:`[-1,1]` with weight function :math:`(1 - x^2)^{(\alpha -
        1/2)}`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt

        We can initialize a variable ``p`` as a Gegenbauer polynomial using the
        `gegenbauer` function and evaluate at a point ``x = 1``.

        >>> p = special.gegenbauer(3, 0.5, monic=False)
        >>> p
        poly1d([ 2.5,  0. , -1.5,  0. ])
        >>> p(1)
        1.0

        To evaluate ``p`` at various points ``x`` in the interval ``(-3, 3)``,
        simply pass an array ``x`` to ``p`` as follows:

        >>> x = np.linspace(-3, 3, 400)
        >>> y = p(x)

        We can then visualize ``x, y`` using `matplotlib.pyplot`.

        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, y)
        >>> ax.set_title("Gegenbauer (ultraspherical) polynomial of degree 3")
        >>> ax.set_xlabel("x")
        >>> ax.set_ylabel("G_3(x)")
        >>> plt.show()

    genlaguerre(n, alpha, monic=False)
        Generalized (associated) Laguerre polynomial.

        Defined to be the solution of

        .. math::
            x\frac{d^2}{dx^2}L_n^{(\alpha)}
              + (\alpha + 1 - x)\frac{d}{dx}L_n^{(\alpha)}
              + nL_n^{(\alpha)} = 0,

        where :math:`\alpha > -1`; :math:`L_n^{(\alpha)}` is a polynomial
        of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        alpha : float
            Parameter, must be greater than -1.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        L : orthopoly1d
            Generalized Laguerre polynomial.

        See Also
        --------
        laguerre : Laguerre polynomial.
        hyp1f1 : confluent hypergeometric function

        Notes
        -----
        For fixed :math:`\alpha`, the polynomials :math:`L_n^{(\alpha)}`
        are orthogonal over :math:`[0, \infty)` with weight function
        :math:`e^{-x}x^\alpha`.

        The Laguerre polynomials are the special case where :math:`\alpha
        = 0`.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The generalized Laguerre polynomials are closely related to the confluent
        hypergeometric function :math:`{}_1F_1`:

            .. math::
                L_n^{(\alpha)} = \binom{n + \alpha}{n} {}_1F_1(-n, \alpha +1, x)

        This can be verified, for example,  for :math:`n = \alpha = 3` over the
        interval :math:`[-1, 1]`:

        >>> import numpy as np
        >>> from scipy.special import binom
        >>> from scipy.special import genlaguerre
        >>> from scipy.special import hyp1f1
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> np.allclose(genlaguerre(3, 3)(x), binom(6, 3) * hyp1f1(-3, 4, x))
        True

        This is the plot of the generalized Laguerre polynomials
        :math:`L_3^{(\alpha)}` for some values of :math:`\alpha`:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(-4.0, 12.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-5.0, 10.0)
        >>> ax.set_title(r'Generalized Laguerre polynomials $L_3^{\alpha}$')
        >>> for alpha in np.arange(0, 5):
        ...     ax.plot(x, genlaguerre(3, alpha)(x), label=rf'$L_3^{(alpha)}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    geterr()
        Get the current way of handling special-function errors.

        Returns
        -------
        err : dict
            A dictionary with keys "singular", "underflow", "overflow",
            "slow", "loss", "no_result", "domain", "arg", and "other",
            whose values are from the strings "ignore", "warn", and
            "raise". The keys represent possible special-function errors,
            and the values define how these errors are handled.

        See Also
        --------
        seterr : set how special-function errors are handled
        errstate : context manager for special-function error handling
        numpy.geterr : similar numpy function for floating-point errors

        Notes
        -----
        For complete documentation of the types of special-function errors
        and treatment options, see `seterr`.

        Examples
        --------
        By default all errors are ignored.

        >>> import scipy.special as sc
        >>> for key, value in sorted(sc.geterr().items()):
        ...     print("{}: {}".format(key, value))
        ...
        arg: ignore
        domain: ignore
        loss: ignore
        no_result: ignore
        other: ignore
        overflow: ignore
        singular: ignore
        slow: ignore
        underflow: ignore

    h1vp(v, z, n=1)
        Compute derivatives of Hankel function H1v(z) with respect to `z`.

        Parameters
        ----------
        v : array_like
            Order of Hankel function
        z : array_like
            Argument at which to evaluate the derivative. Can be real or
            complex.
        n : int, default 1
            Order of derivative. For 0 returns the Hankel function `h1v` itself.

        Returns
        -------
        scalar or ndarray
            Values of the derivative of the Hankel function.

        See Also
        --------
        hankel1

        Notes
        -----
        The derivative is computed using the relation DLFM 10.6.7 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.6.E7

        Examples
        --------
        Compute the Hankel function of the first kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import h1vp
        >>> h1vp(0, 1, 0), h1vp(0, 1, 1), h1vp(0, 1, 2)
        ((0.7651976865579664+0.088256964215677j),
         (-0.44005058574493355+0.7812128213002889j),
         (-0.3251471008130329-0.8694697855159659j))

        Compute the first derivative of the Hankel function of the first kind
        for several orders at 1 by providing an array for `v`.

        >>> h1vp([0, 1, 2], 1, 1)
        array([-0.44005059+0.78121282j,  0.3251471 +0.86946979j,
               0.21024362+2.52015239j])

        Compute the first derivative of the Hankel function of the first kind
        of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> h1vp(0, points, 1)
        array([-0.24226846+1.47147239j, -0.55793651+0.41230863j,
               -0.33905896-0.32467442j])

    h2vp(v, z, n=1)
        Compute derivatives of Hankel function H2v(z) with respect to `z`.

        Parameters
        ----------
        v : array_like
            Order of Hankel function
        z : array_like
            Argument at which to evaluate the derivative. Can be real or
            complex.
        n : int, default 1
            Order of derivative. For 0 returns the Hankel function `h2v` itself.

        Returns
        -------
        scalar or ndarray
            Values of the derivative of the Hankel function.

        See Also
        --------
        hankel2

        Notes
        -----
        The derivative is computed using the relation DLFM 10.6.7 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.6.E7

        Examples
        --------
        Compute the Hankel function of the second kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import h2vp
        >>> h2vp(0, 1, 0), h2vp(0, 1, 1), h2vp(0, 1, 2)
        ((0.7651976865579664-0.088256964215677j),
         (-0.44005058574493355-0.7812128213002889j),
         (-0.3251471008130329+0.8694697855159659j))

        Compute the first derivative of the Hankel function of the second kind
        for several orders at 1 by providing an array for `v`.

        >>> h2vp([0, 1, 2], 1, 1)
        array([-0.44005059-0.78121282j,  0.3251471 -0.86946979j,
               0.21024362-2.52015239j])

        Compute the first derivative of the Hankel function of the second kind
        of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> h2vp(0, points, 1)
        array([-0.24226846-1.47147239j, -0.55793651-0.41230863j,
               -0.33905896+0.32467442j])

    h_roots = roots_hermite(n, mu=False)
        Gauss-Hermite (physicist's) quadrature.

        Compute the sample points and weights for Gauss-Hermite
        quadrature. The sample points are the roots of the nth degree
        Hermite polynomial, :math:`H_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-\infty, \infty]` with weight
        function :math:`w(x) = e^{-x^2}`. See 22.2.14 in [AS]_ for
        details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.hermite.hermgauss
        roots_hermitenorm

        Notes
        -----
        For small n up to 150 a modified version of the Golub-Welsch
        algorithm is used. Nodes are computed from the eigenvalue
        problem and improved by one step of a Newton iteration.
        The weights are computed from the well-known analytical formula.

        For n larger than 150 an optimal asymptotic algorithm is applied
        which computes nodes and weights in a numerically stable manner.
        The algorithm has linear runtime making computation for very
        large n (several thousand or more) feasible.

        References
        ----------
        .. [townsend.trogdon.olver-2014]
            Townsend, A. and Trogdon, T. and Olver, S. (2014)
            *Fast computation of Gauss quadrature nodes and
            weights on the whole real line*. :arXiv:`1410.5286`.
        .. [townsend.trogdon.olver-2015]
            Townsend, A. and Trogdon, T. and Olver, S. (2015)
            *Fast computation of Gauss quadrature nodes and
            weights on the whole real line*.
            IMA Journal of Numerical Analysis
            :doi:`10.1093/imanum/drv002`.
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    he_roots = roots_hermitenorm(n, mu=False)
        Gauss-Hermite (statistician's) quadrature.

        Compute the sample points and weights for Gauss-Hermite
        quadrature. The sample points are the roots of the nth degree
        Hermite polynomial, :math:`He_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-\infty, \infty]` with weight
        function :math:`w(x) = e^{-x^2/2}`. See 22.2.15 in [AS]_ for more
        details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.hermite_e.hermegauss

        Notes
        -----
        For small n up to 150 a modified version of the Golub-Welsch
        algorithm is used. Nodes are computed from the eigenvalue
        problem and improved by one step of a Newton iteration.
        The weights are computed from the well-known analytical formula.

        For n larger than 150 an optimal asymptotic algorithm is used
        which computes nodes and weights in a numerical stable manner.
        The algorithm has linear runtime making computation for very
        large n (several thousand or more) feasible.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    hermite(n, monic=False)
        Physicist's Hermite polynomial.

        Defined by

        .. math::

            H_n(x) = (-1)^ne^{x^2}\frac{d^n}{dx^n}e^{-x^2};

        :math:`H_n` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        H : orthopoly1d
            Hermite polynomial.

        Notes
        -----
        The polynomials :math:`H_n` are orthogonal over :math:`(-\infty,
        \infty)` with weight function :math:`e^{-x^2}`.

        Examples
        --------
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> import numpy as np

        >>> p_monic = special.hermite(3, monic=True)
        >>> p_monic
        poly1d([ 1. ,  0. , -1.5,  0. ])
        >>> p_monic(1)
        -0.49999999999999983
        >>> x = np.linspace(-3, 3, 400)
        >>> y = p_monic(x)
        >>> plt.plot(x, y)
        >>> plt.title("Monic Hermite polynomial of degree 3")
        >>> plt.xlabel("x")
        >>> plt.ylabel("H_3(x)")
        >>> plt.show()

    hermitenorm(n, monic=False)
        Normalized (probabilist's) Hermite polynomial.

        Defined by

        .. math::

            He_n(x) = (-1)^ne^{x^2/2}\frac{d^n}{dx^n}e^{-x^2/2};

        :math:`He_n` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        He : orthopoly1d
            Hermite polynomial.

        Notes
        -----

        The polynomials :math:`He_n` are orthogonal over :math:`(-\infty,
        \infty)` with weight function :math:`e^{-x^2/2}`.

    ivp(v, z, n=1)
        Compute derivatives of modified Bessel functions of the first kind.

        Compute the nth derivative of the modified Bessel function `Iv`
        with respect to `z`.

        Parameters
        ----------
        v : array_like or float
            Order of Bessel function
        z : array_like
            Argument at which to evaluate the derivative; can be real or
            complex.
        n : int, default 1
            Order of derivative. For 0, returns the Bessel function `iv` itself.

        Returns
        -------
        scalar or ndarray
            nth derivative of the modified Bessel function.

        See Also
        --------
        iv

        Notes
        -----
        The derivative is computed using the relation DLFM 10.29.5 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 6.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.29.E5

        Examples
        --------
        Compute the modified Bessel function of the first kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import ivp
        >>> ivp(0, 1, 0), ivp(0, 1, 1), ivp(0, 1, 2)
        (1.2660658777520084, 0.565159103992485, 0.7009067737595233)

        Compute the first derivative of the modified Bessel function of the first
        kind for several orders at 1 by providing an array for `v`.

        >>> ivp([0, 1, 2], 1, 1)
        array([0.5651591 , 0.70090677, 0.29366376])

        Compute the first derivative of the modified Bessel function of the
        first kind of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0., 1.5, 3.])
        >>> ivp(0, points, 1)
        array([0.        , 0.98166643, 3.95337022])

        Plot the modified Bessel function of the first kind of order 1 and its
        first three derivatives.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-5, 5, 1000)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, ivp(1, x, 0), label=r"$I_1$")
        >>> ax.plot(x, ivp(1, x, 1), label=r"$I_1'$")
        >>> ax.plot(x, ivp(1, x, 2), label=r"$I_1''$")
        >>> ax.plot(x, ivp(1, x, 3), label=r"$I_1'''$")
        >>> plt.legend()
        >>> plt.show()

    j_roots = roots_jacobi(n, alpha, beta, mu=False)
        Gauss-Jacobi quadrature.

        Compute the sample points and weights for Gauss-Jacobi
        quadrature. The sample points are the roots of the nth degree
        Jacobi polynomial, :math:`P^{\alpha, \beta}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
        weight function :math:`w(x) = (1 - x)^{\alpha} (1 +
        x)^{\beta}`. See 22.2.1 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -1
        beta : float
            beta must be > -1
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    jacobi(n, alpha, beta, monic=False)
        Jacobi polynomial.

        Defined to be the solution of

        .. math::
            (1 - x^2)\frac{d^2}{dx^2}P_n^{(\alpha, \beta)}
              + (\beta - \alpha - (\alpha + \beta + 2)x)
                \frac{d}{dx}P_n^{(\alpha, \beta)}
              + n(n + \alpha + \beta + 1)P_n^{(\alpha, \beta)} = 0

        for :math:`\alpha, \beta > -1`; :math:`P_n^{(\alpha, \beta)}` is a
        polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        alpha : float
            Parameter, must be greater than -1.
        beta : float
            Parameter, must be greater than -1.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        P : orthopoly1d
            Jacobi polynomial.

        Notes
        -----
        For fixed :math:`\alpha, \beta`, the polynomials
        :math:`P_n^{(\alpha, \beta)}` are orthogonal over :math:`[-1, 1]`
        with weight function :math:`(1 - x)^\alpha(1 + x)^\beta`.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The Jacobi polynomials satisfy the recurrence relation:

        .. math::
            P_n^{(\alpha, \beta-1)}(x) - P_n^{(\alpha-1, \beta)}(x)
              = P_{n-1}^{(\alpha, \beta)}(x)

        This can be verified, for example, for :math:`\alpha = \beta = 2`
        and :math:`n = 1` over the interval :math:`[-1, 1]`:

        >>> import numpy as np
        >>> from scipy.special import jacobi
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> np.allclose(jacobi(0, 2, 2)(x),
        ...             jacobi(1, 2, 1)(x) - jacobi(1, 1, 2)(x))
        True

        Plot of the Jacobi polynomial :math:`P_5^{(\alpha, -0.5)}` for
        different values of :math:`\alpha`:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-2.0, 2.0)
        >>> ax.set_title(r'Jacobi polynomials $P_5^{(\alpha, -0.5)}$')
        >>> for alpha in np.arange(0, 4, 1):
        ...     ax.plot(x, jacobi(5, alpha, -0.5)(x), label=rf'$\alpha={alpha}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    jn_zeros(n, nt)
        Compute zeros of integer-order Bessel functions Jn.

        Compute `nt` zeros of the Bessel functions :math:`J_n(x)` on the
        interval :math:`(0, \infty)`. The zeros are returned in ascending
        order. Note that this interval excludes the zero at :math:`x = 0`
        that exists for :math:`n > 0`.

        Parameters
        ----------
        n : int
            Order of Bessel function
        nt : int
            Number of zeros to return

        Returns
        -------
        ndarray
            First `nt` zeros of the Bessel function.

        See Also
        --------
        jv: Real-order Bessel functions of the first kind
        jnp_zeros: Zeros of :math:`Jn'`

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first four positive roots of :math:`J_3`.

        >>> from scipy.special import jn_zeros
        >>> jn_zeros(3, 4)
        array([ 6.3801619 ,  9.76102313, 13.01520072, 16.22346616])

        Plot :math:`J_3` and its first four positive roots. Note
        that the root located at 0 is not returned by `jn_zeros`.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import jn, jn_zeros
        >>> j3_roots = jn_zeros(3, 4)
        >>> xmax = 18
        >>> xmin = -1
        >>> x = np.linspace(xmin, xmax, 500)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, jn(3, x), label=r'$J_3$')
        >>> ax.scatter(j3_roots, np.zeros((4, )), s=30, c='r',
        ...            label=r"$J_3$_Zeros", zorder=5)
        >>> ax.scatter(0, 0, s=30, c='k',
        ...            label=r"Root at 0", zorder=5)
        >>> ax.hlines(0, 0, xmax, color='k')
        >>> ax.set_xlim(xmin, xmax)
        >>> plt.legend()
        >>> plt.show()

    jnjnp_zeros(nt)
        Compute zeros of integer-order Bessel functions Jn and Jn'.

        Results are arranged in order of the magnitudes of the zeros.

        Parameters
        ----------
        nt : int
            Number (<=1200) of zeros to compute

        Returns
        -------
        zo[l-1] : ndarray
            Value of the lth zero of Jn(x) and Jn'(x). Of length `nt`.
        n[l-1] : ndarray
            Order of the Jn(x) or Jn'(x) associated with lth zero. Of length `nt`.
        m[l-1] : ndarray
            Serial number of the zeros of Jn(x) or Jn'(x) associated
            with lth zero. Of length `nt`.
        t[l-1] : ndarray
            0 if lth zero in zo is zero of Jn(x), 1 if it is a zero of Jn'(x). Of
            length `nt`.

        See Also
        --------
        jn_zeros, jnp_zeros : to get separated arrays of zeros.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    jnp_zeros(n, nt)
        Compute zeros of integer-order Bessel function derivatives Jn'.

        Compute `nt` zeros of the functions :math:`J_n'(x)` on the
        interval :math:`(0, \infty)`. The zeros are returned in ascending
        order. Note that this interval excludes the zero at :math:`x = 0`
        that exists for :math:`n > 1`.

        Parameters
        ----------
        n : int
            Order of Bessel function
        nt : int
            Number of zeros to return

        Returns
        -------
        ndarray
            First `nt` zeros of the Bessel function.

        See Also
        --------
        jvp: Derivatives of integer-order Bessel functions of the first kind
        jv: Float-order Bessel functions of the first kind

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first four roots of :math:`J_2'`.

        >>> from scipy.special import jnp_zeros
        >>> jnp_zeros(2, 4)
        array([ 3.05423693,  6.70613319,  9.96946782, 13.17037086])

        As `jnp_zeros` yields the roots of :math:`J_n'`, it can be used to
        compute the locations of the peaks of :math:`J_n`. Plot
        :math:`J_2`, :math:`J_2'` and the locations of the roots of :math:`J_2'`.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import jn, jnp_zeros, jvp
        >>> j2_roots = jnp_zeros(2, 4)
        >>> xmax = 15
        >>> x = np.linspace(0, xmax, 500)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, jn(2, x), label=r'$J_2$')
        >>> ax.plot(x, jvp(2, x, 1), label=r"$J_2'$")
        >>> ax.hlines(0, 0, xmax, color='k')
        >>> ax.scatter(j2_roots, np.zeros((4, )), s=30, c='r',
        ...            label=r"Roots of $J_2'$", zorder=5)
        >>> ax.set_ylim(-0.4, 0.8)
        >>> ax.set_xlim(0, xmax)
        >>> plt.legend()
        >>> plt.show()

    jnyn_zeros(n, nt)
        Compute nt zeros of Bessel functions Jn(x), Jn'(x), Yn(x), and Yn'(x).

        Returns 4 arrays of length `nt`, corresponding to the first `nt`
        zeros of Jn(x), Jn'(x), Yn(x), and Yn'(x), respectively. The zeros
        are returned in ascending order.

        Parameters
        ----------
        n : int
            Order of the Bessel functions
        nt : int
            Number (<=1200) of zeros to compute

        Returns
        -------
        Jn : ndarray
            First `nt` zeros of Jn
        Jnp : ndarray
            First `nt` zeros of Jn'
        Yn : ndarray
            First `nt` zeros of Yn
        Ynp : ndarray
            First `nt` zeros of Yn'

        See Also
        --------
        jn_zeros, jnp_zeros, yn_zeros, ynp_zeros

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first three roots of :math:`J_1`, :math:`J_1'`,
        :math:`Y_1` and :math:`Y_1'`.

        >>> from scipy.special import jnyn_zeros
        >>> jn_roots, jnp_roots, yn_roots, ynp_roots = jnyn_zeros(1, 3)
        >>> jn_roots, yn_roots
        (array([ 3.83170597,  7.01558667, 10.17346814]),
         array([2.19714133, 5.42968104, 8.59600587]))

        Plot :math:`J_1`, :math:`J_1'`, :math:`Y_1`, :math:`Y_1'` and their roots.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import jnyn_zeros, jvp, jn, yvp, yn
        >>> jn_roots, jnp_roots, yn_roots, ynp_roots = jnyn_zeros(1, 3)
        >>> fig, ax = plt.subplots()
        >>> xmax= 11
        >>> x = np.linspace(0, xmax)
        >>> x[0] += 1e-15
        >>> ax.plot(x, jn(1, x), label=r"$J_1$", c='r')
        >>> ax.plot(x, jvp(1, x, 1), label=r"$J_1'$", c='b')
        >>> ax.plot(x, yn(1, x), label=r"$Y_1$", c='y')
        >>> ax.plot(x, yvp(1, x, 1), label=r"$Y_1'$", c='c')
        >>> zeros = np.zeros((3, ))
        >>> ax.scatter(jn_roots, zeros, s=30, c='r', zorder=5,
        ...            label=r"$J_1$ roots")
        >>> ax.scatter(jnp_roots, zeros, s=30, c='b', zorder=5,
        ...            label=r"$J_1'$ roots")
        >>> ax.scatter(yn_roots, zeros, s=30, c='y', zorder=5,
        ...            label=r"$Y_1$ roots")
        >>> ax.scatter(ynp_roots, zeros, s=30, c='c', zorder=5,
        ...            label=r"$Y_1'$ roots")
        >>> ax.hlines(0, 0, xmax, color='k')
        >>> ax.set_ylim(-0.6, 0.6)
        >>> ax.set_xlim(0, xmax)
        >>> ax.legend(ncol=2, bbox_to_anchor=(1., 0.75))
        >>> plt.tight_layout()
        >>> plt.show()

    js_roots = roots_sh_jacobi(n, p1, q1, mu=False)
        Gauss-Jacobi (shifted) quadrature.

        Compute the sample points and weights for Gauss-Jacobi (shifted)
        quadrature. The sample points are the roots of the nth degree
        shifted Jacobi polynomial, :math:`G^{p,q}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[0, 1]` with
        weight function :math:`w(x) = (1 - x)^{p-q} x^{q-1}`. See 22.2.2
        in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        p1 : float
            (p1 - q1) must be > -1
        q1 : float
            q1 must be > 0
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    jvp(v, z, n=1)
        Compute derivatives of Bessel functions of the first kind.

        Compute the nth derivative of the Bessel function `Jv` with
        respect to `z`.

        Parameters
        ----------
        v : array_like or float
            Order of Bessel function
        z : complex
            Argument at which to evaluate the derivative; can be real or
            complex.
        n : int, default 1
            Order of derivative. For 0 returns the Bessel function `jv` itself.

        Returns
        -------
        scalar or ndarray
            Values of the derivative of the Bessel function.

        Notes
        -----
        The derivative is computed using the relation DLFM 10.6.7 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.6.E7

        Examples
        --------

        Compute the Bessel function of the first kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import jvp
        >>> jvp(0, 1, 0), jvp(0, 1, 1), jvp(0, 1, 2)
        (0.7651976865579666, -0.44005058574493355, -0.3251471008130331)

        Compute the first derivative of the Bessel function of the first
        kind for several orders at 1 by providing an array for `v`.

        >>> jvp([0, 1, 2], 1, 1)
        array([-0.44005059,  0.3251471 ,  0.21024362])

        Compute the first derivative of the Bessel function of the first
        kind of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0., 1.5, 3.])
        >>> jvp(0, points, 1)
        array([-0.        , -0.55793651, -0.33905896])

        Plot the Bessel function of the first kind of order 1 and its
        first three derivatives.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-10, 10, 1000)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, jvp(1, x, 0), label=r"$J_1$")
        >>> ax.plot(x, jvp(1, x, 1), label=r"$J_1'$")
        >>> ax.plot(x, jvp(1, x, 2), label=r"$J_1''$")
        >>> ax.plot(x, jvp(1, x, 3), label=r"$J_1'''$")
        >>> plt.legend()
        >>> plt.show()

    kei_zeros(nt)
        Compute nt zeros of the Kelvin function kei.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the Kelvin function.

        See Also
        --------
        kei

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    keip_zeros(nt)
        Compute nt zeros of the derivative of the Kelvin function kei.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the derivative of the Kelvin function.

        See Also
        --------
        kei, keip

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    kelvin_zeros(nt)
        Compute nt zeros of all Kelvin functions.

        Returned in a length-8 tuple of arrays of length nt.  The tuple contains
        the arrays of zeros of (ber, bei, ker, kei, ber', bei', ker', kei').

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    ker_zeros(nt)
        Compute nt zeros of the Kelvin function ker.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the Kelvin function.

        See Also
        --------
        ker

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    kerp_zeros(nt)
        Compute nt zeros of the derivative of the Kelvin function ker.

        Parameters
        ----------
        nt : int
            Number of zeros to compute. Must be positive.

        Returns
        -------
        ndarray
            First `nt` zeros of the derivative of the Kelvin function.

        See Also
        --------
        ker, kerp

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    kvp(v, z, n=1)
        Compute derivatives of real-order modified Bessel function Kv(z)

        Kv(z) is the modified Bessel function of the second kind.
        Derivative is calculated with respect to `z`.

        Parameters
        ----------
        v : array_like of float
            Order of Bessel function
        z : array_like of complex
            Argument at which to evaluate the derivative
        n : int, default 1
            Order of derivative. For 0 returns the Bessel function `kv` itself.

        Returns
        -------
        out : ndarray
            The results

        See Also
        --------
        kv

        Notes
        -----
        The derivative is computed using the relation DLFM 10.29.5 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 6.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.29.E5

        Examples
        --------
        Compute the modified bessel function of the second kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import kvp
        >>> kvp(0, 1, 0), kvp(0, 1, 1), kvp(0, 1, 2)
        (0.42102443824070834, -0.6019072301972346, 1.0229316684379428)

        Compute the first derivative of the modified Bessel function of the second
        kind for several orders at 1 by providing an array for `v`.

        >>> kvp([0, 1, 2], 1, 1)
        array([-0.60190723, -1.02293167, -3.85158503])

        Compute the first derivative of the modified Bessel function of the
        second kind of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> kvp(0, points, 1)
        array([-1.65644112, -0.2773878 , -0.04015643])

        Plot the modified bessel function of the second kind and its
        first three derivatives.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0, 5, 1000)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, kvp(1, x, 0), label=r"$K_1$")
        >>> ax.plot(x, kvp(1, x, 1), label=r"$K_1'$")
        >>> ax.plot(x, kvp(1, x, 2), label=r"$K_1''$")
        >>> ax.plot(x, kvp(1, x, 3), label=r"$K_1'''$")
        >>> ax.set_ylim(-2.5, 2.5)
        >>> plt.legend()
        >>> plt.show()

    l_roots = roots_laguerre(n, mu=False)
        Gauss-Laguerre quadrature.

        Compute the sample points and weights for Gauss-Laguerre
        quadrature. The sample points are the roots of the nth degree
        Laguerre polynomial, :math:`L_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[0, \infty]` with weight function
        :math:`w(x) = e^{-x}`. See 22.2.13 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.laguerre.laggauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    la_roots = roots_genlaguerre(n, alpha, mu=False)
        Gauss-generalized Laguerre quadrature.

        Compute the sample points and weights for Gauss-generalized
        Laguerre quadrature. The sample points are the roots of the nth
        degree generalized Laguerre polynomial, :math:`L^{\alpha}_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0,
        \infty]` with weight function :math:`w(x) = x^{\alpha}
        e^{-x}`. See 22.3.9 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -1
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    laguerre(n, monic=False)
        Laguerre polynomial.

        Defined to be the solution of

        .. math::
            x\frac{d^2}{dx^2}L_n + (1 - x)\frac{d}{dx}L_n + nL_n = 0;

        :math:`L_n` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        L : orthopoly1d
            Laguerre Polynomial.

        See Also
        --------
        genlaguerre : Generalized (associated) Laguerre polynomial.

        Notes
        -----
        The polynomials :math:`L_n` are orthogonal over :math:`[0,
        \infty)` with weight function :math:`e^{-x}`.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The Laguerre polynomials :math:`L_n` are the special case
        :math:`\alpha = 0` of the generalized Laguerre polynomials
        :math:`L_n^{(\alpha)}`.
        Let's verify it on the interval :math:`[-1, 1]`:

        >>> import numpy as np
        >>> from scipy.special import genlaguerre
        >>> from scipy.special import laguerre
        >>> x = np.arange(-1.0, 1.0, 0.01)
        >>> np.allclose(genlaguerre(3, 0)(x), laguerre(3)(x))
        True

        The polynomials :math:`L_n` also satisfy the recurrence relation:

        .. math::
            (n + 1)L_{n+1}(x) = (2n +1 -x)L_n(x) - nL_{n-1}(x)

        This can be easily checked on :math:`[0, 1]` for :math:`n = 3`:

        >>> x = np.arange(0.0, 1.0, 0.01)
        >>> np.allclose(4 * laguerre(4)(x),
        ...             (7 - x) * laguerre(3)(x) - 3 * laguerre(2)(x))
        True

        This is the plot of the first few Laguerre polynomials :math:`L_n`:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(-1.0, 5.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-5.0, 5.0)
        >>> ax.set_title(r'Laguerre polynomials $L_n$')
        >>> for n in np.arange(0, 5):
        ...     ax.plot(x, laguerre(n)(x), label=rf'$L_{n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    lambertw(z, k=0, tol=1e-08)
        lambertw(z, k=0, tol=1e-8)

        Lambert W function.

        The Lambert W function `W(z)` is defined as the inverse function
        of ``w * exp(w)``. In other words, the value of ``W(z)`` is
        such that ``z = W(z) * exp(W(z))`` for any complex number
        ``z``.

        The Lambert W function is a multivalued function with infinitely
        many branches. Each branch gives a separate solution of the
        equation ``z = w exp(w)``. Here, the branches are indexed by the
        integer `k`.

        Parameters
        ----------
        z : array_like
            Input argument.
        k : int, optional
            Branch index.
        tol : float, optional
            Evaluation tolerance.

        Returns
        -------
        w : array
            `w` will have the same shape as `z`.

        See Also
        --------
        wrightomega : the Wright Omega function

        Notes
        -----
        All branches are supported by `lambertw`:

        * ``lambertw(z)`` gives the principal solution (branch 0)
        * ``lambertw(z, k)`` gives the solution on branch `k`

        The Lambert W function has two partially real branches: the
        principal branch (`k = 0`) is real for real ``z > -1/e``, and the
        ``k = -1`` branch is real for ``-1/e < z < 0``. All branches except
        ``k = 0`` have a logarithmic singularity at ``z = 0``.

        **Possible issues**

        The evaluation can become inaccurate very close to the branch point
        at ``-1/e``. In some corner cases, `lambertw` might currently
        fail to converge, or can end up on the wrong branch.

        **Algorithm**

        Halley's iteration is used to invert ``w * exp(w)``, using a first-order
        asymptotic approximation (O(log(w)) or `O(w)`) as the initial estimate.

        The definition, implementation and choice of branches is based on [2]_.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Lambert_W_function
        .. [2] Corless et al, "On the Lambert W function", Adv. Comp. Math. 5
           (1996) 329-359.
           https://cs.uwaterloo.ca/research/tr/1993/03/W.pdf

        Examples
        --------
        The Lambert W function is the inverse of ``w exp(w)``:

        >>> import numpy as np
        >>> from scipy.special import lambertw
        >>> w = lambertw(1)
        >>> w
        (0.56714329040978384+0j)
        >>> w * np.exp(w)
        (1.0+0j)

        Any branch gives a valid inverse:

        >>> w = lambertw(1, k=3)
        >>> w
        (-2.8535817554090377+17.113535539412148j)
        >>> w*np.exp(w)
        (1.0000000000000002+1.609823385706477e-15j)

        **Applications to equation-solving**

        The Lambert W function may be used to solve various kinds of
        equations.  We give two examples here.

        First, the function can be used to solve implicit equations of the
        form

            :math:`x = a + b e^{c x}`

        for :math:`x`.  We assume :math:`c` is not zero.  After a little
        algebra, the equation may be written

            :math:`z e^z = -b c e^{a c}`

        where :math:`z = c (a - x)`.  :math:`z` may then be expressed using
        the Lambert W function

            :math:`z = W(-b c e^{a c})`

        giving

            :math:`x = a - W(-b c e^{a c})/c`

        For example,

        >>> a = 3
        >>> b = 2
        >>> c = -0.5

        The solution to :math:`x = a + b e^{c x}` is:

        >>> x = a - lambertw(-b*c*np.exp(a*c))/c
        >>> x
        (3.3707498368978794+0j)

        Verify that it solves the equation:

        >>> a + b*np.exp(c*x)
        (3.37074983689788+0j)

        The Lambert W function may also be used find the value of the infinite
        power tower :math:`z^{z^{z^{\ldots}}}`:

        >>> def tower(z, n):
        ...     if n == 0:
        ...         return z
        ...     return z ** tower(z, n-1)
        ...
        >>> tower(0.5, 100)
        0.641185744504986
        >>> -lambertw(-np.log(0.5)) / np.log(0.5)
        (0.64118574450498589+0j)

    legendre(n, monic=False)
        Legendre polynomial.

        Defined to be the solution of

        .. math::
            \frac{d}{dx}\left[(1 - x^2)\frac{d}{dx}P_n(x)\right]
              + n(n + 1)P_n(x) = 0;

        :math:`P_n(x)` is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        P : orthopoly1d
            Legendre polynomial.

        Notes
        -----
        The polynomials :math:`P_n` are orthogonal over :math:`[-1, 1]`
        with weight function 1.

        Examples
        --------
        Generate the 3rd-order Legendre polynomial 1/2*(5x^3 + 0x^2 - 3x + 0):

        >>> from scipy.special import legendre
        >>> legendre(3)
        poly1d([ 2.5,  0. , -1.5,  0. ])

    lmbda(v, x)
        Jahnke-Emden Lambda function, Lambdav(x).

        This function is defined as [2]_,

        .. math:: \Lambda_v(x) = \Gamma(v+1) \frac{J_v(x)}{(x/2)^v},

        where :math:`\Gamma` is the gamma function and :math:`J_v` is the
        Bessel function of the first kind.

        Parameters
        ----------
        v : float
            Order of the Lambda function
        x : float
            Value at which to evaluate the function and derivatives

        Returns
        -------
        vl : ndarray
            Values of Lambda_vi(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.
        dl : ndarray
            Derivatives Lambda_vi'(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] Jahnke, E. and Emde, F. "Tables of Functions with Formulae and
               Curves" (4th ed.), Dover, 1945

    log_softmax(x, axis=None)
        Compute the logarithm of the softmax function.

        In principle::

            log_softmax(x) = log(softmax(x))

        but using a more accurate implementation.

        Parameters
        ----------
        x : array_like
            Input array.
        axis : int or tuple of ints, optional
            Axis to compute values along. Default is None and softmax will be
            computed over the entire array `x`.

        Returns
        -------
        s : ndarray or scalar
            An array with the same shape as `x`. Exponential of the result will
            sum to 1 along the specified axis. If `x` is a scalar, a scalar is
            returned.

        Notes
        -----
        `log_softmax` is more accurate than ``np.log(softmax(x))`` with inputs that
        make `softmax` saturate (see examples below).

        .. versionadded:: 1.5.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import log_softmax
        >>> from scipy.special import softmax
        >>> np.set_printoptions(precision=5)

        >>> x = np.array([1000.0, 1.0])

        >>> y = log_softmax(x)
        >>> y
        array([   0., -999.])

        >>> with np.errstate(divide='ignore'):
        ...   y = np.log(softmax(x))
        ...
        >>> y
        array([  0., -inf])

    logsumexp(a, axis=None, b=None, keepdims=False, return_sign=False)
        Compute the log of the sum of exponentials of input elements.

        Parameters
        ----------
        a : array_like
            Input array.
        axis : None or int or tuple of ints, optional
            Axis or axes over which the sum is taken. By default `axis` is None,
            and all elements are summed.

            .. versionadded:: 0.11.0
        b : array-like, optional
            Scaling factor for exp(`a`) must be of the same shape as `a` or
            broadcastable to `a`. These values may be negative in order to
            implement subtraction.

            .. versionadded:: 0.12.0
        keepdims : bool, optional
            If this is set to True, the axes which are reduced are left in the
            result as dimensions with size one. With this option, the result
            will broadcast correctly against the original array.

            .. versionadded:: 0.15.0
        return_sign : bool, optional
            If this is set to True, the result will be a pair containing sign
            information; if False, results that are negative will be returned
            as NaN. Default is False (no sign information).

            .. versionadded:: 0.16.0

        Returns
        -------
        res : ndarray
            The result, ``np.log(np.sum(np.exp(a)))`` calculated in a numerically
            more stable way. If `b` is given then ``np.log(np.sum(b*np.exp(a)))``
            is returned. If ``return_sign`` is True, ``res`` contains the log of
            the absolute value of the argument.
        sgn : ndarray
            If ``return_sign`` is True, this will be an array of floating-point
            numbers matching res containing +1, 0, -1 (for real-valued inputs)
            or a complex phase (for complex inputs). This gives the sign of the
            argument of the logarithm in ``res``.
            If ``return_sign`` is False, only one result is returned.

        See Also
        --------
        numpy.logaddexp, numpy.logaddexp2

        Notes
        -----
        NumPy has a logaddexp function which is very similar to `logsumexp`, but
        only handles two arguments. `logaddexp.reduce` is similar to this
        function, but may be less stable.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import logsumexp
        >>> a = np.arange(10)
        >>> logsumexp(a)
        9.4586297444267107
        >>> np.log(np.sum(np.exp(a)))
        9.4586297444267107

        With weights

        >>> a = np.arange(10)
        >>> b = np.arange(10, 0, -1)
        >>> logsumexp(a, b=b)
        9.9170178533034665
        >>> np.log(np.sum(b*np.exp(a)))
        9.9170178533034647

        Returning a sign flag

        >>> logsumexp([1,2],b=[1,-1],return_sign=True)
        (1.5413248546129181, -1.0)

        Notice that `logsumexp` does not directly support masked arrays. To use it
        on a masked array, convert the mask into zero weights:

        >>> a = np.ma.array([np.log(2), 2, np.log(3)],
        ...                  mask=[False, True, False])
        >>> b = (~a.mask).astype(int)
        >>> logsumexp(a.data, b=b), np.log(5)
        1.6094379124341005, 1.6094379124341005

    lpmn(m, n, z)
        Sequence of associated Legendre functions of the first kind.

        Computes the associated Legendre function of the first kind of order m and
        degree n, ``Pmn(z)`` = :math:`P_n^m(z)`, and its derivative, ``Pmn'(z)``.
        Returns two arrays of size ``(m+1, n+1)`` containing ``Pmn(z)`` and
        ``Pmn'(z)`` for all orders from ``0..m`` and degrees from ``0..n``.

        This function takes a real argument ``z``. For complex arguments ``z``
        use clpmn instead.

        Parameters
        ----------
        m : int
           ``|m| <= n``; the order of the Legendre function.
        n : int
           where ``n >= 0``; the degree of the Legendre function.  Often
           called ``l`` (lower case L) in descriptions of the associated
           Legendre function
        z : array_like
            Input value.

        Returns
        -------
        Pmn_z : (m+1, n+1) array
           Values for all orders 0..m and degrees 0..n
        Pmn_d_z : (m+1, n+1) array
           Derivatives for all orders 0..m and degrees 0..n

        See Also
        --------
        clpmn: associated Legendre functions of the first kind for complex z

        Notes
        -----
        In the interval (-1, 1), Ferrer's function of the first kind is
        returned. The phase convention used for the intervals (1, inf)
        and (-inf, -1) is such that the result is always real.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/14.3

    lpn(n, z)
        Legendre function of the first kind.

        Compute sequence of Legendre functions of the first kind (polynomials),
        Pn(z) and derivatives for all degrees from 0 to n (inclusive).

        See also special.legendre for polynomial class.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    lqmn(m, n, z)
        Sequence of associated Legendre functions of the second kind.

        Computes the associated Legendre function of the second kind of order m and
        degree n, ``Qmn(z)`` = :math:`Q_n^m(z)`, and its derivative, ``Qmn'(z)``.
        Returns two arrays of size ``(m+1, n+1)`` containing ``Qmn(z)`` and
        ``Qmn'(z)`` for all orders from ``0..m`` and degrees from ``0..n``.

        Parameters
        ----------
        m : int
           ``|m| <= n``; the order of the Legendre function.
        n : int
           where ``n >= 0``; the degree of the Legendre function.  Often
           called ``l`` (lower case L) in descriptions of the associated
           Legendre function
        z : array_like, complex
            Input value.

        Returns
        -------
        Qmn_z : (m+1, n+1) array
           Values for all orders 0..m and degrees 0..n
        Qmn_d_z : (m+1, n+1) array
           Derivatives for all orders 0..m and degrees 0..n

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    lqn(n, z)
        Legendre function of the second kind.

        Compute sequence of Legendre functions of the second kind, Qn(z) and
        derivatives for all degrees from 0 to n (inclusive).

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    mathieu_even_coef(m, q)
        Fourier coefficients for even Mathieu and modified Mathieu functions.

        The Fourier series of the even solutions of the Mathieu differential
        equation are of the form

        .. math:: \mathrm{ce}_{2n}(z, q) = \sum_{k=0}^{\infty} A_{(2n)}^{(2k)} \cos 2kz

        .. math:: \mathrm{ce}_{2n+1}(z, q) =
                  \sum_{k=0}^{\infty} A_{(2n+1)}^{(2k+1)} \cos (2k+1)z

        This function returns the coefficients :math:`A_{(2n)}^{(2k)}` for even
        input m=2n, and the coefficients :math:`A_{(2n+1)}^{(2k+1)}` for odd input
        m=2n+1.

        Parameters
        ----------
        m : int
            Order of Mathieu functions.  Must be non-negative.
        q : float (>=0)
            Parameter of Mathieu functions.  Must be non-negative.

        Returns
        -------
        Ak : ndarray
            Even or odd Fourier coefficients, corresponding to even or odd m.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/28.4#i

    mathieu_odd_coef(m, q)
        Fourier coefficients for even Mathieu and modified Mathieu functions.

        The Fourier series of the odd solutions of the Mathieu differential
        equation are of the form

        .. math:: \mathrm{se}_{2n+1}(z, q) =
                  \sum_{k=0}^{\infty} B_{(2n+1)}^{(2k+1)} \sin (2k+1)z

        .. math:: \mathrm{se}_{2n+2}(z, q) =
                  \sum_{k=0}^{\infty} B_{(2n+2)}^{(2k+2)} \sin (2k+2)z

        This function returns the coefficients :math:`B_{(2n+2)}^{(2k+2)}` for even
        input m=2n+2, and the coefficients :math:`B_{(2n+1)}^{(2k+1)}` for odd
        input m=2n+1.

        Parameters
        ----------
        m : int
            Order of Mathieu functions.  Must be non-negative.
        q : float (>=0)
            Parameter of Mathieu functions.  Must be non-negative.

        Returns
        -------
        Bk : ndarray
            Even or odd Fourier coefficients, corresponding to even or odd m.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    multigammaln(a, d)
        Returns the log of multivariate gamma, also sometimes called the
        generalized gamma.

        Parameters
        ----------
        a : ndarray
            The multivariate gamma is computed for each item of `a`.
        d : int
            The dimension of the space of integration.

        Returns
        -------
        res : ndarray
            The values of the log multivariate gamma at the given points `a`.

        Notes
        -----
        The formal definition of the multivariate gamma of dimension d for a real
        `a` is

        .. math::

            \Gamma_d(a) = \int_{A>0} e^{-tr(A)} |A|^{a - (d+1)/2} dA

        with the condition :math:`a > (d-1)/2`, and :math:`A > 0` being the set of
        all the positive definite matrices of dimension `d`.  Note that `a` is a
        scalar: the integrand only is multivariate, the argument is not (the
        function is defined over a subset of the real set).

        This can be proven to be equal to the much friendlier equation

        .. math::

            \Gamma_d(a) = \pi^{d(d-1)/4} \prod_{i=1}^{d} \Gamma(a - (i-1)/2).

        References
        ----------
        R. J. Muirhead, Aspects of multivariate statistical theory (Wiley Series in
        probability and mathematical statistics).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import multigammaln, gammaln
        >>> a = 23.5
        >>> d = 10
        >>> multigammaln(a, d)
        454.1488605074416

        Verify that the result agrees with the logarithm of the equation
        shown above:

        >>> d*(d-1)/4*np.log(np.pi) + gammaln(a - 0.5*np.arange(0, d)).sum()
        454.1488605074416

    obl_cv_seq(m, n, c)
        Characteristic values for oblate spheroidal wave functions.

        Compute a sequence of characteristic values for the oblate
        spheroidal wave functions for mode m and n'=m..n and spheroidal
        parameter c.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    p_roots = roots_legendre(n, mu=False)
        Gauss-Legendre quadrature.

        Compute the sample points and weights for Gauss-Legendre
        quadrature [GL]_. The sample points are the roots of the nth degree
        Legendre polynomial :math:`P_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-1, 1]` with weight function
        :math:`w(x) = 1`. See 2.2.10 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.legendre.leggauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [GL] Gauss-Legendre quadrature, Wikipedia,
            https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import roots_legendre, eval_legendre
        >>> roots, weights = roots_legendre(9)

        ``roots`` holds the roots, and ``weights`` holds the weights for
        Gauss-Legendre quadrature.

        >>> roots
        array([-0.96816024, -0.83603111, -0.61337143, -0.32425342,  0.        ,
                0.32425342,  0.61337143,  0.83603111,  0.96816024])
        >>> weights
        array([0.08127439, 0.18064816, 0.2606107 , 0.31234708, 0.33023936,
               0.31234708, 0.2606107 , 0.18064816, 0.08127439])

        Verify that we have the roots by evaluating the degree 9 Legendre
        polynomial at ``roots``.  All the values are approximately zero:

        >>> eval_legendre(9, roots)
        array([-8.88178420e-16, -2.22044605e-16,  1.11022302e-16,  1.11022302e-16,
                0.00000000e+00, -5.55111512e-17, -1.94289029e-16,  1.38777878e-16,
               -8.32667268e-17])

        Here we'll show how the above values can be used to estimate the
        integral from 1 to 2 of f(t) = t + 1/t with Gauss-Legendre
        quadrature [GL]_.  First define the function and the integration
        limits.

        >>> def f(t):
        ...    return t + 1/t
        ...
        >>> a = 1
        >>> b = 2

        We'll use ``integral(f(t), t=a, t=b)`` to denote the definite integral
        of f from t=a to t=b.  The sample points in ``roots`` are from the
        interval [-1, 1], so we'll rewrite the integral with the simple change
        of variable::

            x = 2/(b - a) * t - (a + b)/(b - a)

        with inverse::

            t = (b - a)/2 * x + (a + 2)/2

        Then::

            integral(f(t), a, b) =
                (b - a)/2 * integral(f((b-a)/2*x + (a+b)/2), x=-1, x=1)

        We can approximate the latter integral with the values returned
        by `roots_legendre`.

        Map the roots computed above from [-1, 1] to [a, b].

        >>> t = (b - a)/2 * roots + (a + b)/2

        Approximate the integral as the weighted sum of the function values.

        >>> (b - a)/2 * f(t).dot(weights)
        2.1931471805599276

        Compare that to the exact result, which is 3/2 + log(2):

        >>> 1.5 + np.log(2)
        2.1931471805599454

    pbdn_seq(n, z)
        Parabolic cylinder functions Dn(z) and derivatives.

        Parameters
        ----------
        n : int
            Order of the parabolic cylinder function
        z : complex
            Value at which to evaluate the function and derivatives

        Returns
        -------
        dv : ndarray
            Values of D_i(z), for i=0, ..., i=n.
        dp : ndarray
            Derivatives D_i'(z), for i=0, ..., i=n.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 13.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    pbdv_seq(v, x)
        Parabolic cylinder functions Dv(x) and derivatives.

        Parameters
        ----------
        v : float
            Order of the parabolic cylinder function
        x : float
            Value at which to evaluate the function and derivatives

        Returns
        -------
        dv : ndarray
            Values of D_vi(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.
        dp : ndarray
            Derivatives D_vi'(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 13.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    pbvv_seq(v, x)
        Parabolic cylinder functions Vv(x) and derivatives.

        Parameters
        ----------
        v : float
            Order of the parabolic cylinder function
        x : float
            Value at which to evaluate the function and derivatives

        Returns
        -------
        dv : ndarray
            Values of V_vi(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.
        dp : ndarray
            Derivatives V_vi'(x), for vi=v-int(v), vi=1+v-int(v), ..., vi=v.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 13.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    perm(N, k, exact=False)
        Permutations of N things taken k at a time, i.e., k-permutations of N.

        It's also known as "partial permutations".

        Parameters
        ----------
        N : int, ndarray
            Number of things.
        k : int, ndarray
            Number of elements taken.
        exact : bool, optional
            If ``True``, calculate the answer exactly using long integer arithmetic (`N`
            and `k` must be scalar integers). If ``False``, a floating point approximation
            is calculated (more rapidly) using `poch`. Default is ``False``.

        Returns
        -------
        val : int, ndarray
            The number of k-permutations of N.

        Notes
        -----
        - Array arguments accepted only for exact=False case.
        - If k > N, N < 0, or k < 0, then a 0 is returned.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import perm
        >>> k = np.array([3, 4])
        >>> n = np.array([10, 10])
        >>> perm(n, k)
        array([  720.,  5040.])
        >>> perm(10, 3, exact=True)
        720

    polygamma(n, x)
        Polygamma functions.

        Defined as :math:`\psi^{(n)}(x)` where :math:`\psi` is the
        `digamma` function. See [dlmf]_ for details.

        Parameters
        ----------
        n : array_like
            The order of the derivative of the digamma function; must be
            integral
        x : array_like
            Real valued input

        Returns
        -------
        ndarray
            Function results

        See Also
        --------
        digamma

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/5.15

        Examples
        --------
        >>> from scipy import special
        >>> x = [2, 3, 25.5]
        >>> special.polygamma(1, x)
        array([ 0.64493407,  0.39493407,  0.03999467])
        >>> special.polygamma(0, x) == special.psi(x)
        array([ True,  True,  True], dtype=bool)

    pro_cv_seq(m, n, c)
        Characteristic values for prolate spheroidal wave functions.

        Compute a sequence of characteristic values for the prolate
        spheroidal wave functions for mode m and n'=m..n and spheroidal
        parameter c.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

    ps_roots = roots_sh_legendre(n, mu=False)
        Gauss-Legendre (shifted) quadrature.

        Compute the sample points and weights for Gauss-Legendre
        quadrature. The sample points are the roots of the nth degree
        shifted Legendre polynomial :math:`P^*_n(x)`. These sample points
        and weights correctly integrate polynomials of degree :math:`2n -
        1` or less over the interval :math:`[0, 1]` with weight function
        :math:`w(x) = 1.0`. See 2.2.11 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    riccati_jn(n, x)
        Compute Ricatti-Bessel function of the first kind and its derivative.

        The Ricatti-Bessel function of the first kind is defined as :math:`x
        j_n(x)`, where :math:`j_n` is the spherical Bessel function of the first
        kind of order :math:`n`.

        This function computes the value and first derivative of the
        Ricatti-Bessel function for all orders up to and including `n`.

        Parameters
        ----------
        n : int
            Maximum order of function to compute
        x : float
            Argument at which to evaluate

        Returns
        -------
        jn : ndarray
            Value of j0(x), ..., jn(x)
        jnp : ndarray
            First derivative j0'(x), ..., jn'(x)

        Notes
        -----
        The computation is carried out via backward recurrence, using the
        relation DLMF 10.51.1 [2]_.

        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.51.E1

    riccati_yn(n, x)
        Compute Ricatti-Bessel function of the second kind and its derivative.

        The Ricatti-Bessel function of the second kind is defined as :math:`x
        y_n(x)`, where :math:`y_n` is the spherical Bessel function of the second
        kind of order :math:`n`.

        This function computes the value and first derivative of the function for
        all orders up to and including `n`.

        Parameters
        ----------
        n : int
            Maximum order of function to compute
        x : float
            Argument at which to evaluate

        Returns
        -------
        yn : ndarray
            Value of y0(x), ..., yn(x)
        ynp : ndarray
            First derivative y0'(x), ..., yn'(x)

        Notes
        -----
        The computation is carried out via ascending recurrence, using the
        relation DLMF 10.51.1 [2]_.

        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html
        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.51.E1

    roots_chebyc(n, mu=False)
        Gauss-Chebyshev (first kind) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the first kind, :math:`C_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
        with weight function :math:`w(x) = 1 / \sqrt{1 - (x/2)^2}`. See
        22.2.6 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_chebys(n, mu=False)
        Gauss-Chebyshev (second kind) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the second kind, :math:`S_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
        with weight function :math:`w(x) = \sqrt{1 - (x/2)^2}`. See 22.2.7
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_chebyt(n, mu=False)
        Gauss-Chebyshev (first kind) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the first kind, :math:`T_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
        with weight function :math:`w(x) = 1/\sqrt{1 - x^2}`. See 22.2.4
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.chebyshev.chebgauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_chebyu(n, mu=False)
        Gauss-Chebyshev (second kind) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the second kind, :math:`U_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
        with weight function :math:`w(x) = \sqrt{1 - x^2}`. See 22.2.5 in
        [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_gegenbauer(n, alpha, mu=False)
        Gauss-Gegenbauer quadrature.

        Compute the sample points and weights for Gauss-Gegenbauer
        quadrature. The sample points are the roots of the nth degree
        Gegenbauer polynomial, :math:`C^{\alpha}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
        weight function :math:`w(x) = (1 - x^2)^{\alpha - 1/2}`. See
        22.2.3 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -0.5
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_genlaguerre(n, alpha, mu=False)
        Gauss-generalized Laguerre quadrature.

        Compute the sample points and weights for Gauss-generalized
        Laguerre quadrature. The sample points are the roots of the nth
        degree generalized Laguerre polynomial, :math:`L^{\alpha}_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0,
        \infty]` with weight function :math:`w(x) = x^{\alpha}
        e^{-x}`. See 22.3.9 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -1
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_hermite(n, mu=False)
        Gauss-Hermite (physicist's) quadrature.

        Compute the sample points and weights for Gauss-Hermite
        quadrature. The sample points are the roots of the nth degree
        Hermite polynomial, :math:`H_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-\infty, \infty]` with weight
        function :math:`w(x) = e^{-x^2}`. See 22.2.14 in [AS]_ for
        details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.hermite.hermgauss
        roots_hermitenorm

        Notes
        -----
        For small n up to 150 a modified version of the Golub-Welsch
        algorithm is used. Nodes are computed from the eigenvalue
        problem and improved by one step of a Newton iteration.
        The weights are computed from the well-known analytical formula.

        For n larger than 150 an optimal asymptotic algorithm is applied
        which computes nodes and weights in a numerically stable manner.
        The algorithm has linear runtime making computation for very
        large n (several thousand or more) feasible.

        References
        ----------
        .. [townsend.trogdon.olver-2014]
            Townsend, A. and Trogdon, T. and Olver, S. (2014)
            *Fast computation of Gauss quadrature nodes and
            weights on the whole real line*. :arXiv:`1410.5286`.
        .. [townsend.trogdon.olver-2015]
            Townsend, A. and Trogdon, T. and Olver, S. (2015)
            *Fast computation of Gauss quadrature nodes and
            weights on the whole real line*.
            IMA Journal of Numerical Analysis
            :doi:`10.1093/imanum/drv002`.
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_hermitenorm(n, mu=False)
        Gauss-Hermite (statistician's) quadrature.

        Compute the sample points and weights for Gauss-Hermite
        quadrature. The sample points are the roots of the nth degree
        Hermite polynomial, :math:`He_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-\infty, \infty]` with weight
        function :math:`w(x) = e^{-x^2/2}`. See 22.2.15 in [AS]_ for more
        details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.hermite_e.hermegauss

        Notes
        -----
        For small n up to 150 a modified version of the Golub-Welsch
        algorithm is used. Nodes are computed from the eigenvalue
        problem and improved by one step of a Newton iteration.
        The weights are computed from the well-known analytical formula.

        For n larger than 150 an optimal asymptotic algorithm is used
        which computes nodes and weights in a numerical stable manner.
        The algorithm has linear runtime making computation for very
        large n (several thousand or more) feasible.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_jacobi(n, alpha, beta, mu=False)
        Gauss-Jacobi quadrature.

        Compute the sample points and weights for Gauss-Jacobi
        quadrature. The sample points are the roots of the nth degree
        Jacobi polynomial, :math:`P^{\alpha, \beta}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
        weight function :math:`w(x) = (1 - x)^{\alpha} (1 +
        x)^{\beta}`. See 22.2.1 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        alpha : float
            alpha must be > -1
        beta : float
            beta must be > -1
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_laguerre(n, mu=False)
        Gauss-Laguerre quadrature.

        Compute the sample points and weights for Gauss-Laguerre
        quadrature. The sample points are the roots of the nth degree
        Laguerre polynomial, :math:`L_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[0, \infty]` with weight function
        :math:`w(x) = e^{-x}`. See 22.2.13 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.laguerre.laggauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_legendre(n, mu=False)
        Gauss-Legendre quadrature.

        Compute the sample points and weights for Gauss-Legendre
        quadrature [GL]_. The sample points are the roots of the nth degree
        Legendre polynomial :math:`P_n(x)`. These sample points and
        weights correctly integrate polynomials of degree :math:`2n - 1`
        or less over the interval :math:`[-1, 1]` with weight function
        :math:`w(x) = 1`. See 2.2.10 in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.legendre.leggauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [GL] Gauss-Legendre quadrature, Wikipedia,
            https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import roots_legendre, eval_legendre
        >>> roots, weights = roots_legendre(9)

        ``roots`` holds the roots, and ``weights`` holds the weights for
        Gauss-Legendre quadrature.

        >>> roots
        array([-0.96816024, -0.83603111, -0.61337143, -0.32425342,  0.        ,
                0.32425342,  0.61337143,  0.83603111,  0.96816024])
        >>> weights
        array([0.08127439, 0.18064816, 0.2606107 , 0.31234708, 0.33023936,
               0.31234708, 0.2606107 , 0.18064816, 0.08127439])

        Verify that we have the roots by evaluating the degree 9 Legendre
        polynomial at ``roots``.  All the values are approximately zero:

        >>> eval_legendre(9, roots)
        array([-8.88178420e-16, -2.22044605e-16,  1.11022302e-16,  1.11022302e-16,
                0.00000000e+00, -5.55111512e-17, -1.94289029e-16,  1.38777878e-16,
               -8.32667268e-17])

        Here we'll show how the above values can be used to estimate the
        integral from 1 to 2 of f(t) = t + 1/t with Gauss-Legendre
        quadrature [GL]_.  First define the function and the integration
        limits.

        >>> def f(t):
        ...    return t + 1/t
        ...
        >>> a = 1
        >>> b = 2

        We'll use ``integral(f(t), t=a, t=b)`` to denote the definite integral
        of f from t=a to t=b.  The sample points in ``roots`` are from the
        interval [-1, 1], so we'll rewrite the integral with the simple change
        of variable::

            x = 2/(b - a) * t - (a + b)/(b - a)

        with inverse::

            t = (b - a)/2 * x + (a + 2)/2

        Then::

            integral(f(t), a, b) =
                (b - a)/2 * integral(f((b-a)/2*x + (a+b)/2), x=-1, x=1)

        We can approximate the latter integral with the values returned
        by `roots_legendre`.

        Map the roots computed above from [-1, 1] to [a, b].

        >>> t = (b - a)/2 * roots + (a + b)/2

        Approximate the integral as the weighted sum of the function values.

        >>> (b - a)/2 * f(t).dot(weights)
        2.1931471805599276

        Compare that to the exact result, which is 3/2 + log(2):

        >>> 1.5 + np.log(2)
        2.1931471805599454

    roots_sh_chebyt(n, mu=False)
        Gauss-Chebyshev (first kind, shifted) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        shifted Chebyshev polynomial of the first kind, :math:`T_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
        with weight function :math:`w(x) = 1/\sqrt{x - x^2}`. See 22.2.8
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_sh_chebyu(n, mu=False)
        Gauss-Chebyshev (second kind, shifted) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        shifted Chebyshev polynomial of the second kind, :math:`U_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
        with weight function :math:`w(x) = \sqrt{x - x^2}`. See 22.2.9 in
        [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_sh_jacobi(n, p1, q1, mu=False)
        Gauss-Jacobi (shifted) quadrature.

        Compute the sample points and weights for Gauss-Jacobi (shifted)
        quadrature. The sample points are the roots of the nth degree
        shifted Jacobi polynomial, :math:`G^{p,q}_n(x)`. These sample
        points and weights correctly integrate polynomials of degree
        :math:`2n - 1` or less over the interval :math:`[0, 1]` with
        weight function :math:`w(x) = (1 - x)^{p-q} x^{q-1}`. See 22.2.2
        in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        p1 : float
            (p1 - q1) must be > -1
        q1 : float
            q1 must be > 0
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    roots_sh_legendre(n, mu=False)
        Gauss-Legendre (shifted) quadrature.

        Compute the sample points and weights for Gauss-Legendre
        quadrature. The sample points are the roots of the nth degree
        shifted Legendre polynomial :math:`P^*_n(x)`. These sample points
        and weights correctly integrate polynomials of degree :math:`2n -
        1` or less over the interval :math:`[0, 1]` with weight function
        :math:`w(x) = 1.0`. See 2.2.11 in [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    s_roots = roots_chebys(n, mu=False)
        Gauss-Chebyshev (second kind) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the second kind, :math:`S_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
        with weight function :math:`w(x) = \sqrt{1 - (x/2)^2}`. See 22.2.7
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    seterr(**kwargs)
        Set how special-function errors are handled.

        Parameters
        ----------
        all : {'ignore', 'warn' 'raise'}, optional
            Set treatment for all type of special-function errors at
            once. The options are:

            - 'ignore' Take no action when the error occurs
            - 'warn' Print a `SpecialFunctionWarning` when the error
              occurs (via the Python `warnings` module)
            - 'raise' Raise a `SpecialFunctionError` when the error
              occurs.

            The default is to not change the current behavior. If
            behaviors for additional categories of special-function errors
            are specified, then ``all`` is applied first, followed by the
            additional categories.
        singular : {'ignore', 'warn', 'raise'}, optional
            Treatment for singularities.
        underflow : {'ignore', 'warn', 'raise'}, optional
            Treatment for underflow.
        overflow : {'ignore', 'warn', 'raise'}, optional
            Treatment for overflow.
        slow : {'ignore', 'warn', 'raise'}, optional
            Treatment for slow convergence.
        loss : {'ignore', 'warn', 'raise'}, optional
            Treatment for loss of accuracy.
        no_result : {'ignore', 'warn', 'raise'}, optional
            Treatment for failing to find a result.
        domain : {'ignore', 'warn', 'raise'}, optional
            Treatment for an invalid argument to a function.
        arg : {'ignore', 'warn', 'raise'}, optional
            Treatment for an invalid parameter to a function.
        other : {'ignore', 'warn', 'raise'}, optional
            Treatment for an unknown error.

        Returns
        -------
        olderr : dict
            Dictionary containing the old settings.

        See Also
        --------
        geterr : get the current way of handling special-function errors
        errstate : context manager for special-function error handling
        numpy.seterr : similar numpy function for floating-point errors

        Examples
        --------
        >>> import scipy.special as sc
        >>> from pytest import raises
        >>> sc.gammaln(0)
        inf
        >>> olderr = sc.seterr(singular='raise')
        >>> with raises(sc.SpecialFunctionError):
        ...     sc.gammaln(0)
        ...
        >>> _ = sc.seterr(**olderr)

        We can also raise for every category except one.

        >>> olderr = sc.seterr(all='raise', singular='ignore')
        >>> sc.gammaln(0)
        inf
        >>> with raises(sc.SpecialFunctionError):
        ...     sc.spence(-1)
        ...
        >>> _ = sc.seterr(**olderr)

    sh_chebyt(n, monic=False)
        Shifted Chebyshev polynomial of the first kind.

        Defined as :math:`T^*_n(x) = T_n(2x - 1)` for :math:`T_n` the nth
        Chebyshev polynomial of the first kind.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        T : orthopoly1d
            Shifted Chebyshev polynomial of the first kind.

        Notes
        -----
        The polynomials :math:`T^*_n` are orthogonal over :math:`[0, 1]`
        with weight function :math:`(x - x^2)^{-1/2}`.

    sh_chebyu(n, monic=False)
        Shifted Chebyshev polynomial of the second kind.

        Defined as :math:`U^*_n(x) = U_n(2x - 1)` for :math:`U_n` the nth
        Chebyshev polynomial of the second kind.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        U : orthopoly1d
            Shifted Chebyshev polynomial of the second kind.

        Notes
        -----
        The polynomials :math:`U^*_n` are orthogonal over :math:`[0, 1]`
        with weight function :math:`(x - x^2)^{1/2}`.

    sh_jacobi(n, p, q, monic=False)
        Shifted Jacobi polynomial.

        Defined by

        .. math::

            G_n^{(p, q)}(x)
              = \binom{2n + p - 1}{n}^{-1}P_n^{(p - q, q - 1)}(2x - 1),

        where :math:`P_n^{(\cdot, \cdot)}` is the nth Jacobi polynomial.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        p : float
            Parameter, must have :math:`p > q - 1`.
        q : float
            Parameter, must be greater than 0.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        G : orthopoly1d
            Shifted Jacobi polynomial.

        Notes
        -----
        For fixed :math:`p, q`, the polynomials :math:`G_n^{(p, q)}` are
        orthogonal over :math:`[0, 1]` with weight function :math:`(1 -
        x)^{p - q}x^{q - 1}`.

    sh_legendre(n, monic=False)
        Shifted Legendre polynomial.

        Defined as :math:`P^*_n(x) = P_n(2x - 1)` for :math:`P_n` the nth
        Legendre polynomial.

        Parameters
        ----------
        n : int
            Degree of the polynomial.
        monic : bool, optional
            If `True`, scale the leading coefficient to be 1. Default is
            `False`.

        Returns
        -------
        P : orthopoly1d
            Shifted Legendre polynomial.

        Notes
        -----
        The polynomials :math:`P^*_n` are orthogonal over :math:`[0, 1]`
        with weight function 1.

    sinc(x)
        Return the normalized sinc function.

        The sinc function is equal to :math:`\sin(\pi x)/(\pi x)` for any argument
        :math:`x\ne 0`. ``sinc(0)`` takes the limit value 1, making ``sinc`` not
        only everywhere continuous but also infinitely differentiable.

        .. note::

            Note the normalization factor of ``pi`` used in the definition.
            This is the most commonly used definition in signal processing.
            Use ``sinc(x / np.pi)`` to obtain the unnormalized sinc function
            :math:`\sin(x)/x` that is more common in mathematics.

        Parameters
        ----------
        x : ndarray
            Array (possibly multi-dimensional) of values for which to calculate
            ``sinc(x)``.

        Returns
        -------
        out : ndarray
            ``sinc(x)``, which has the same shape as the input.

        Notes
        -----
        The name sinc is short for "sine cardinal" or "sinus cardinalis".

        The sinc function is used in various signal processing applications,
        including in anti-aliasing, in the construction of a Lanczos resampling
        filter, and in interpolation.

        For bandlimited interpolation of discrete-time signals, the ideal
        interpolation kernel is proportional to the sinc function.

        References
        ----------
        .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
               Resource. https://mathworld.wolfram.com/SincFunction.html
        .. [2] Wikipedia, "Sinc function",
               https://en.wikipedia.org/wiki/Sinc_function

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-4, 4, 41)
        >>> np.sinc(x)
         array([-3.89804309e-17,  -4.92362781e-02,  -8.40918587e-02, # may vary
                -8.90384387e-02,  -5.84680802e-02,   3.89804309e-17,
                6.68206631e-02,   1.16434881e-01,   1.26137788e-01,
                8.50444803e-02,  -3.89804309e-17,  -1.03943254e-01,
                -1.89206682e-01,  -2.16236208e-01,  -1.55914881e-01,
                3.89804309e-17,   2.33872321e-01,   5.04551152e-01,
                7.56826729e-01,   9.35489284e-01,   1.00000000e+00,
                9.35489284e-01,   7.56826729e-01,   5.04551152e-01,
                2.33872321e-01,   3.89804309e-17,  -1.55914881e-01,
               -2.16236208e-01,  -1.89206682e-01,  -1.03943254e-01,
               -3.89804309e-17,   8.50444803e-02,   1.26137788e-01,
                1.16434881e-01,   6.68206631e-02,   3.89804309e-17,
                -5.84680802e-02,  -8.90384387e-02,  -8.40918587e-02,
                -4.92362781e-02,  -3.89804309e-17])

        >>> plt.plot(x, np.sinc(x))
        [<matplotlib.lines.Line2D object at 0x...>]
        >>> plt.title("Sinc Function")
        Text(0.5, 1.0, 'Sinc Function')
        >>> plt.ylabel("Amplitude")
        Text(0, 0.5, 'Amplitude')
        >>> plt.xlabel("X")
        Text(0.5, 0, 'X')
        >>> plt.show()

    softmax(x, axis=None)
        Compute the softmax function.

        The softmax function transforms each element of a collection by
        computing the exponential of each element divided by the sum of the
        exponentials of all the elements. That is, if `x` is a one-dimensional
        numpy array::

            softmax(x) = np.exp(x)/sum(np.exp(x))

        Parameters
        ----------
        x : array_like
            Input array.
        axis : int or tuple of ints, optional
            Axis to compute values along. Default is None and softmax will be
            computed over the entire array `x`.

        Returns
        -------
        s : ndarray
            An array the same shape as `x`. The result will sum to 1 along the
            specified axis.

        Notes
        -----
        The formula for the softmax function :math:`\sigma(x)` for a vector
        :math:`x = \{x_0, x_1, ..., x_{n-1}\}` is

        .. math:: \sigma(x)_j = \frac{e^{x_j}}{\sum_k e^{x_k}}

        The `softmax` function is the gradient of `logsumexp`.

        The implementation uses shifting to avoid overflow. See [1]_ for more
        details.

        .. versionadded:: 1.2.0

        References
        ----------
        .. [1] P. Blanchard, D.J. Higham, N.J. Higham, "Accurately computing the
           log-sum-exp and softmax functions", IMA Journal of Numerical Analysis,
           Vol.41(4), :doi:`10.1093/imanum/draa038`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import softmax
        >>> np.set_printoptions(precision=5)

        >>> x = np.array([[1, 0.5, 0.2, 3],
        ...               [1,  -1,   7, 3],
        ...               [2,  12,  13, 3]])
        ...

        Compute the softmax transformation over the entire array.

        >>> m = softmax(x)
        >>> m
        array([[  4.48309e-06,   2.71913e-06,   2.01438e-06,   3.31258e-05],
               [  4.48309e-06,   6.06720e-07,   1.80861e-03,   3.31258e-05],
               [  1.21863e-05,   2.68421e-01,   7.29644e-01,   3.31258e-05]])

        >>> m.sum()
        1.0

        Compute the softmax transformation along the first axis (i.e., the
        columns).

        >>> m = softmax(x, axis=0)

        >>> m
        array([[  2.11942e-01,   1.01300e-05,   2.75394e-06,   3.33333e-01],
               [  2.11942e-01,   2.26030e-06,   2.47262e-03,   3.33333e-01],
               [  5.76117e-01,   9.99988e-01,   9.97525e-01,   3.33333e-01]])

        >>> m.sum(axis=0)
        array([ 1.,  1.,  1.,  1.])

        Compute the softmax transformation along the second axis (i.e., the rows).

        >>> m = softmax(x, axis=1)
        >>> m
        array([[  1.05877e-01,   6.42177e-02,   4.75736e-02,   7.82332e-01],
               [  2.42746e-03,   3.28521e-04,   9.79307e-01,   1.79366e-02],
               [  1.22094e-05,   2.68929e-01,   7.31025e-01,   3.31885e-05]])

        >>> m.sum(axis=1)
        array([ 1.,  1.,  1.])

    spherical_in(n, z, derivative=False)
        Modified spherical Bessel function of the first kind or its derivative.

        Defined as [1]_,

        .. math:: i_n(z) = \sqrt{\frac{\pi}{2z}} I_{n + 1/2}(z),

        where :math:`I_n` is the modified Bessel function of the first kind.

        Parameters
        ----------
        n : int, array_like
            Order of the Bessel function (n >= 0).
        z : complex or float, array_like
            Argument of the Bessel function.
        derivative : bool, optional
            If True, the value of the derivative (rather than the function
            itself) is returned.

        Returns
        -------
        in : ndarray

        Notes
        -----
        The function is computed using its definitional relation to the
        modified cylindrical Bessel function of the first kind.

        The derivative is computed using the relations [2]_,

        .. math::
            i_n' = i_{n-1} - \frac{n + 1}{z} i_n.

            i_1' = i_0


        .. versionadded:: 0.18.0

        References
        ----------
        .. [1] https://dlmf.nist.gov/10.47.E7
        .. [2] https://dlmf.nist.gov/10.51.E5
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The modified spherical Bessel functions of the first kind :math:`i_n`
        accept both real and complex second argument.
        They can return a complex type:

        >>> from scipy.special import spherical_in
        >>> spherical_in(0, 3+5j)
        (-1.1689867793369182-1.2697305267234222j)
        >>> type(spherical_in(0, 3+5j))
        <class 'numpy.complex128'>

        We can verify the relation for the derivative from the Notes
        for :math:`n=3` in the interval :math:`[1, 2]`:

        >>> import numpy as np
        >>> x = np.arange(1.0, 2.0, 0.01)
        >>> np.allclose(spherical_in(3, x, True),
        ...             spherical_in(2, x) - 4/x * spherical_in(3, x))
        True

        The first few :math:`i_n` with real argument:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(0.0, 6.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-0.5, 5.0)
        >>> ax.set_title(r'Modified spherical Bessel functions $i_n$')
        >>> for n in np.arange(0, 4):
        ...     ax.plot(x, spherical_in(n, x), label=rf'$i_{n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    spherical_jn(n, z, derivative=False)
        Spherical Bessel function of the first kind or its derivative.

        Defined as [1]_,

        .. math:: j_n(z) = \sqrt{\frac{\pi}{2z}} J_{n + 1/2}(z),

        where :math:`J_n` is the Bessel function of the first kind.

        Parameters
        ----------
        n : int, array_like
            Order of the Bessel function (n >= 0).
        z : complex or float, array_like
            Argument of the Bessel function.
        derivative : bool, optional
            If True, the value of the derivative (rather than the function
            itself) is returned.

        Returns
        -------
        jn : ndarray

        Notes
        -----
        For real arguments greater than the order, the function is computed
        using the ascending recurrence [2]_. For small real or complex
        arguments, the definitional relation to the cylindrical Bessel function
        of the first kind is used.

        The derivative is computed using the relations [3]_,

        .. math::
            j_n'(z) = j_{n-1}(z) - \frac{n + 1}{z} j_n(z).

            j_0'(z) = -j_1(z)


        .. versionadded:: 0.18.0

        References
        ----------
        .. [1] https://dlmf.nist.gov/10.47.E3
        .. [2] https://dlmf.nist.gov/10.51.E1
        .. [3] https://dlmf.nist.gov/10.51.E2
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The spherical Bessel functions of the first kind :math:`j_n` accept
        both real and complex second argument. They can return a complex type:

        >>> from scipy.special import spherical_jn
        >>> spherical_jn(0, 3+5j)
        (-9.878987731663194-8.021894345786002j)
        >>> type(spherical_jn(0, 3+5j))
        <class 'numpy.complex128'>

        We can verify the relation for the derivative from the Notes
        for :math:`n=3` in the interval :math:`[1, 2]`:

        >>> import numpy as np
        >>> x = np.arange(1.0, 2.0, 0.01)
        >>> np.allclose(spherical_jn(3, x, True),
        ...             spherical_jn(2, x) - 4/x * spherical_jn(3, x))
        True

        The first few :math:`j_n` with real argument:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(0.0, 10.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-0.5, 1.5)
        >>> ax.set_title(r'Spherical Bessel functions $j_n$')
        >>> for n in np.arange(0, 4):
        ...     ax.plot(x, spherical_jn(n, x), label=rf'$j_{n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    spherical_kn(n, z, derivative=False)
        Modified spherical Bessel function of the second kind or its derivative.

        Defined as [1]_,

        .. math:: k_n(z) = \sqrt{\frac{\pi}{2z}} K_{n + 1/2}(z),

        where :math:`K_n` is the modified Bessel function of the second kind.

        Parameters
        ----------
        n : int, array_like
            Order of the Bessel function (n >= 0).
        z : complex or float, array_like
            Argument of the Bessel function.
        derivative : bool, optional
            If True, the value of the derivative (rather than the function
            itself) is returned.

        Returns
        -------
        kn : ndarray

        Notes
        -----
        The function is computed using its definitional relation to the
        modified cylindrical Bessel function of the second kind.

        The derivative is computed using the relations [2]_,

        .. math::
            k_n' = -k_{n-1} - \frac{n + 1}{z} k_n.

            k_0' = -k_1


        .. versionadded:: 0.18.0

        References
        ----------
        .. [1] https://dlmf.nist.gov/10.47.E9
        .. [2] https://dlmf.nist.gov/10.51.E5
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The modified spherical Bessel functions of the second kind :math:`k_n`
        accept both real and complex second argument.
        They can return a complex type:

        >>> from scipy.special import spherical_kn
        >>> spherical_kn(0, 3+5j)
        (0.012985785614001561+0.003354691603137546j)
        >>> type(spherical_kn(0, 3+5j))
        <class 'numpy.complex128'>

        We can verify the relation for the derivative from the Notes
        for :math:`n=3` in the interval :math:`[1, 2]`:

        >>> import numpy as np
        >>> x = np.arange(1.0, 2.0, 0.01)
        >>> np.allclose(spherical_kn(3, x, True),
        ...             - 4/x * spherical_kn(3, x) - spherical_kn(2, x))
        True

        The first few :math:`k_n` with real argument:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(0.0, 4.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(0.0, 5.0)
        >>> ax.set_title(r'Modified spherical Bessel functions $k_n$')
        >>> for n in np.arange(0, 4):
        ...     ax.plot(x, spherical_kn(n, x), label=rf'$k_{n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    spherical_yn(n, z, derivative=False)
        Spherical Bessel function of the second kind or its derivative.

        Defined as [1]_,

        .. math:: y_n(z) = \sqrt{\frac{\pi}{2z}} Y_{n + 1/2}(z),

        where :math:`Y_n` is the Bessel function of the second kind.

        Parameters
        ----------
        n : int, array_like
            Order of the Bessel function (n >= 0).
        z : complex or float, array_like
            Argument of the Bessel function.
        derivative : bool, optional
            If True, the value of the derivative (rather than the function
            itself) is returned.

        Returns
        -------
        yn : ndarray

        Notes
        -----
        For real arguments, the function is computed using the ascending
        recurrence [2]_.  For complex arguments, the definitional relation to
        the cylindrical Bessel function of the second kind is used.

        The derivative is computed using the relations [3]_,

        .. math::
            y_n' = y_{n-1} - \frac{n + 1}{z} y_n.

            y_0' = -y_1


        .. versionadded:: 0.18.0

        References
        ----------
        .. [1] https://dlmf.nist.gov/10.47.E4
        .. [2] https://dlmf.nist.gov/10.51.E1
        .. [3] https://dlmf.nist.gov/10.51.E2
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        The spherical Bessel functions of the second kind :math:`y_n` accept
        both real and complex second argument. They can return a complex type:

        >>> from scipy.special import spherical_yn
        >>> spherical_yn(0, 3+5j)
        (8.022343088587197-9.880052589376795j)
        >>> type(spherical_yn(0, 3+5j))
        <class 'numpy.complex128'>

        We can verify the relation for the derivative from the Notes
        for :math:`n=3` in the interval :math:`[1, 2]`:

        >>> import numpy as np
        >>> x = np.arange(1.0, 2.0, 0.01)
        >>> np.allclose(spherical_yn(3, x, True),
        ...             spherical_yn(2, x) - 4/x * spherical_yn(3, x))
        True

        The first few :math:`y_n` with real argument:

        >>> import matplotlib.pyplot as plt
        >>> x = np.arange(0.0, 10.0, 0.01)
        >>> fig, ax = plt.subplots()
        >>> ax.set_ylim(-2.0, 1.0)
        >>> ax.set_title(r'Spherical Bessel functions $y_n$')
        >>> for n in np.arange(0, 4):
        ...     ax.plot(x, spherical_yn(n, x), label=rf'$y_{n}$')
        >>> plt.legend(loc='best')
        >>> plt.show()

    stirling2(N, K, *, exact=False)
        Generate Stirling number(s) of the second kind.

        Stirling numbers of the second kind count the number of ways to
        partition a set with N elements into K non-empty subsets.

        The values this function returns are calculated using a dynamic
        program which avoids redundant computation across the subproblems
        in the solution. For array-like input, this implementation also
        avoids redundant computation across the different Stirling number
        calculations.

        The numbers are sometimes denoted

        .. math::

            {N \brace{K}}

        see [1]_ for details. This is often expressed-verbally-as
        "N subset K".

        Parameters
        ----------
        N : int, ndarray
            Number of things.
        K : int, ndarray
            Number of non-empty subsets taken.
        exact : bool, optional
            Uses dynamic programming (DP) with floating point
            numbers for smaller arrays and uses a second order approximation due to
            Temme for larger entries  of `N` and `K` that allows trading speed for
            accuracy. See [2]_ for a description. Temme approximation is used for
            values `n>50`. The max error from the DP has max relative error
            `4.5*10^-16` for `n<=50` and the max error from the Temme approximation
            has max relative error `5*10^-5` for `51 <= n < 70` and
            `9*10^-6` for `70 <= n < 101`. Note that these max relative errors will
            decrease further as `n` increases.

        Returns
        -------
        val : int, float, ndarray
            The number of partitions.

        See Also
        --------
        comb : The number of combinations of N things taken k at a time.

        Notes
        -----
        - If N < 0, or K < 0, then 0 is returned.
        - If K > N, then 0 is returned.

        The output type will always be `int` or ndarray of `object`.
        The input must contain either numpy or python integers otherwise a
        TypeError is raised.

        References
        ----------
        .. [1] R. L. Graham, D. E. Knuth and O. Patashnik, "Concrete
            Mathematics: A Foundation for Computer Science," Addison-Wesley
            Publishing Company, Boston, 1989. Chapter 6, page 258.

        .. [2] Temme, Nico M. "Asymptotic estimates of Stirling numbers."
            Studies in Applied Mathematics 89.3 (1993): 233-243.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import stirling2
        >>> k = np.array([3, -1, 3])
        >>> n = np.array([10, 10, 9])
        >>> stirling2(n, k)
        array([9330, 0, 3025], dtype=object)

    t_roots = roots_chebyt(n, mu=False)
        Gauss-Chebyshev (first kind) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the first kind, :math:`T_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
        with weight function :math:`w(x) = 1/\sqrt{1 - x^2}`. See 22.2.4
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad
        numpy.polynomial.chebyshev.chebgauss

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    ts_roots = roots_sh_chebyt(n, mu=False)
        Gauss-Chebyshev (first kind, shifted) quadrature.

        Compute the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        shifted Chebyshev polynomial of the first kind, :math:`T_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
        with weight function :math:`w(x) = 1/\sqrt{x - x^2}`. See 22.2.8
        in [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    u_roots = roots_chebyu(n, mu=False)
        Gauss-Chebyshev (second kind) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        Chebyshev polynomial of the second kind, :math:`U_n(x)`. These
        sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
        with weight function :math:`w(x) = \sqrt{1 - x^2}`. See 22.2.5 in
        [AS]_ for details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    us_roots = roots_sh_chebyu(n, mu=False)
        Gauss-Chebyshev (second kind, shifted) quadrature.

        Computes the sample points and weights for Gauss-Chebyshev
        quadrature. The sample points are the roots of the nth degree
        shifted Chebyshev polynomial of the second kind, :math:`U_n(x)`.
        These sample points and weights correctly integrate polynomials of
        degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
        with weight function :math:`w(x) = \sqrt{x - x^2}`. See 22.2.9 in
        [AS]_ for more details.

        Parameters
        ----------
        n : int
            quadrature order
        mu : bool, optional
            If True, return the sum of the weights, optional.

        Returns
        -------
        x : ndarray
            Sample points
        w : ndarray
            Weights
        mu : float
            Sum of the weights

        See Also
        --------
        scipy.integrate.quadrature
        scipy.integrate.fixed_quad

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    y0_zeros(nt, complex=False)
        Compute nt zeros of Bessel function Y0(z), and derivative at each zero.

        The derivatives are given by Y0'(z0) = -Y1(z0) at each zero z0.

        Parameters
        ----------
        nt : int
            Number of zeros to return
        complex : bool, default False
            Set to False to return only the real zeros; set to True to return only
            the complex zeros with negative real part and positive imaginary part.
            Note that the complex conjugates of the latter are also zeros of the
            function, but are not returned by this routine.

        Returns
        -------
        z0n : ndarray
            Location of nth zero of Y0(z)
        y0pz0n : ndarray
            Value of derivative Y0'(z0) for nth zero

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first 4 real roots and the derivatives at the roots of
        :math:`Y_0`:

        >>> import numpy as np
        >>> from scipy.special import y0_zeros
        >>> zeros, grads = y0_zeros(4)
        >>> with np.printoptions(precision=5):
        ...     print(f"Roots: {zeros}")
        ...     print(f"Gradients: {grads}")
        Roots: [ 0.89358+0.j  3.95768+0.j  7.08605+0.j 10.22235+0.j]
        Gradients: [-0.87942+0.j  0.40254+0.j -0.3001 +0.j  0.2497 +0.j]

        Plot the real part of :math:`Y_0` and the first four computed roots.

        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import y0
        >>> xmin = 0
        >>> xmax = 11
        >>> x = np.linspace(xmin, xmax, 500)
        >>> fig, ax = plt.subplots()
        >>> ax.hlines(0, xmin, xmax, color='k')
        >>> ax.plot(x, y0(x), label=r'$Y_0$')
        >>> zeros, grads = y0_zeros(4)
        >>> ax.scatter(zeros.real, np.zeros((4, )), s=30, c='r',
        ...            label=r'$Y_0$_zeros', zorder=5)
        >>> ax.set_ylim(-0.5, 0.6)
        >>> ax.set_xlim(xmin, xmax)
        >>> plt.legend(ncol=2)
        >>> plt.show()

        Compute the first 4 complex roots and the derivatives at the roots of
        :math:`Y_0` by setting ``complex=True``:

        >>> y0_zeros(4, True)
        (array([ -2.40301663+0.53988231j,  -5.5198767 +0.54718001j,
                 -8.6536724 +0.54841207j, -11.79151203+0.54881912j]),
         array([ 0.10074769-0.88196771j, -0.02924642+0.5871695j ,
                 0.01490806-0.46945875j, -0.00937368+0.40230454j]))

    y1_zeros(nt, complex=False)
        Compute nt zeros of Bessel function Y1(z), and derivative at each zero.

        The derivatives are given by Y1'(z1) = Y0(z1) at each zero z1.

        Parameters
        ----------
        nt : int
            Number of zeros to return
        complex : bool, default False
            Set to False to return only the real zeros; set to True to return only
            the complex zeros with negative real part and positive imaginary part.
            Note that the complex conjugates of the latter are also zeros of the
            function, but are not returned by this routine.

        Returns
        -------
        z1n : ndarray
            Location of nth zero of Y1(z)
        y1pz1n : ndarray
            Value of derivative Y1'(z1) for nth zero

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first 4 real roots and the derivatives at the roots of
        :math:`Y_1`:

        >>> import numpy as np
        >>> from scipy.special import y1_zeros
        >>> zeros, grads = y1_zeros(4)
        >>> with np.printoptions(precision=5):
        ...     print(f"Roots: {zeros}")
        ...     print(f"Gradients: {grads}")
        Roots: [ 2.19714+0.j  5.42968+0.j  8.59601+0.j 11.74915+0.j]
        Gradients: [ 0.52079+0.j -0.34032+0.j  0.27146+0.j -0.23246+0.j]

        Extract the real parts:

        >>> realzeros = zeros.real
        >>> realzeros
        array([ 2.19714133,  5.42968104,  8.59600587, 11.74915483])

        Plot :math:`Y_1` and the first four computed roots.

        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import y1
        >>> xmin = 0
        >>> xmax = 13
        >>> x = np.linspace(xmin, xmax, 500)
        >>> zeros, grads = y1_zeros(4)
        >>> fig, ax = plt.subplots()
        >>> ax.hlines(0, xmin, xmax, color='k')
        >>> ax.plot(x, y1(x), label=r'$Y_1$')
        >>> ax.scatter(zeros.real, np.zeros((4, )), s=30, c='r',
        ...            label=r'$Y_1$_zeros', zorder=5)
        >>> ax.set_ylim(-0.5, 0.5)
        >>> ax.set_xlim(xmin, xmax)
        >>> plt.legend()
        >>> plt.show()

        Compute the first 4 complex roots and the derivatives at the roots of
        :math:`Y_1` by setting ``complex=True``:

        >>> y1_zeros(4, True)
        (array([ -0.50274327+0.78624371j,  -3.83353519+0.56235654j,
                 -7.01590368+0.55339305j, -10.17357383+0.55127339j]),
         array([-0.45952768+1.31710194j,  0.04830191-0.69251288j,
                -0.02012695+0.51864253j,  0.011614  -0.43203296j]))

    y1p_zeros(nt, complex=False)
        Compute nt zeros of Bessel derivative Y1'(z), and value at each zero.

        The values are given by Y1(z1) at each z1 where Y1'(z1)=0.

        Parameters
        ----------
        nt : int
            Number of zeros to return
        complex : bool, default False
            Set to False to return only the real zeros; set to True to return only
            the complex zeros with negative real part and positive imaginary part.
            Note that the complex conjugates of the latter are also zeros of the
            function, but are not returned by this routine.

        Returns
        -------
        z1pn : ndarray
            Location of nth zero of Y1'(z)
        y1z1pn : ndarray
            Value of derivative Y1(z1) for nth zero

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first four roots of :math:`Y_1'` and the values of
        :math:`Y_1` at these roots.

        >>> import numpy as np
        >>> from scipy.special import y1p_zeros
        >>> y1grad_roots, y1_values = y1p_zeros(4)
        >>> with np.printoptions(precision=5):
        ...     print(f"Y1' Roots: {y1grad_roots.real}")
        ...     print(f"Y1 values: {y1_values.real}")
        Y1' Roots: [ 3.68302  6.9415  10.1234  13.28576]
        Y1 values: [ 0.41673 -0.30317  0.25091 -0.21897]

        `y1p_zeros` can be used to calculate the extremal points of :math:`Y_1`
        directly. Here we plot :math:`Y_1` and the first four extrema.

        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import y1, yvp
        >>> y1_roots, y1_values_at_roots = y1p_zeros(4)
        >>> real_roots = y1_roots.real
        >>> xmax = 15
        >>> x = np.linspace(0, xmax, 500)
        >>> x[0] += 1e-15
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, y1(x), label=r'$Y_1$')
        >>> ax.plot(x, yvp(1, x, 1), label=r"$Y_1'$")
        >>> ax.scatter(real_roots, np.zeros((4, )), s=30, c='r',
        ...            label=r"Roots of $Y_1'$", zorder=5)
        >>> ax.scatter(real_roots, y1_values_at_roots.real, s=30, c='k',
        ...            label=r"Extrema of $Y_1$", zorder=5)
        >>> ax.hlines(0, 0, xmax, color='k')
        >>> ax.set_ylim(-0.5, 0.5)
        >>> ax.set_xlim(0, xmax)
        >>> ax.legend(ncol=2, bbox_to_anchor=(1., 0.75))
        >>> plt.tight_layout()
        >>> plt.show()

    yn_zeros(n, nt)
        Compute zeros of integer-order Bessel function Yn(x).

        Compute `nt` zeros of the functions :math:`Y_n(x)` on the interval
        :math:`(0, \infty)`. The zeros are returned in ascending order.

        Parameters
        ----------
        n : int
            Order of Bessel function
        nt : int
            Number of zeros to return

        Returns
        -------
        ndarray
            First `nt` zeros of the Bessel function.

        See Also
        --------
        yn: Bessel function of the second kind for integer order
        yv: Bessel function of the second kind for real order

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first four roots of :math:`Y_2`.

        >>> from scipy.special import yn_zeros
        >>> yn_zeros(2, 4)
        array([ 3.38424177,  6.79380751, 10.02347798, 13.20998671])

        Plot :math:`Y_2` and its first four roots.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import yn, yn_zeros
        >>> xmin = 2
        >>> xmax = 15
        >>> x = np.linspace(xmin, xmax, 500)
        >>> fig, ax = plt.subplots()
        >>> ax.hlines(0, xmin, xmax, color='k')
        >>> ax.plot(x, yn(2, x), label=r'$Y_2$')
        >>> ax.scatter(yn_zeros(2, 4), np.zeros((4, )), s=30, c='r',
        ...            label='Roots', zorder=5)
        >>> ax.set_ylim(-0.4, 0.4)
        >>> ax.set_xlim(xmin, xmax)
        >>> plt.legend()
        >>> plt.show()

    ynp_zeros(n, nt)
        Compute zeros of integer-order Bessel function derivatives Yn'(x).

        Compute `nt` zeros of the functions :math:`Y_n'(x)` on the
        interval :math:`(0, \infty)`. The zeros are returned in ascending
        order.

        Parameters
        ----------
        n : int
            Order of Bessel function
        nt : int
            Number of zeros to return

        Returns
        -------
        ndarray
            First `nt` zeros of the Bessel derivative function.


        See Also
        --------
        yvp

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        Examples
        --------
        Compute the first four roots of the first derivative of the
        Bessel function of second kind for order 0 :math:`Y_0'`.

        >>> from scipy.special import ynp_zeros
        >>> ynp_zeros(0, 4)
        array([ 2.19714133,  5.42968104,  8.59600587, 11.74915483])

        Plot :math:`Y_0`, :math:`Y_0'` and confirm visually that the roots of
        :math:`Y_0'` are located at local extrema of :math:`Y_0`.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import yn, ynp_zeros, yvp
        >>> zeros = ynp_zeros(0, 4)
        >>> xmax = 13
        >>> x = np.linspace(0, xmax, 500)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, yn(0, x), label=r'$Y_0$')
        >>> ax.plot(x, yvp(0, x, 1), label=r"$Y_0'$")
        >>> ax.scatter(zeros, np.zeros((4, )), s=30, c='r',
        ...            label=r"Roots of $Y_0'$", zorder=5)
        >>> for root in zeros:
        ...     y0_extremum =  yn(0, root)
        ...     lower = min(0, y0_extremum)
        ...     upper = max(0, y0_extremum)
        ...     ax.vlines(root, lower, upper, color='r')
        >>> ax.hlines(0, 0, xmax, color='k')
        >>> ax.set_ylim(-0.6, 0.6)
        >>> ax.set_xlim(0, xmax)
        >>> plt.legend()
        >>> plt.show()

    yvp(v, z, n=1)
        Compute derivatives of Bessel functions of the second kind.

        Compute the nth derivative of the Bessel function `Yv` with
        respect to `z`.

        Parameters
        ----------
        v : array_like of float
            Order of Bessel function
        z : complex
            Argument at which to evaluate the derivative
        n : int, default 1
            Order of derivative. For 0 returns the BEssel function `yv`

        Returns
        -------
        scalar or ndarray
            nth derivative of the Bessel function.

        See Also
        --------
        yv : Bessel functions of the second kind

        Notes
        -----
        The derivative is computed using the relation DLFM 10.6.7 [2]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996, chapter 5.
               https://people.sc.fsu.edu/~jburkardt/f77_src/special_functions/special_functions.html

        .. [2] NIST Digital Library of Mathematical Functions.
               https://dlmf.nist.gov/10.6.E7

        Examples
        --------
        Compute the Bessel function of the second kind of order 0 and
        its first two derivatives at 1.

        >>> from scipy.special import yvp
        >>> yvp(0, 1, 0), yvp(0, 1, 1), yvp(0, 1, 2)
        (0.088256964215677, 0.7812128213002889, -0.8694697855159659)

        Compute the first derivative of the Bessel function of the second
        kind for several orders at 1 by providing an array for `v`.

        >>> yvp([0, 1, 2], 1, 1)
        array([0.78121282, 0.86946979, 2.52015239])

        Compute the first derivative of the Bessel function of the
        second kind of order 0 at several points by providing an array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> yvp(0, points, 1)
        array([ 1.47147239,  0.41230863, -0.32467442])

        Plot the Bessel function of the second kind of order 1 and its
        first three derivatives.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0, 5, 1000)
        >>> x[0] += 1e-15
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, yvp(1, x, 0), label=r"$Y_1$")
        >>> ax.plot(x, yvp(1, x, 1), label=r"$Y_1'$")
        >>> ax.plot(x, yvp(1, x, 2), label=r"$Y_1''$")
        >>> ax.plot(x, yvp(1, x, 3), label=r"$Y_1'''$")
        >>> ax.set_ylim(-10, 10)
        >>> plt.legend()
        >>> plt.show()

    zeta(x, q=None, out=None)
        Riemann or Hurwitz zeta function.

        Parameters
        ----------
        x : array_like of float
            Input data, must be real
        q : array_like of float, optional
            Input data, must be real.  Defaults to Riemann zeta.
        out : ndarray, optional
            Output array for the computed values.

        Returns
        -------
        out : array_like
            Values of zeta(x).

        See Also
        --------
        zetac

        Notes
        -----
        The two-argument version is the Hurwitz zeta function

        .. math::

            \zeta(x, q) = \sum_{k=0}^{\infty} \frac{1}{(k + q)^x};

        see [dlmf]_ for details. The Riemann zeta function corresponds to
        the case when ``q = 1``.

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/25.11#i

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import zeta, polygamma, factorial

        Some specific values:

        >>> zeta(2), np.pi**2/6
        (1.6449340668482266, 1.6449340668482264)

        >>> zeta(4), np.pi**4/90
        (1.0823232337111381, 1.082323233711138)

        Relation to the `polygamma` function:

        >>> m = 3
        >>> x = 1.25
        >>> polygamma(m, x)
        array(2.782144009188397)
        >>> (-1)**(m+1) * factorial(m) * zeta(m+1, x)
        2.7821440091883969

DATA
    __all__ = ['agm', 'bdtr', 'bdtrc', 'bdtri', 'bdtrik', 'bdtrin', 'besse...
    agm = <ufunc 'agm'>
        agm(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        agm(a, b, out=None)

        Compute the arithmetic-geometric mean of `a` and `b`.

        Start with a_0 = a and b_0 = b and iteratively compute::

            a_{n+1} = (a_n + b_n)/2
            b_{n+1} = sqrt(a_n*b_n)

        a_n and b_n converge to the same limit as n increases; their common
        limit is agm(a, b).

        Parameters
        ----------
        a, b : array_like
            Real values only. If the values are both negative, the result
            is negative. If one value is negative and the other is positive,
            `nan` is returned.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            The arithmetic-geometric mean of `a` and `b`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import agm
        >>> a, b = 24.0, 6.0
        >>> agm(a, b)
        13.458171481725614

        Compare that result to the iteration:

        >>> while a != b:
        ...     a, b = (a + b)/2, np.sqrt(a*b)
        ...     print("a = %19.16f  b=%19.16f" % (a, b))
        ...
        a = 15.0000000000000000  b=12.0000000000000000
        a = 13.5000000000000000  b=13.4164078649987388
        a = 13.4582039324993694  b=13.4581390309909850
        a = 13.4581714817451772  b=13.4581714817060547
        a = 13.4581714817256159  b=13.4581714817256159

        When array-like arguments are given, broadcasting applies:

        >>> a = np.array([[1.5], [3], [6]])  # a has shape (3, 1).
        >>> b = np.array([6, 12, 24, 48])    # b has shape (4,).
        >>> agm(a, b)
        array([[  3.36454287,   5.42363427,   9.05798751,  15.53650756],
               [  4.37037309,   6.72908574,  10.84726853,  18.11597502],
               [  6.        ,   8.74074619,  13.45817148,  21.69453707]])

    airy = <ufunc 'airy'>
        airy(x[, out1, out2, out3, out4], / [, out=(None, None, None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        airy(z, out=None)

        Airy functions and their derivatives.

        Parameters
        ----------
        z : array_like
            Real or complex argument.
        out : tuple of ndarray, optional
            Optional output arrays for the function values

        Returns
        -------
        Ai, Aip, Bi, Bip : 4-tuple of scalar or ndarray
            Airy functions Ai and Bi, and their derivatives Aip and Bip.

        See Also
        --------
        airye : exponentially scaled Airy functions.

        Notes
        -----
        The Airy functions Ai and Bi are two independent solutions of

        .. math:: y''(x) = x y(x).

        For real `z` in [-10, 10], the computation is carried out by calling
        the Cephes [1]_ `airy` routine, which uses power series summation
        for small `z` and rational minimax approximations for large `z`.

        Outside this range, the AMOS [2]_ `zairy` and `zbiry` routines are
        employed.  They are computed using power series for :math:`|z| < 1` and
        the following relations to modified Bessel functions for larger `z`
        (where :math:`t \equiv 2 z^{3/2}/3`):

        .. math::

            Ai(z) = \frac{1}{\pi \sqrt{3}} K_{1/3}(t)

            Ai'(z) = -\frac{z}{\pi \sqrt{3}} K_{2/3}(t)

            Bi(z) = \sqrt{\frac{z}{3}} \left(I_{-1/3}(t) + I_{1/3}(t) \right)

            Bi'(z) = \frac{z}{\sqrt{3}} \left(I_{-2/3}(t) + I_{2/3}(t)\right)

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [2] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Compute the Airy functions on the interval [-15, 5].

        >>> import numpy as np
        >>> from scipy import special
        >>> x = np.linspace(-15, 5, 201)
        >>> ai, aip, bi, bip = special.airy(x)

        Plot Ai(x) and Bi(x).

        >>> import matplotlib.pyplot as plt
        >>> plt.plot(x, ai, 'r', label='Ai(x)')
        >>> plt.plot(x, bi, 'b--', label='Bi(x)')
        >>> plt.ylim(-0.5, 1.0)
        >>> plt.grid()
        >>> plt.legend(loc='upper left')
        >>> plt.show()

    airye = <ufunc 'airye'>
        airye(x[, out1, out2, out3, out4], / [, out=(None, None, None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        airye(z, out=None)

        Exponentially scaled Airy functions and their derivatives.

        Scaling::

            eAi  = Ai  * exp(2.0/3.0*z*sqrt(z))
            eAip = Aip * exp(2.0/3.0*z*sqrt(z))
            eBi  = Bi  * exp(-abs(2.0/3.0*(z*sqrt(z)).real))
            eBip = Bip * exp(-abs(2.0/3.0*(z*sqrt(z)).real))

        Parameters
        ----------
        z : array_like
            Real or complex argument.
        out : tuple of ndarray, optional
            Optional output arrays for the function values

        Returns
        -------
        eAi, eAip, eBi, eBip : 4-tuple of scalar or ndarray
            Exponentially scaled Airy functions eAi and eBi, and their derivatives
            eAip and eBip

        See Also
        --------
        airy

        Notes
        -----
        Wrapper for the AMOS [1]_ routines `zairy` and `zbiry`.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        We can compute exponentially scaled Airy functions and their derivatives:

        >>> import numpy as np
        >>> from scipy.special import airye
        >>> import matplotlib.pyplot as plt
        >>> z = np.linspace(0, 50, 500)
        >>> eAi, eAip, eBi, eBip = airye(z)
        >>> f, ax = plt.subplots(2, 1, sharex=True)
        >>> for ind, data in enumerate([[eAi, eAip, ["eAi", "eAip"]],
        ...                             [eBi, eBip, ["eBi", "eBip"]]]):
        ...     ax[ind].plot(z, data[0], "-r", z, data[1], "-b")
        ...     ax[ind].legend(data[2])
        ...     ax[ind].grid(True)
        >>> plt.show()

        We can compute these using usual non-scaled Airy functions by:

        >>> from scipy.special import airy
        >>> Ai, Aip, Bi, Bip = airy(z)
        >>> np.allclose(eAi, Ai * np.exp(2.0 / 3.0 * z * np.sqrt(z)))
        True
        >>> np.allclose(eAip, Aip * np.exp(2.0 / 3.0 * z * np.sqrt(z)))
        True
        >>> np.allclose(eBi, Bi * np.exp(-abs(np.real(2.0 / 3.0 * z * np.sqrt(z)))))
        True
        >>> np.allclose(eBip, Bip * np.exp(-abs(np.real(2.0 / 3.0 * z * np.sqrt(z)))))
        True

        Comparing non-scaled and exponentially scaled ones, the usual non-scaled
        function quickly underflows for large values, whereas the exponentially
        scaled function does not.

        >>> airy(200)
        (0.0, 0.0, nan, nan)
        >>> airye(200)
        (0.07501041684381093, -1.0609012305109042, 0.15003188417418148, 2.1215836725571093)

    bdtr = <ufunc 'bdtr'>
        bdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        bdtr(k, n, p, out=None)

        Binomial distribution cumulative distribution function.

        Sum of the terms 0 through `floor(k)` of the Binomial probability density.

        .. math::
            \mathrm{bdtr}(k, n, p) =
            \sum_{j=0}^{\lfloor k \rfloor} {{n}\choose{j}} p^j (1-p)^{n-j}

        Parameters
        ----------
        k : array_like
            Number of successes (double), rounded down to the nearest integer.
        n : array_like
            Number of events (int).
        p : array_like
            Probability of success in a single event (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            Probability of `floor(k)` or fewer successes in `n` independent events with
            success probabilities of `p`.

        Notes
        -----
        The terms are not summed directly; instead the regularized incomplete beta
        function is employed, according to the formula,

        .. math::
            \mathrm{bdtr}(k, n, p) =
            I_{1 - p}(n - \lfloor k \rfloor, \lfloor k \rfloor + 1).

        Wrapper for the Cephes [1]_ routine `bdtr`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    bdtrc = <ufunc 'bdtrc'>
        bdtrc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        bdtrc(k, n, p, out=None)

        Binomial distribution survival function.

        Sum of the terms `floor(k) + 1` through `n` of the binomial probability
        density,

        .. math::
            \mathrm{bdtrc}(k, n, p) =
            \sum_{j=\lfloor k \rfloor +1}^n {{n}\choose{j}} p^j (1-p)^{n-j}

        Parameters
        ----------
        k : array_like
            Number of successes (double), rounded down to nearest integer.
        n : array_like
            Number of events (int)
        p : array_like
            Probability of success in a single event.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            Probability of `floor(k) + 1` or more successes in `n` independent
            events with success probabilities of `p`.

        See Also
        --------
        bdtr
        betainc

        Notes
        -----
        The terms are not summed directly; instead the regularized incomplete beta
        function is employed, according to the formula,

        .. math::
            \mathrm{bdtrc}(k, n, p) = I_{p}(\lfloor k \rfloor + 1, n - \lfloor k \rfloor).

        Wrapper for the Cephes [1]_ routine `bdtrc`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    bdtri = <ufunc 'bdtri'>
        bdtri(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        bdtri(k, n, y, out=None)

        Inverse function to `bdtr` with respect to `p`.

        Finds the event probability `p` such that the sum of the terms 0 through
        `k` of the binomial probability density is equal to the given cumulative
        probability `y`.

        Parameters
        ----------
        k : array_like
            Number of successes (float), rounded down to the nearest integer.
        n : array_like
            Number of events (float)
        y : array_like
            Cumulative probability (probability of `k` or fewer successes in `n`
            events).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        p : scalar or ndarray
            The event probability such that `bdtr(\lfloor k \rfloor, n, p) = y`.

        See Also
        --------
        bdtr
        betaincinv

        Notes
        -----
        The computation is carried out using the inverse beta integral function
        and the relation,::

            1 - p = betaincinv(n - k, k + 1, y).

        Wrapper for the Cephes [1]_ routine `bdtri`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    bdtrik = <ufunc 'bdtrik'>
        bdtrik(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        bdtrik(y, n, p, out=None)

        Inverse function to `bdtr` with respect to `k`.

        Finds the number of successes `k` such that the sum of the terms 0 through
        `k` of the Binomial probability density for `n` events with probability
        `p` is equal to the given cumulative probability `y`.

        Parameters
        ----------
        y : array_like
            Cumulative probability (probability of `k` or fewer successes in `n`
            events).
        n : array_like
            Number of events (float).
        p : array_like
            Success probability (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        k : scalar or ndarray
            The number of successes `k` such that `bdtr(k, n, p) = y`.

        See Also
        --------
        bdtr

        Notes
        -----
        Formula 26.5.24 of [1]_ is used to reduce the binomial distribution to the
        cumulative incomplete beta distribution.

        Computation of `k` involves a search for a value that produces the desired
        value of `y`. The search relies on the monotonicity of `y` with `k`.

        Wrapper for the CDFLIB [2]_ Fortran routine `cdfbin`.

        References
        ----------
        .. [1] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [2] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.

    bdtrin = <ufunc 'bdtrin'>
        bdtrin(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        bdtrin(k, y, p, out=None)

        Inverse function to `bdtr` with respect to `n`.

        Finds the number of events `n` such that the sum of the terms 0 through
        `k` of the Binomial probability density for events with probability `p` is
        equal to the given cumulative probability `y`.

        Parameters
        ----------
        k : array_like
            Number of successes (float).
        y : array_like
            Cumulative probability (probability of `k` or fewer successes in `n`
            events).
        p : array_like
            Success probability (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        n : scalar or ndarray
            The number of events `n` such that `bdtr(k, n, p) = y`.

        See Also
        --------
        bdtr

        Notes
        -----
        Formula 26.5.24 of [1]_ is used to reduce the binomial distribution to the
        cumulative incomplete beta distribution.

        Computation of `n` involves a search for a value that produces the desired
        value of `y`. The search relies on the monotonicity of `y` with `n`.

        Wrapper for the CDFLIB [2]_ Fortran routine `cdfbin`.

        References
        ----------
        .. [1] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [2] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.

    bei = <ufunc 'bei'>
        bei(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        bei(x, out=None)

        Kelvin function bei.

        Defined as

        .. math::

            \mathrm{bei}(x) = \Im[J_0(x e^{3 \pi i / 4})]

        where :math:`J_0` is the Bessel function of the first kind of
        order zero (see `jv`). See [dlmf]_ for more details.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the Kelvin function.

        See Also
        --------
        ber : the corresponding real part
        beip : the derivative of bei
        jv : Bessel function of the first kind

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10.61

        Examples
        --------
        It can be expressed using Bessel functions.

        >>> import numpy as np
        >>> import scipy.special as sc
        >>> x = np.array([1.0, 2.0, 3.0, 4.0])
        >>> sc.jv(0, x * np.exp(3 * np.pi * 1j / 4)).imag
        array([0.24956604, 0.97229163, 1.93758679, 2.29269032])
        >>> sc.bei(x)
        array([0.24956604, 0.97229163, 1.93758679, 2.29269032])

    beip = <ufunc 'beip'>
        beip(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        beip(x, out=None)

        Derivative of the Kelvin function bei.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            The values of the derivative of bei.

        See Also
        --------
        bei

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10#PT5

    ber = <ufunc 'ber'>
        ber(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        ber(x, out=None)

        Kelvin function ber.

        Defined as

        .. math::

            \mathrm{ber}(x) = \Re[J_0(x e^{3 \pi i / 4})]

        where :math:`J_0` is the Bessel function of the first kind of
        order zero (see `jv`). See [dlmf]_ for more details.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the Kelvin function.

        See Also
        --------
        bei : the corresponding real part
        berp : the derivative of bei
        jv : Bessel function of the first kind

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10.61

        Examples
        --------
        It can be expressed using Bessel functions.

        >>> import numpy as np
        >>> import scipy.special as sc
        >>> x = np.array([1.0, 2.0, 3.0, 4.0])
        >>> sc.jv(0, x * np.exp(3 * np.pi * 1j / 4)).real
        array([ 0.98438178,  0.75173418, -0.22138025, -2.56341656])
        >>> sc.ber(x)
        array([ 0.98438178,  0.75173418, -0.22138025, -2.56341656])

    berp = <ufunc 'berp'>
        berp(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        berp(x, out=None)

        Derivative of the Kelvin function ber.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            The values of the derivative of ber.

        See Also
        --------
        ber

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10#PT5

    besselpoly = <ufunc 'besselpoly'>
        besselpoly(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        besselpoly(a, lmb, nu, out=None)

        Weighted integral of the Bessel function of the first kind.

        Computes

        .. math::

           \int_0^1 x^\lambda J_\nu(2 a x) \, dx

        where :math:`J_\nu` is a Bessel function and :math:`\lambda=lmb`,
        :math:`\nu=nu`.

        Parameters
        ----------
        a : array_like
            Scale factor inside the Bessel function.
        lmb : array_like
            Power of `x`
        nu : array_like
            Order of the Bessel function.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Value of the integral.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Evaluate the function for one parameter set.

        >>> from scipy.special import besselpoly
        >>> besselpoly(1, 1, 1)
        0.24449718372863877

        Evaluate the function for different scale factors.

        >>> import numpy as np
        >>> factors = np.array([0., 3., 6.])
        >>> besselpoly(factors, 1, 1)
        array([ 0.        , -0.00549029,  0.00140174])

        Plot the function for varying powers, orders and scales.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> powers = np.linspace(0, 10, 100)
        >>> orders = [1, 2, 3]
        >>> scales = [1, 2]
        >>> all_combinations = [(order, scale) for order in orders
        ...                     for scale in scales]
        >>> for order, scale in all_combinations:
        ...     ax.plot(powers, besselpoly(scale, powers, order),
        ...             label=rf"$\nu={order}, a={scale}$")
        >>> ax.legend()
        >>> ax.set_xlabel(r"$\lambda$")
        >>> ax.set_ylabel(r"$\int_0^1 x^{\lambda} J_{\nu}(2ax)\,dx$")
        >>> plt.show()

    beta = <ufunc 'beta'>
        beta(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        beta(a, b, out=None)

        Beta function.

        This function is defined in [1]_ as

        .. math::

            B(a, b) = \int_0^1 t^{a-1}(1-t)^{b-1}dt
                    = \frac{\Gamma(a)\Gamma(b)}{\Gamma(a+b)},

        where :math:`\Gamma` is the gamma function.

        Parameters
        ----------
        a, b : array_like
            Real-valued arguments
        out : ndarray, optional
            Optional output array for the function result

        Returns
        -------
        scalar or ndarray
            Value of the beta function

        See Also
        --------
        gamma : the gamma function
        betainc :  the regularized incomplete beta function
        betaln : the natural logarithm of the absolute
                 value of the beta function

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions,
               Eq. 5.12.1. https://dlmf.nist.gov/5.12

        Examples
        --------
        >>> import scipy.special as sc

        The beta function relates to the gamma function by the
        definition given above:

        >>> sc.beta(2, 3)
        0.08333333333333333
        >>> sc.gamma(2)*sc.gamma(3)/sc.gamma(2 + 3)
        0.08333333333333333

        As this relationship demonstrates, the beta function
        is symmetric:

        >>> sc.beta(1.7, 2.4)
        0.16567527689031739
        >>> sc.beta(2.4, 1.7)
        0.16567527689031739

        This function satisfies :math:`B(1, b) = 1/b`:

        >>> sc.beta(1, 4)
        0.25

    betainc = <ufunc 'betainc'>
        betainc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        betainc(a, b, x, out=None)

        Regularized incomplete beta function.

        Computes the regularized incomplete beta function, defined as [1]_:

        .. math::

            I_x(a, b) = \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)} \int_0^x
            t^{a-1}(1-t)^{b-1}dt,

        for :math:`0 \leq x \leq 1`.

        This function is the cumulative distribution function for the beta
        distribution; its range is [0, 1].

        Parameters
        ----------
        a, b : array_like
               Positive, real-valued parameters
        x : array_like
            Real-valued such that :math:`0 \leq x \leq 1`,
            the upper limit of integration
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Value of the regularized incomplete beta function

        See Also
        --------
        beta : beta function
        betaincinv : inverse of the regularized incomplete beta function
        betaincc : complement of the regularized incomplete beta function
        scipy.stats.beta : beta distribution

        Notes
        -----
        The term *regularized* in the name of this function refers to the
        scaling of the function by the gamma function terms shown in the
        formula.  When not qualified as *regularized*, the name *incomplete
        beta function* often refers to just the integral expression,
        without the gamma terms.  One can use the function `beta` from
        `scipy.special` to get this "nonregularized" incomplete beta
        function by multiplying the result of ``betainc(a, b, x)`` by
        ``beta(a, b)``.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/8.17

        Examples
        --------

        Let :math:`B(a, b)` be the `beta` function.

        >>> import scipy.special as sc

        The coefficient in terms of `gamma` is equal to
        :math:`1/B(a, b)`. Also, when :math:`x=1`
        the integral is equal to :math:`B(a, b)`.
        Therefore, :math:`I_{x=1}(a, b) = 1` for any :math:`a, b`.

        >>> sc.betainc(0.2, 3.5, 1.0)
        1.0

        It satisfies
        :math:`I_x(a, b) = x^a F(a, 1-b, a+1, x)/ (aB(a, b))`,
        where :math:`F` is the hypergeometric function `hyp2f1`:

        >>> a, b, x = 1.4, 3.1, 0.5
        >>> x**a * sc.hyp2f1(a, 1 - b, a + 1, x)/(a * sc.beta(a, b))
        0.8148904036225295
        >>> sc.betainc(a, b, x)
        0.8148904036225296

        This functions satisfies the relationship
        :math:`I_x(a, b) = 1 - I_{1-x}(b, a)`:

        >>> sc.betainc(2.2, 3.1, 0.4)
        0.49339638807619446
        >>> 1 - sc.betainc(3.1, 2.2, 1 - 0.4)
        0.49339638807619446

    betaincc = <ufunc 'betaincc'>
        betaincc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        betaincc(a, b, x, out=None)

        Complement of the regularized incomplete beta function.

        Computes the complement of the regularized incomplete beta function,
        defined as [1]_:

        .. math::

            \bar{I}_x(a, b) = 1 - I_x(a, b)
                            = 1 - \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)} \int_0^x
                                      t^{a-1}(1-t)^{b-1}dt,

        for :math:`0 \leq x \leq 1`.

        Parameters
        ----------
        a, b : array_like
               Positive, real-valued parameters
        x : array_like
            Real-valued such that :math:`0 \leq x \leq 1`,
            the upper limit of integration
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Value of the regularized incomplete beta function

        See Also
        --------
        betainc : regularized incomplete beta function
        betaincinv : inverse of the regularized incomplete beta function
        betainccinv :
            inverse of the complement of the regularized incomplete beta function
        beta : beta function
        scipy.stats.beta : beta distribution

        Notes
        -----
        .. versionadded:: 1.11.0

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/8.17

        Examples
        --------
        >>> from scipy.special import betaincc, betainc

        The naive calculation ``1 - betainc(a, b, x)`` loses precision when
        the values of ``betainc(a, b, x)`` are close to 1:

        >>> 1 - betainc(0.5, 8, [0.9, 0.99, 0.999])
        array([2.0574632e-09, 0.0000000e+00, 0.0000000e+00])

        By using ``betaincc``, we get the correct values:

        >>> betaincc(0.5, 8, [0.9, 0.99, 0.999])
        array([2.05746321e-09, 1.97259354e-17, 1.96467954e-25])

    betainccinv = <ufunc 'betainccinv'>
        betainccinv(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        betainccinv(a, b, y, out=None)

        Inverse of the complemented regularized incomplete beta function.

        Computes :math:`x` such that:

        .. math::

            y = 1 - I_x(a, b) = 1 - \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)}
            \int_0^x t^{a-1}(1-t)^{b-1}dt,

        where :math:`I_x` is the normalized incomplete beta function `betainc`
        and :math:`\Gamma` is the `gamma` function [1]_.

        Parameters
        ----------
        a, b : array_like
            Positive, real-valued parameters
        y : array_like
            Real-valued input
        out : ndarray, optional
            Optional output array for function values

        Returns
        -------
        scalar or ndarray
            Value of the inverse of the regularized incomplete beta function

        See Also
        --------
        betainc : regularized incomplete beta function
        betaincc : complement of the regularized incomplete beta function

        Notes
        -----
        .. versionadded:: 1.11.0

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/8.17

        Examples
        --------
        >>> from scipy.special import betainccinv, betaincc

        This function is the inverse of `betaincc` for fixed
        values of :math:`a` and :math:`b`.

        >>> a, b = 1.2, 3.1
        >>> y = betaincc(a, b, 0.2)
        >>> betainccinv(a, b, y)
        0.2

        >>> a, b = 7, 2.5
        >>> x = betainccinv(a, b, 0.875)
        >>> betaincc(a, b, x)
        0.875

    betaincinv = <ufunc 'betaincinv'>
        betaincinv(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        betaincinv(a, b, y, out=None)

        Inverse of the regularized incomplete beta function.

        Computes :math:`x` such that:

        .. math::

            y = I_x(a, b) = \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)}
            \int_0^x t^{a-1}(1-t)^{b-1}dt,

        where :math:`I_x` is the normalized incomplete beta function `betainc`
        and :math:`\Gamma` is the `gamma` function [1]_.

        Parameters
        ----------
        a, b : array_like
            Positive, real-valued parameters
        y : array_like
            Real-valued input
        out : ndarray, optional
            Optional output array for function values

        Returns
        -------
        scalar or ndarray
            Value of the inverse of the regularized incomplete beta function

        See Also
        --------
        betainc : regularized incomplete beta function
        gamma : gamma function

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/8.17

        Examples
        --------
        >>> import scipy.special as sc

        This function is the inverse of `betainc` for fixed
        values of :math:`a` and :math:`b`.

        >>> a, b = 1.2, 3.1
        >>> y = sc.betainc(a, b, 0.2)
        >>> sc.betaincinv(a, b, y)
        0.2
        >>>
        >>> a, b = 7.5, 0.4
        >>> x = sc.betaincinv(a, b, 0.5)
        >>> sc.betainc(a, b, x)
        0.5

    betaln = <ufunc 'betaln'>
        betaln(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        betaln(a, b, out=None)

        Natural logarithm of absolute value of beta function.

        Computes ``ln(abs(beta(a, b)))``.

        Parameters
        ----------
        a, b : array_like
            Positive, real-valued parameters
        out : ndarray, optional
            Optional output array for function values

        Returns
        -------
        scalar or ndarray
            Value of the betaln function

        See Also
        --------
        gamma : the gamma function
        betainc :  the regularized incomplete beta function
        beta : the beta function

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import betaln, beta

        Verify that, for moderate values of ``a`` and ``b``, ``betaln(a, b)``
        is the same as ``log(beta(a, b))``:

        >>> betaln(3, 4)
        -4.0943445622221

        >>> np.log(beta(3, 4))
        -4.0943445622221

        In the following ``beta(a, b)`` underflows to 0, so we can't compute
        the logarithm of the actual value.

        >>> a = 400
        >>> b = 900
        >>> beta(a, b)
        0.0

        We can compute the logarithm of ``beta(a, b)`` by using `betaln`:

        >>> betaln(a, b)
        -804.3069951764146

    binom = <ufunc 'binom'>
        binom(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        binom(x, y, out=None)

        Binomial coefficient considered as a function of two real variables.

        For real arguments, the binomial coefficient is defined as

        .. math::

            \binom{x}{y} = \frac{\Gamma(x + 1)}{\Gamma(y + 1)\Gamma(x - y + 1)} =
                \frac{1}{(x + 1)\mathrm{B}(x - y + 1, y + 1)}

        Where :math:`\Gamma` is the Gamma function (`gamma`) and :math:`\mathrm{B}`
        is the Beta function (`beta`) [1]_.

        Parameters
        ----------
        x, y: array_like
           Real arguments to :math:`\binom{x}{y}`.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Value of binomial coefficient.

        See Also
        --------
        comb : The number of combinations of N things taken k at a time.

        Notes
        -----
        The Gamma function has poles at non-positive integers and tends to either
        positive or negative infinity depending on the direction on the real line
        from which a pole is approached. When considered as a function of two real
        variables, :math:`\binom{x}{y}` is thus undefined when `x` is a negative
        integer.  `binom` returns ``nan`` when ``x`` is a negative integer. This
        is the case even when ``x`` is a negative integer and ``y`` an integer,
        contrary to the usual convention for defining :math:`\binom{n}{k}` when it
        is considered as a function of two integer variables.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Binomial_coefficient

        Examples
        --------
        The following examples illustrate the ways in which `binom` differs from
        the function `comb`.

        >>> from scipy.special import binom, comb

        When ``exact=False`` and ``x`` and ``y`` are both positive, `comb` calls
        `binom` internally.

        >>> x, y = 3, 2
        >>> (binom(x, y), comb(x, y), comb(x, y, exact=True))
        (3.0, 3.0, 3)

        For larger values, `comb` with ``exact=True`` no longer agrees
        with `binom`.

        >>> x, y = 43, 23
        >>> (binom(x, y), comb(x, y), comb(x, y, exact=True))
        (960566918219.9999, 960566918219.9999, 960566918220)

        `binom` returns ``nan`` when ``x`` is a negative integer, but is otherwise
        defined for negative arguments. `comb` returns 0 whenever one of ``x`` or
        ``y`` is negative or ``x`` is less than ``y``.

        >>> x, y = -3, 2
        >>> (binom(x, y), comb(x, y))
        (nan, 0.0)

        >>> x, y = -3.1, 2.2
        >>> (binom(x, y), comb(x, y))
        (18.714147876804432, 0.0)

        >>> x, y = 2.2, 3.1
        >>> (binom(x, y), comb(x, y))
        (0.037399983365134115, 0.0)

    boxcox = <ufunc 'boxcox'>
        boxcox(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        boxcox(x, lmbda, out=None)

        Compute the Box-Cox transformation.

        The Box-Cox transformation is::

            y = (x**lmbda - 1) / lmbda  if lmbda != 0
                log(x)                  if lmbda == 0

        Returns `nan` if ``x < 0``.
        Returns `-inf` if ``x == 0`` and ``lmbda < 0``.

        Parameters
        ----------
        x : array_like
            Data to be transformed.
        lmbda : array_like
            Power parameter of the Box-Cox transform.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            Transformed data.

        Notes
        -----

        .. versionadded:: 0.14.0

        Examples
        --------
        >>> from scipy.special import boxcox
        >>> boxcox([1, 4, 10], 2.5)
        array([   0.        ,   12.4       ,  126.09110641])
        >>> boxcox(2, [0, 1, 2])
        array([ 0.69314718,  1.        ,  1.5       ])

    boxcox1p = <ufunc 'boxcox1p'>
        boxcox1p(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        boxcox1p(x, lmbda, out=None)

        Compute the Box-Cox transformation of 1 + `x`.

        The Box-Cox transformation computed by `boxcox1p` is::

            y = ((1+x)**lmbda - 1) / lmbda  if lmbda != 0
                log(1+x)                    if lmbda == 0

        Returns `nan` if ``x < -1``.
        Returns `-inf` if ``x == -1`` and ``lmbda < 0``.

        Parameters
        ----------
        x : array_like
            Data to be transformed.
        lmbda : array_like
            Power parameter of the Box-Cox transform.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            Transformed data.

        Notes
        -----

        .. versionadded:: 0.14.0

        Examples
        --------
        >>> from scipy.special import boxcox1p
        >>> boxcox1p(1e-4, [0, 0.5, 1])
        array([  9.99950003e-05,   9.99975001e-05,   1.00000000e-04])
        >>> boxcox1p([0.01, 0.1], 0.25)
        array([ 0.00996272,  0.09645476])

    btdtria = <ufunc 'btdtria'>
        btdtria(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        btdtria(p, b, x, out=None)

        Inverse of `btdtr` with respect to `a`.

        This is the inverse of the beta cumulative distribution function, `btdtr`,
        considered as a function of `a`, returning the value of `a` for which
        `btdtr(a, b, x) = p`, or

        .. math::
            p = \int_0^x \frac{\Gamma(a + b)}{\Gamma(a)\Gamma(b)} t^{a-1} (1-t)^{b-1}\,dt

        Parameters
        ----------
        p : array_like
            Cumulative probability, in [0, 1].
        b : array_like
            Shape parameter (`b` > 0).
        x : array_like
            The quantile, in [0, 1].
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        a : scalar or ndarray
            The value of the shape parameter `a` such that `btdtr(a, b, x) = p`.

        See Also
        --------
        btdtr : Cumulative distribution function of the beta distribution.
        btdtri : Inverse with respect to `x`.
        btdtrib : Inverse with respect to `b`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfbet`.

        The cumulative distribution function `p` is computed using a routine by
        DiDinato and Morris [2]_. Computation of `a` involves a search for a value
        that produces the desired value of `p`. The search relies on the
        monotonicity of `p` with `a`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] DiDinato, A. R. and Morris, A. H.,
               Algorithm 708: Significant Digit Computation of the Incomplete Beta
               Function Ratios. ACM Trans. Math. Softw. 18 (1993), 360-373.

    btdtrib = <ufunc 'btdtrib'>
        btdtrib(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        btdtria(a, p, x, out=None)

        Inverse of `btdtr` with respect to `b`.

        This is the inverse of the beta cumulative distribution function, `btdtr`,
        considered as a function of `b`, returning the value of `b` for which
        `btdtr(a, b, x) = p`, or

        .. math::
            p = \int_0^x \frac{\Gamma(a + b)}{\Gamma(a)\Gamma(b)} t^{a-1} (1-t)^{b-1}\,dt

        Parameters
        ----------
        a : array_like
            Shape parameter (`a` > 0).
        p : array_like
            Cumulative probability, in [0, 1].
        x : array_like
            The quantile, in [0, 1].
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        b : scalar or ndarray
            The value of the shape parameter `b` such that `btdtr(a, b, x) = p`.

        See Also
        --------
        btdtr : Cumulative distribution function of the beta distribution.
        btdtri : Inverse with respect to `x`.
        btdtria : Inverse with respect to `a`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfbet`.

        The cumulative distribution function `p` is computed using a routine by
        DiDinato and Morris [2]_. Computation of `b` involves a search for a value
        that produces the desired value of `p`. The search relies on the
        monotonicity of `p` with `b`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] DiDinato, A. R. and Morris, A. H.,
               Algorithm 708: Significant Digit Computation of the Incomplete Beta
               Function Ratios. ACM Trans. Math. Softw. 18 (1993), 360-373.

    cbrt = <ufunc 'cbrt'>
        cbrt(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        cbrt(x, out=None)

        Element-wise cube root of `x`.

        Parameters
        ----------
        x : array_like
            `x` must contain real numbers.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            The cube root of each value in `x`.

        Examples
        --------
        >>> from scipy.special import cbrt

        >>> cbrt(8)
        2.0
        >>> cbrt([-8, -3, 0.125, 1.331])
        array([-2.        , -1.44224957,  0.5       ,  1.1       ])

    chdtr = <ufunc 'chdtr'>
        chdtr(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chdtr(v, x, out=None)

        Chi square cumulative distribution function.

        Returns the area under the left tail (from 0 to `x`) of the Chi
        square probability density function with `v` degrees of freedom:

        .. math::

            \frac{1}{2^{v/2} \Gamma(v/2)} \int_0^x t^{v/2 - 1} e^{-t/2} dt

        Here :math:`\Gamma` is the Gamma function; see `gamma`. This
        integral can be expressed in terms of the regularized lower
        incomplete gamma function `gammainc` as
        ``gammainc(v / 2, x / 2)``. [1]_

        Parameters
        ----------
        v : array_like
            Degrees of freedom.
        x : array_like
            Upper bound of the integral.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the cumulative distribution function.

        See Also
        --------
        chdtrc, chdtri, chdtriv, gammainc

        References
        ----------
        .. [1] Chi-Square distribution,
            https://www.itl.nist.gov/div898/handbook/eda/section3/eda3666.htm

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It can be expressed in terms of the regularized lower incomplete
        gamma function.

        >>> v = 1
        >>> x = np.arange(4)
        >>> sc.chdtr(v, x)
        array([0.        , 0.68268949, 0.84270079, 0.91673548])
        >>> sc.gammainc(v / 2, x / 2)
        array([0.        , 0.68268949, 0.84270079, 0.91673548])

    chdtrc = <ufunc 'chdtrc'>
        chdtrc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chdtrc(v, x, out=None)

        Chi square survival function.

        Returns the area under the right hand tail (from `x` to infinity)
        of the Chi square probability density function with `v` degrees of
        freedom:

        .. math::

            \frac{1}{2^{v/2} \Gamma(v/2)} \int_x^\infty t^{v/2 - 1} e^{-t/2} dt

        Here :math:`\Gamma` is the Gamma function; see `gamma`. This
        integral can be expressed in terms of the regularized upper
        incomplete gamma function `gammaincc` as
        ``gammaincc(v / 2, x / 2)``. [1]_

        Parameters
        ----------
        v : array_like
            Degrees of freedom.
        x : array_like
            Lower bound of the integral.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the survival function.

        See Also
        --------
        chdtr, chdtri, chdtriv, gammaincc

        References
        ----------
        .. [1] Chi-Square distribution,
            https://www.itl.nist.gov/div898/handbook/eda/section3/eda3666.htm

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It can be expressed in terms of the regularized upper incomplete
        gamma function.

        >>> v = 1
        >>> x = np.arange(4)
        >>> sc.chdtrc(v, x)
        array([1.        , 0.31731051, 0.15729921, 0.08326452])
        >>> sc.gammaincc(v / 2, x / 2)
        array([1.        , 0.31731051, 0.15729921, 0.08326452])

    chdtri = <ufunc 'chdtri'>
        chdtri(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chdtri(v, p, out=None)

        Inverse to `chdtrc` with respect to `x`.

        Returns `x` such that ``chdtrc(v, x) == p``.

        Parameters
        ----------
        v : array_like
            Degrees of freedom.
        p : array_like
            Probability.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        x : scalar or ndarray
            Value so that the probability a Chi square random variable
            with `v` degrees of freedom is greater than `x` equals `p`.

        See Also
        --------
        chdtrc, chdtr, chdtriv

        References
        ----------
        .. [1] Chi-Square distribution,
            https://www.itl.nist.gov/div898/handbook/eda/section3/eda3666.htm

        Examples
        --------
        >>> import scipy.special as sc

        It inverts `chdtrc`.

        >>> v, p = 1, 0.3
        >>> sc.chdtrc(v, sc.chdtri(v, p))
        0.3
        >>> x = 1
        >>> sc.chdtri(v, sc.chdtrc(v, x))
        1.0

    chdtriv = <ufunc 'chdtriv'>
        chdtriv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chdtriv(p, x, out=None)

        Inverse to `chdtr` with respect to `v`.

        Returns `v` such that ``chdtr(v, x) == p``.

        Parameters
        ----------
        p : array_like
            Probability that the Chi square random variable is less than
            or equal to `x`.
        x : array_like
            Nonnegative input.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Degrees of freedom.

        See Also
        --------
        chdtr, chdtrc, chdtri

        References
        ----------
        .. [1] Chi-Square distribution,
            https://www.itl.nist.gov/div898/handbook/eda/section3/eda3666.htm

        Examples
        --------
        >>> import scipy.special as sc

        It inverts `chdtr`.

        >>> p, x = 0.5, 1
        >>> sc.chdtr(sc.chdtriv(p, x), x)
        0.5000000000202172
        >>> v = 1
        >>> sc.chdtriv(sc.chdtr(v, x), v)
        1.0000000000000013

    chndtr = <ufunc 'chndtr'>
        chndtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chndtr(x, df, nc, out=None)

        Non-central chi square cumulative distribution function

        The cumulative distribution function is given by:

        .. math::

            P(\chi^{\prime 2} \vert \nu, \lambda) =\sum_{j=0}^{\infty}
            e^{-\lambda /2}
            \frac{(\lambda /2)^j}{j!} P(\chi^{\prime 2} \vert \nu + 2j),

        where :math:`\nu > 0` is the degrees of freedom (``df``) and
        :math:`\lambda \geq 0` is the non-centrality parameter (``nc``).

        Parameters
        ----------
        x : array_like
            Upper bound of the integral; must satisfy ``x >= 0``
        df : array_like
            Degrees of freedom; must satisfy ``df > 0``
        nc : array_like
            Non-centrality parameter; must satisfy ``nc >= 0``
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        x : scalar or ndarray
            Value of the non-central chi square cumulative distribution function.

        See Also
        --------
        chndtrix, chndtridf, chndtrinc

    chndtridf = <ufunc 'chndtridf'>
        chndtridf(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chndtridf(x, p, nc, out=None)

        Inverse to `chndtr` vs `df`

        Calculated using a search to find a value for `df` that produces the
        desired value of `p`.

        Parameters
        ----------
        x : array_like
            Upper bound of the integral; must satisfy ``x >= 0``
        p : array_like
            Probability; must satisfy ``0 <= p < 1``
        nc : array_like
            Non-centrality parameter; must satisfy ``nc >= 0``
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        df : scalar or ndarray
            Degrees of freedom

        See Also
        --------
        chndtr, chndtrix, chndtrinc

    chndtrinc = <ufunc 'chndtrinc'>
        chndtrinc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chndtrinc(x, df, p, out=None)

        Inverse to `chndtr` vs `nc`

        Calculated using a search to find a value for `df` that produces the
        desired value of `p`.

        Parameters
        ----------
        x : array_like
            Upper bound of the integral; must satisfy ``x >= 0``
        df : array_like
            Degrees of freedom; must satisfy ``df > 0``
        p : array_like
            Probability; must satisfy ``0 <= p < 1``
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        nc : scalar or ndarray
            Non-centrality

        See Also
        --------
        chndtr, chndtrix, chndtrinc

    chndtrix = <ufunc 'chndtrix'>
        chndtrix(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        chndtrix(p, df, nc, out=None)

        Inverse to `chndtr` vs `x`

        Calculated using a search to find a value for `x` that produces the
        desired value of `p`.

        Parameters
        ----------
        p : array_like
            Probability; must satisfy ``0 <= p < 1``
        df : array_like
            Degrees of freedom; must satisfy ``df > 0``
        nc : array_like
            Non-centrality parameter; must satisfy ``nc >= 0``
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        x : scalar or ndarray
            Value so that the probability a non-central Chi square random variable
            with `df` degrees of freedom and non-centrality, `nc`, is greater than
            `x` equals `p`.

        See Also
        --------
        chndtr, chndtridf, chndtrinc

    cosdg = <ufunc 'cosdg'>
        cosdg(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        cosdg(x, out=None)

        Cosine of the angle `x` given in degrees.

        Parameters
        ----------
        x : array_like
            Angle, given in degrees.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Cosine of the input.

        See Also
        --------
        sindg, tandg, cotdg

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than using cosine directly.

        >>> x = 90 + 180 * np.arange(3)
        >>> sc.cosdg(x)
        array([-0.,  0., -0.])
        >>> np.cos(x * np.pi / 180)
        array([ 6.1232340e-17, -1.8369702e-16,  3.0616170e-16])

    cosm1 = <ufunc 'cosm1'>
        cosm1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        cosm1(x, out=None)

        cos(x) - 1 for use when `x` is near zero.

        Parameters
        ----------
        x : array_like
            Real valued argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of ``cos(x) - 1``.

        See Also
        --------
        expm1, log1p

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than computing ``cos(x) - 1`` directly for
        ``x`` around 0.

        >>> x = 1e-30
        >>> np.cos(x) - 1
        0.0
        >>> sc.cosm1(x)
        -5.0000000000000005e-61

    cotdg = <ufunc 'cotdg'>
        cotdg(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        cotdg(x, out=None)

        Cotangent of the angle `x` given in degrees.

        Parameters
        ----------
        x : array_like
            Angle, given in degrees.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Cotangent at the input.

        See Also
        --------
        sindg, cosdg, tandg

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than using cotangent directly.

        >>> x = 90 + 180 * np.arange(3)
        >>> sc.cotdg(x)
        array([0., 0., 0.])
        >>> 1 / np.tan(x * np.pi / 180)
        array([6.1232340e-17, 1.8369702e-16, 3.0616170e-16])

    dawsn = <ufunc 'dawsn'>
        dawsn(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        dawsn(x, out=None)

        Dawson's integral.

        Computes::

            exp(-x**2) * integral(exp(t**2), t=0..x).

        Parameters
        ----------
        x : array_like
            Function parameter.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            Value of the integral.

        See Also
        --------
        wofz, erf, erfc, erfcx, erfi

        References
        ----------
        .. [1] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-15, 15, num=1000)
        >>> plt.plot(x, special.dawsn(x))
        >>> plt.xlabel('$x$')
        >>> plt.ylabel('$dawsn(x)$')
        >>> plt.show()

    digamma = <ufunc 'psi'>
        psi(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        psi(z, out=None)

        The digamma function.

        The logarithmic derivative of the gamma function evaluated at ``z``.

        Parameters
        ----------
        z : array_like
            Real or complex argument.
        out : ndarray, optional
            Array for the computed values of ``psi``.

        Returns
        -------
        digamma : scalar or ndarray
            Computed values of ``psi``.

        Notes
        -----
        For large values not close to the negative real axis, ``psi`` is
        computed using the asymptotic series (5.11.2) from [1]_. For small
        arguments not close to the negative real axis, the recurrence
        relation (5.5.2) from [1]_ is used until the argument is large
        enough to use the asymptotic series. For values close to the
        negative real axis, the reflection formula (5.5.4) from [1]_ is
        used first. Note that ``psi`` has a family of zeros on the
        negative real axis which occur between the poles at nonpositive
        integers. Around the zeros the reflection formula suffers from
        cancellation and the implementation loses precision. The sole
        positive zero and the first negative zero, however, are handled
        separately by precomputing series expansions using [2]_, so the
        function should maintain full accuracy around the origin.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/5
        .. [2] Fredrik Johansson and others.
               "mpmath: a Python library for arbitrary-precision floating-point arithmetic"
               (Version 0.19) http://mpmath.org/

        Examples
        --------
        >>> from scipy.special import psi
        >>> z = 3 + 4j
        >>> psi(z)
        (1.55035981733341+1.0105022091860445j)

        Verify psi(z) = psi(z + 1) - 1/z:

        >>> psi(z + 1) - 1/z
        (1.55035981733341+1.0105022091860445j)

    ellipe = <ufunc 'ellipe'>
        ellipe(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipe(m, out=None)

        Complete elliptic integral of the second kind

        This function is defined as

        .. math:: E(m) = \int_0^{\pi/2} [1 - m \sin(t)^2]^{1/2} dt

        Parameters
        ----------
        m : array_like
            Defines the parameter of the elliptic integral.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        E : scalar or ndarray
            Value of the elliptic integral.

        See Also
        --------
        ellipkm1 : Complete elliptic integral of the first kind, near `m` = 1
        ellipk : Complete elliptic integral of the first kind
        ellipkinc : Incomplete elliptic integral of the first kind
        ellipeinc : Incomplete elliptic integral of the second kind
        elliprd : Symmetric elliptic integral of the second kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `ellpe`.

        For `m > 0` the computation uses the approximation,

        .. math:: E(m) \approx P(1-m) - (1-m) \log(1-m) Q(1-m),

        where :math:`P` and :math:`Q` are tenth-order polynomials.  For
        `m < 0`, the relation

        .. math:: E(m) = E(m/(m - 1)) \sqrt(1-m)

        is used.

        The parameterization in terms of :math:`m` follows that of section
        17.2 in [2]_. Other parameterizations in terms of the
        complementary parameter :math:`1 - m`, modular angle
        :math:`\sin^2(\alpha) = m`, or modulus :math:`k^2 = m` are also
        used, so be careful that you choose the correct parameter.

        The Legendre E integral is related to Carlson's symmetric R_D or R_G
        functions in multiple ways [3]_. For example,

        .. math:: E(m) = 2 R_G(0, 1-k^2, 1) .

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [3] NIST Digital Library of Mathematical
               Functions. http://dlmf.nist.gov/, Release 1.0.28 of
               2020-09-15. See Sec. 19.25(i) https://dlmf.nist.gov/19.25#i

        Examples
        --------
        This function is used in finding the circumference of an
        ellipse with semi-major axis `a` and semi-minor axis `b`.

        >>> import numpy as np
        >>> from scipy import special

        >>> a = 3.5
        >>> b = 2.1
        >>> e_sq = 1.0 - b**2/a**2  # eccentricity squared

        Then the circumference is found using the following:

        >>> C = 4*a*special.ellipe(e_sq)  # circumference formula
        >>> C
        17.868899204378693

        When `a` and `b` are the same (meaning eccentricity is 0),
        this reduces to the circumference of a circle.

        >>> 4*a*special.ellipe(0.0)  # formula for ellipse with a = b
        21.991148575128552
        >>> 2*np.pi*a  # formula for circle of radius a
        21.991148575128552

    ellipeinc = <ufunc 'ellipeinc'>
        ellipeinc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipeinc(phi, m, out=None)

        Incomplete elliptic integral of the second kind

        This function is defined as

        .. math:: E(\phi, m) = \int_0^{\phi} [1 - m \sin(t)^2]^{1/2} dt

        Parameters
        ----------
        phi : array_like
            amplitude of the elliptic integral.
        m : array_like
            parameter of the elliptic integral.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        E : scalar or ndarray
            Value of the elliptic integral.

        See Also
        --------
        ellipkm1 : Complete elliptic integral of the first kind, near `m` = 1
        ellipk : Complete elliptic integral of the first kind
        ellipkinc : Incomplete elliptic integral of the first kind
        ellipe : Complete elliptic integral of the second kind
        elliprd : Symmetric elliptic integral of the second kind.
        elliprf : Completely-symmetric elliptic integral of the first kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `ellie`.

        Computation uses arithmetic-geometric means algorithm.

        The parameterization in terms of :math:`m` follows that of section
        17.2 in [2]_. Other parameterizations in terms of the
        complementary parameter :math:`1 - m`, modular angle
        :math:`\sin^2(\alpha) = m`, or modulus :math:`k^2 = m` are also
        used, so be careful that you choose the correct parameter.

        The Legendre E incomplete integral can be related to combinations
        of Carlson's symmetric integrals R_D, R_F, and R_G in multiple
        ways [3]_. For example, with :math:`c = \csc^2\phi`,

        .. math::
          E(\phi, m) = R_F(c-1, c-k^2, c)
            - \frac{1}{3} k^2 R_D(c-1, c-k^2, c) .

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [3] NIST Digital Library of Mathematical
               Functions. http://dlmf.nist.gov/, Release 1.0.28 of
               2020-09-15. See Sec. 19.25(i) https://dlmf.nist.gov/19.25#i

    ellipj = <ufunc 'ellipj'>
        ellipj(x1, x2[, out1, out2, out3, out4], / [, out=(None, None, None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipj(u, m, out=None)

        Jacobian elliptic functions

        Calculates the Jacobian elliptic functions of parameter `m` between
        0 and 1, and real argument `u`.

        Parameters
        ----------
        m : array_like
            Parameter.
        u : array_like
            Argument.
        out : tuple of ndarray, optional
            Optional output arrays for the function values

        Returns
        -------
        sn, cn, dn, ph : 4-tuple of scalar or ndarray
            The returned functions::

                sn(u|m), cn(u|m), dn(u|m)

            The value `ph` is such that if `u = ellipkinc(ph, m)`,
            then `sn(u|m) = sin(ph)` and `cn(u|m) = cos(ph)`.

        See Also
        --------
        ellipk : Complete elliptic integral of the first kind
        ellipkinc : Incomplete elliptic integral of the first kind

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `ellpj`.

        These functions are periodic, with quarter-period on the real axis
        equal to the complete elliptic integral `ellipk(m)`.

        Relation to incomplete elliptic integral: If `u = ellipkinc(phi,m)`, then
        `sn(u|m) = sin(phi)`, and `cn(u|m) = cos(phi)`. The `phi` is called
        the amplitude of `u`.

        Computation is by means of the arithmetic-geometric mean algorithm,
        except when `m` is within 1e-9 of 0 or 1. In the latter case with `m`
        close to 1, the approximation applies only for `phi < pi/2`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    ellipk = <ufunc 'ellipk'>
        ellipk(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipk(m, out=None)

        Complete elliptic integral of the first kind.

        This function is defined as

        .. math:: K(m) = \int_0^{\pi/2} [1 - m \sin(t)^2]^{-1/2} dt

        Parameters
        ----------
        m : array_like
            The parameter of the elliptic integral.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the elliptic integral.

        See Also
        --------
        ellipkm1 : Complete elliptic integral of the first kind around m = 1
        ellipkinc : Incomplete elliptic integral of the first kind
        ellipe : Complete elliptic integral of the second kind
        ellipeinc : Incomplete elliptic integral of the second kind
        elliprf : Completely-symmetric elliptic integral of the first kind.

        Notes
        -----
        For more precision around point m = 1, use `ellipkm1`, which this
        function calls.

        The parameterization in terms of :math:`m` follows that of section
        17.2 in [1]_. Other parameterizations in terms of the
        complementary parameter :math:`1 - m`, modular angle
        :math:`\sin^2(\alpha) = m`, or modulus :math:`k^2 = m` are also
        used, so be careful that you choose the correct parameter.

        The Legendre K integral is related to Carlson's symmetric R_F
        function by [2]_:

        .. math:: K(m) = R_F(0, 1-k^2, 1) .

        References
        ----------
        .. [1] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [2] NIST Digital Library of Mathematical
               Functions. http://dlmf.nist.gov/, Release 1.0.28 of
               2020-09-15. See Sec. 19.25(i) https://dlmf.nist.gov/19.25#i

    ellipkinc = <ufunc 'ellipkinc'>
        ellipkinc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipkinc(phi, m, out=None)

        Incomplete elliptic integral of the first kind

        This function is defined as

        .. math:: K(\phi, m) = \int_0^{\phi} [1 - m \sin(t)^2]^{-1/2} dt

        This function is also called :math:`F(\phi, m)`.

        Parameters
        ----------
        phi : array_like
            amplitude of the elliptic integral
        m : array_like
            parameter of the elliptic integral
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the elliptic integral

        See Also
        --------
        ellipkm1 : Complete elliptic integral of the first kind, near `m` = 1
        ellipk : Complete elliptic integral of the first kind
        ellipe : Complete elliptic integral of the second kind
        ellipeinc : Incomplete elliptic integral of the second kind
        elliprf : Completely-symmetric elliptic integral of the first kind.

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `ellik`.  The computation is
        carried out using the arithmetic-geometric mean algorithm.

        The parameterization in terms of :math:`m` follows that of section
        17.2 in [2]_. Other parameterizations in terms of the
        complementary parameter :math:`1 - m`, modular angle
        :math:`\sin^2(\alpha) = m`, or modulus :math:`k^2 = m` are also
        used, so be careful that you choose the correct parameter.

        The Legendre K incomplete integral (or F integral) is related to
        Carlson's symmetric R_F function [3]_.
        Setting :math:`c = \csc^2\phi`,

        .. math:: F(\phi, m) = R_F(c-1, c-k^2, c) .

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
        .. [3] NIST Digital Library of Mathematical
               Functions. http://dlmf.nist.gov/, Release 1.0.28 of
               2020-09-15. See Sec. 19.25(i) https://dlmf.nist.gov/19.25#i

    ellipkm1 = <ufunc 'ellipkm1'>
        ellipkm1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ellipkm1(p, out=None)

        Complete elliptic integral of the first kind around `m` = 1

        This function is defined as

        .. math:: K(p) = \int_0^{\pi/2} [1 - m \sin(t)^2]^{-1/2} dt

        where `m = 1 - p`.

        Parameters
        ----------
        p : array_like
            Defines the parameter of the elliptic integral as `m = 1 - p`.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the elliptic integral.

        See Also
        --------
        ellipk : Complete elliptic integral of the first kind
        ellipkinc : Incomplete elliptic integral of the first kind
        ellipe : Complete elliptic integral of the second kind
        ellipeinc : Incomplete elliptic integral of the second kind
        elliprf : Completely-symmetric elliptic integral of the first kind.

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `ellpk`.

        For `p <= 1`, computation uses the approximation,

        .. math:: K(p) \approx P(p) - \log(p) Q(p),

        where :math:`P` and :math:`Q` are tenth-order polynomials.  The
        argument `p` is used internally rather than `m` so that the logarithmic
        singularity at `m = 1` will be shifted to the origin; this preserves
        maximum accuracy.  For `p > 1`, the identity

        .. math:: K(p) = K(1/p)/\sqrt(p)

        is used.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

    elliprc = <ufunc 'elliprc'>
        elliprc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        elliprc(x, y, out=None)

        Degenerate symmetric elliptic integral.

        The function RC is defined as [1]_

        .. math::

            R_{\mathrm{C}}(x, y) =
               \frac{1}{2} \int_0^{+\infty} (t + x)^{-1/2} (t + y)^{-1} dt
               = R_{\mathrm{F}}(x, y, y)

        Parameters
        ----------
        x, y : array_like
            Real or complex input parameters. `x` can be any number in the
            complex plane cut along the negative real axis. `y` must be non-zero.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        R : scalar or ndarray
            Value of the integral. If `y` is real and negative, the Cauchy
            principal value is returned. If both of `x` and `y` are real, the
            return value is real. Otherwise, the return value is complex.

        See Also
        --------
        elliprf : Completely-symmetric elliptic integral of the first kind.
        elliprd : Symmetric elliptic integral of the second kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.
        elliprj : Symmetric elliptic integral of the third kind.

        Notes
        -----
        RC is a degenerate case of the symmetric integral RF: ``elliprc(x, y) ==
        elliprf(x, y, y)``. It is an elementary function rather than an elliptic
        integral.

        The code implements Carlson's algorithm based on the duplication theorems
        and series expansion up to the 7th order. [2]_

        .. versionadded:: 1.8.0

        References
        ----------
        .. [1] B. C. Carlson, ed., Chapter 19 in "Digital Library of Mathematical
               Functions," NIST, US Dept. of Commerce.
               https://dlmf.nist.gov/19.16.E6
        .. [2] B. C. Carlson, "Numerical computation of real or complex elliptic
               integrals," Numer. Algorithm, vol. 10, no. 1, pp. 13-26, 1995.
               https://arxiv.org/abs/math/9409227
               https://doi.org/10.1007/BF02198293

        Examples
        --------
        Basic homogeneity property:

        >>> import numpy as np
        >>> from scipy.special import elliprc

        >>> x = 1.2 + 3.4j
        >>> y = 5.
        >>> scale = 0.3 + 0.4j
        >>> elliprc(scale*x, scale*y)
        (0.5484493976710874-0.4169557678995833j)

        >>> elliprc(x, y)/np.sqrt(scale)
        (0.5484493976710874-0.41695576789958333j)

        When the two arguments coincide, the integral is particularly
        simple:

        >>> x = 1.2 + 3.4j
        >>> elliprc(x, x)
        (0.4299173120614631-0.3041729818745595j)

        >>> 1/np.sqrt(x)
        (0.4299173120614631-0.30417298187455954j)

        Another simple case: the first argument vanishes:

        >>> y = 1.2 + 3.4j
        >>> elliprc(0, y)
        (0.6753125346116815-0.47779380263880866j)

        >>> np.pi/2/np.sqrt(y)
        (0.6753125346116815-0.4777938026388088j)

        When `x` and `y` are both positive, we can express
        :math:`R_C(x,y)` in terms of more elementary functions.  For the
        case :math:`0 \le x < y`,

        >>> x = 3.2
        >>> y = 6.
        >>> elliprc(x, y)
        0.44942991498453444

        >>> np.arctan(np.sqrt((y-x)/x))/np.sqrt(y-x)
        0.44942991498453433

        And for the case :math:`0 \le y < x`,

        >>> x = 6.
        >>> y = 3.2
        >>> elliprc(x,y)
        0.4989837501576147

        >>> np.log((np.sqrt(x)+np.sqrt(x-y))/np.sqrt(y))/np.sqrt(x-y)
        0.49898375015761476

    elliprd = <ufunc 'elliprd'>
        elliprd(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        elliprd(x, y, z, out=None)

        Symmetric elliptic integral of the second kind.

        The function RD is defined as [1]_

        .. math::

            R_{\mathrm{D}}(x, y, z) =
               \frac{3}{2} \int_0^{+\infty} [(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}
               dt

        Parameters
        ----------
        x, y, z : array_like
            Real or complex input parameters. `x` or `y` can be any number in the
            complex plane cut along the negative real axis, but at most one of them
            can be zero, while `z` must be non-zero.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        R : scalar or ndarray
            Value of the integral. If all of `x`, `y`, and `z` are real, the
            return value is real. Otherwise, the return value is complex.

        See Also
        --------
        elliprc : Degenerate symmetric elliptic integral.
        elliprf : Completely-symmetric elliptic integral of the first kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.
        elliprj : Symmetric elliptic integral of the third kind.

        Notes
        -----
        RD is a degenerate case of the elliptic integral RJ: ``elliprd(x, y, z) ==
        elliprj(x, y, z, z)``.

        The code implements Carlson's algorithm based on the duplication theorems
        and series expansion up to the 7th order. [2]_

        .. versionadded:: 1.8.0

        References
        ----------
        .. [1] B. C. Carlson, ed., Chapter 19 in "Digital Library of Mathematical
               Functions," NIST, US Dept. of Commerce.
               https://dlmf.nist.gov/19.16.E5
        .. [2] B. C. Carlson, "Numerical computation of real or complex elliptic
               integrals," Numer. Algorithm, vol. 10, no. 1, pp. 13-26, 1995.
               https://arxiv.org/abs/math/9409227
               https://doi.org/10.1007/BF02198293

        Examples
        --------
        Basic homogeneity property:

        >>> import numpy as np
        >>> from scipy.special import elliprd

        >>> x = 1.2 + 3.4j
        >>> y = 5.
        >>> z = 6.
        >>> scale = 0.3 + 0.4j
        >>> elliprd(scale*x, scale*y, scale*z)
        (-0.03703043835680379-0.24500934665683802j)

        >>> elliprd(x, y, z)*np.power(scale, -1.5)
        (-0.0370304383568038-0.24500934665683805j)

        All three arguments coincide:

        >>> x = 1.2 + 3.4j
        >>> elliprd(x, x, x)
        (-0.03986825876151896-0.14051741840449586j)

        >>> np.power(x, -1.5)
        (-0.03986825876151894-0.14051741840449583j)

        The so-called "second lemniscate constant":

        >>> elliprd(0, 2, 1)/3
        0.5990701173677961

        >>> from scipy.special import gamma
        >>> gamma(0.75)**2/np.sqrt(2*np.pi)
        0.5990701173677959

    elliprf = <ufunc 'elliprf'>
        elliprf(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        elliprf(x, y, z, out=None)

        Completely-symmetric elliptic integral of the first kind.

        The function RF is defined as [1]_

        .. math::

            R_{\mathrm{F}}(x, y, z) =
               \frac{1}{2} \int_0^{+\infty} [(t + x) (t + y) (t + z)]^{-1/2} dt

        Parameters
        ----------
        x, y, z : array_like
            Real or complex input parameters. `x`, `y`, or `z` can be any number in
            the complex plane cut along the negative real axis, but at most one of
            them can be zero.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        R : scalar or ndarray
            Value of the integral. If all of `x`, `y`, and `z` are real, the return
            value is real. Otherwise, the return value is complex.

        See Also
        --------
        elliprc : Degenerate symmetric integral.
        elliprd : Symmetric elliptic integral of the second kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.
        elliprj : Symmetric elliptic integral of the third kind.

        Notes
        -----
        The code implements Carlson's algorithm based on the duplication theorems
        and series expansion up to the 7th order (cf.:
        https://dlmf.nist.gov/19.36.i) and the AGM algorithm for the complete
        integral. [2]_

        .. versionadded:: 1.8.0

        References
        ----------
        .. [1] B. C. Carlson, ed., Chapter 19 in "Digital Library of Mathematical
               Functions," NIST, US Dept. of Commerce.
               https://dlmf.nist.gov/19.16.E1
        .. [2] B. C. Carlson, "Numerical computation of real or complex elliptic
               integrals," Numer. Algorithm, vol. 10, no. 1, pp. 13-26, 1995.
               https://arxiv.org/abs/math/9409227
               https://doi.org/10.1007/BF02198293

        Examples
        --------
        Basic homogeneity property:

        >>> import numpy as np
        >>> from scipy.special import elliprf

        >>> x = 1.2 + 3.4j
        >>> y = 5.
        >>> z = 6.
        >>> scale = 0.3 + 0.4j
        >>> elliprf(scale*x, scale*y, scale*z)
        (0.5328051227278146-0.4008623567957094j)

        >>> elliprf(x, y, z)/np.sqrt(scale)
        (0.5328051227278147-0.4008623567957095j)

        All three arguments coincide:

        >>> x = 1.2 + 3.4j
        >>> elliprf(x, x, x)
        (0.42991731206146316-0.30417298187455954j)

        >>> 1/np.sqrt(x)
        (0.4299173120614631-0.30417298187455954j)

        The so-called "first lemniscate constant":

        >>> elliprf(0, 1, 2)
        1.3110287771460598

        >>> from scipy.special import gamma
        >>> gamma(0.25)**2/(4*np.sqrt(2*np.pi))
        1.3110287771460598

    elliprg = <ufunc 'elliprg'>
        elliprg(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        elliprg(x, y, z, out=None)

        Completely-symmetric elliptic integral of the second kind.

        The function RG is defined as [1]_

        .. math::

            R_{\mathrm{G}}(x, y, z) =
               \frac{1}{4} \int_0^{+\infty} [(t + x) (t + y) (t + z)]^{-1/2}
               \left(\frac{x}{t + x} + \frac{y}{t + y} + \frac{z}{t + z}\right) t
               dt

        Parameters
        ----------
        x, y, z : array_like
            Real or complex input parameters. `x`, `y`, or `z` can be any number in
            the complex plane cut along the negative real axis.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        R : scalar or ndarray
            Value of the integral. If all of `x`, `y`, and `z` are real, the return
            value is real. Otherwise, the return value is complex.

        See Also
        --------
        elliprc : Degenerate symmetric integral.
        elliprd : Symmetric elliptic integral of the second kind.
        elliprf : Completely-symmetric elliptic integral of the first kind.
        elliprj : Symmetric elliptic integral of the third kind.

        Notes
        -----
        The implementation uses the relation [1]_

        .. math::

            2 R_{\mathrm{G}}(x, y, z) =
               z R_{\mathrm{F}}(x, y, z) -
               \frac{1}{3} (x - z) (y - z) R_{\mathrm{D}}(x, y, z) +
               \sqrt{\frac{x y}{z}}

        and the symmetry of `x`, `y`, `z` when at least one non-zero parameter can
        be chosen as the pivot. When one of the arguments is close to zero, the AGM
        method is applied instead. Other special cases are computed following Ref.
        [2]_

        .. versionadded:: 1.8.0

        References
        ----------
        .. [1] B. C. Carlson, "Numerical computation of real or complex elliptic
               integrals," Numer. Algorithm, vol. 10, no. 1, pp. 13-26, 1995.
               https://arxiv.org/abs/math/9409227
               https://doi.org/10.1007/BF02198293
        .. [2] B. C. Carlson, ed., Chapter 19 in "Digital Library of Mathematical
               Functions," NIST, US Dept. of Commerce.
               https://dlmf.nist.gov/19.16.E1
               https://dlmf.nist.gov/19.20.ii

        Examples
        --------
        Basic homogeneity property:

        >>> import numpy as np
        >>> from scipy.special import elliprg

        >>> x = 1.2 + 3.4j
        >>> y = 5.
        >>> z = 6.
        >>> scale = 0.3 + 0.4j
        >>> elliprg(scale*x, scale*y, scale*z)
        (1.195936862005246+0.8470988320464167j)

        >>> elliprg(x, y, z)*np.sqrt(scale)
        (1.195936862005246+0.8470988320464165j)

        Simplifications:

        >>> elliprg(0, y, y)
        1.756203682760182

        >>> 0.25*np.pi*np.sqrt(y)
        1.7562036827601817

        >>> elliprg(0, 0, z)
        1.224744871391589

        >>> 0.5*np.sqrt(z)
        1.224744871391589

        The surface area of a triaxial ellipsoid with semiaxes ``a``, ``b``, and
        ``c`` is given by

        .. math::

            S = 4 \pi a b c R_{\mathrm{G}}(1 / a^2, 1 / b^2, 1 / c^2).

        >>> def ellipsoid_area(a, b, c):
        ...     r = 4.0 * np.pi * a * b * c
        ...     return r * elliprg(1.0 / (a * a), 1.0 / (b * b), 1.0 / (c * c))
        >>> print(ellipsoid_area(1, 3, 5))
        108.62688289491807

    elliprj = <ufunc 'elliprj'>
        elliprj(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        elliprj(x, y, z, p, out=None)

        Symmetric elliptic integral of the third kind.

        The function RJ is defined as [1]_

        .. math::

            R_{\mathrm{J}}(x, y, z, p) =
               \frac{3}{2} \int_0^{+\infty} [(t + x) (t + y) (t + z)]^{-1/2}
               (t + p)^{-1} dt

        .. warning::
            This function should be considered experimental when the inputs are
            unbalanced.  Check correctness with another independent implementation.

        Parameters
        ----------
        x, y, z, p : array_like
            Real or complex input parameters. `x`, `y`, or `z` are numbers in
            the complex plane cut along the negative real axis (subject to further
            constraints, see Notes), and at most one of them can be zero. `p` must
            be non-zero.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        R : scalar or ndarray
            Value of the integral. If all of `x`, `y`, `z`, and `p` are real, the
            return value is real. Otherwise, the return value is complex.

            If `p` is real and negative, while `x`, `y`, and `z` are real,
            non-negative, and at most one of them is zero, the Cauchy principal
            value is returned. [1]_ [2]_

        See Also
        --------
        elliprc : Degenerate symmetric integral.
        elliprd : Symmetric elliptic integral of the second kind.
        elliprf : Completely-symmetric elliptic integral of the first kind.
        elliprg : Completely-symmetric elliptic integral of the second kind.

        Notes
        -----
        The code implements Carlson's algorithm based on the duplication theorems
        and series expansion up to the 7th order. [3]_ The algorithm is slightly
        different from its earlier incarnation as it appears in [1]_, in that the
        call to `elliprc` (or ``atan``/``atanh``, see [4]_) is no longer needed in
        the inner loop. Asymptotic approximations are used where arguments differ
        widely in the order of magnitude. [5]_

        The input values are subject to certain sufficient but not necessary
        constraints when input arguments are complex. Notably, ``x``, ``y``, and
        ``z`` must have non-negative real parts, unless two of them are
        non-negative and complex-conjugates to each other while the other is a real
        non-negative number. [1]_ If the inputs do not satisfy the sufficient
        condition described in Ref. [1]_ they are rejected outright with the output
        set to NaN.

        In the case where one of ``x``, ``y``, and ``z`` is equal to ``p``, the
        function ``elliprd`` should be preferred because of its less restrictive
        domain.

        .. versionadded:: 1.8.0

        References
        ----------
        .. [1] B. C. Carlson, "Numerical computation of real or complex elliptic
               integrals," Numer. Algorithm, vol. 10, no. 1, pp. 13-26, 1995.
               https://arxiv.org/abs/math/9409227
               https://doi.org/10.1007/BF02198293
        .. [2] B. C. Carlson, ed., Chapter 19 in "Digital Library of Mathematical
               Functions," NIST, US Dept. of Commerce.
               https://dlmf.nist.gov/19.20.iii
        .. [3] B. C. Carlson, J. FitzSimmons, "Reduction Theorems for Elliptic
               Integrands with the Square Root of Two Quadratic Factors," J.
               Comput. Appl. Math., vol. 118, nos. 1-2, pp. 71-85, 2000.
               https://doi.org/10.1016/S0377-0427(00)00282-X
        .. [4] F. Johansson, "Numerical Evaluation of Elliptic Functions, Elliptic
               Integrals and Modular Forms," in J. Blumlein, C. Schneider, P.
               Paule, eds., "Elliptic Integrals, Elliptic Functions and Modular
               Forms in Quantum Field Theory," pp. 269-293, 2019 (Cham,
               Switzerland: Springer Nature Switzerland)
               https://arxiv.org/abs/1806.06725
               https://doi.org/10.1007/978-3-030-04480-0
        .. [5] B. C. Carlson, J. L. Gustafson, "Asymptotic Approximations for
               Symmetric Elliptic Integrals," SIAM J. Math. Anls., vol. 25, no. 2,
               pp. 288-303, 1994.
               https://arxiv.org/abs/math/9310223
               https://doi.org/10.1137/S0036141092228477

        Examples
        --------
        Basic homogeneity property:

        >>> import numpy as np
        >>> from scipy.special import elliprj

        >>> x = 1.2 + 3.4j
        >>> y = 5.
        >>> z = 6.
        >>> p = 7.
        >>> scale = 0.3 - 0.4j
        >>> elliprj(scale*x, scale*y, scale*z, scale*p)
        (0.10834905565679157+0.19694950747103812j)

        >>> elliprj(x, y, z, p)*np.power(scale, -1.5)
        (0.10834905565679556+0.19694950747103854j)

        Reduction to simpler elliptic integral:

        >>> elliprj(x, y, z, z)
        (0.08288462362195129-0.028376809745123258j)

        >>> from scipy.special import elliprd
        >>> elliprd(x, y, z)
        (0.08288462362195136-0.028376809745123296j)

        All arguments coincide:

        >>> elliprj(x, x, x, x)
        (-0.03986825876151896-0.14051741840449586j)

        >>> np.power(x, -1.5)
        (-0.03986825876151894-0.14051741840449583j)

    entr = <ufunc 'entr'>
        entr(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        entr(x, out=None)

        Elementwise function for computing entropy.

        .. math:: \text{entr}(x) = \begin{cases} - x \log(x) & x > 0  \\ 0 & x = 0
                  \\ -\infty & \text{otherwise} \end{cases}

        Parameters
        ----------
        x : ndarray
            Input array.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        res : scalar or ndarray
            The value of the elementwise entropy function at the given points `x`.

        See Also
        --------
        kl_div, rel_entr, scipy.stats.entropy

        Notes
        -----
        .. versionadded:: 0.15.0

        This function is concave.

        The origin of this function is in convex programming; see [1]_.
        Given a probability distribution :math:`p_1, \ldots, p_n`,
        the definition of entropy in the context of *information theory* is

        .. math::

            \sum_{i = 1}^n \mathrm{entr}(p_i).

        To compute the latter quantity, use `scipy.stats.entropy`.

        References
        ----------
        .. [1] Boyd, Stephen and Lieven Vandenberghe. *Convex optimization*.
               Cambridge University Press, 2004.
               :doi:`https://doi.org/10.1017/CBO9780511804441`

    erf = <ufunc 'erf'>
        erf(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erf(z, out=None)

        Returns the error function of complex argument.

        It is defined as ``2/sqrt(pi)*integral(exp(-t**2), t=0..z)``.

        Parameters
        ----------
        x : ndarray
            Input array.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        res : scalar or ndarray
            The values of the error function at the given points `x`.

        See Also
        --------
        erfc, erfinv, erfcinv, wofz, erfcx, erfi

        Notes
        -----
        The cumulative of the unit normal distribution is given by
        ``Phi(z) = 1/2[1 + erf(z/sqrt(2))]``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Error_function
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover,
            1972. http://www.math.sfu.ca/~cbm/aands/page_297.htm
        .. [3] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-3, 3)
        >>> plt.plot(x, special.erf(x))
        >>> plt.xlabel('$x$')
        >>> plt.ylabel('$erf(x)$')
        >>> plt.show()

    erfc = <ufunc 'erfc'>
        erfc(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erfc(x, out=None)

        Complementary error function, ``1 - erf(x)``.

        Parameters
        ----------
        x : array_like
            Real or complex valued argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the complementary error function

        See Also
        --------
        erf, erfi, erfcx, dawsn, wofz

        References
        ----------
        .. [1] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-3, 3)
        >>> plt.plot(x, special.erfc(x))
        >>> plt.xlabel('$x$')
        >>> plt.ylabel('$erfc(x)$')
        >>> plt.show()

    erfcinv = <ufunc 'erfcinv'>
        erfcinv(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erfcinv(y, out=None)

        Inverse of the complementary error function.

        Computes the inverse of the complementary error function.

        In the complex domain, there is no unique complex number w satisfying
        erfc(w)=z. This indicates a true inverse function would be multivalued.
        When the domain restricts to the real, 0 < x < 2, there is a unique real
        number satisfying erfc(erfcinv(x)) = erfcinv(erfc(x)).

        It is related to inverse of the error function by erfcinv(1-x) = erfinv(x)

        Parameters
        ----------
        y : ndarray
            Argument at which to evaluate. Domain: [0, 2]
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        erfcinv : scalar or ndarray
            The inverse of erfc of y, element-wise

        See Also
        --------
        erf : Error function of a complex argument
        erfc : Complementary error function, ``1 - erf(x)``
        erfinv : Inverse of the error function

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import erfcinv

        >>> erfcinv(0.5)
        0.4769362762044699

        >>> y = np.linspace(0.0, 2.0, num=11)
        >>> erfcinv(y)
        array([        inf,  0.9061938 ,  0.59511608,  0.37080716,  0.17914345,
               -0.        , -0.17914345, -0.37080716, -0.59511608, -0.9061938 ,
                      -inf])

        Plot the function:

        >>> y = np.linspace(0, 2, 200)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(y, erfcinv(y))
        >>> ax.grid(True)
        >>> ax.set_xlabel('y')
        >>> ax.set_title('erfcinv(y)')
        >>> plt.show()

    erfcx = <ufunc 'erfcx'>
        erfcx(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erfcx(x, out=None)

        Scaled complementary error function, ``exp(x**2) * erfc(x)``.

        Parameters
        ----------
        x : array_like
            Real or complex valued argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the scaled complementary error function


        See Also
        --------
        erf, erfc, erfi, dawsn, wofz

        Notes
        -----

        .. versionadded:: 0.12.0

        References
        ----------
        .. [1] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-3, 3)
        >>> plt.plot(x, special.erfcx(x))
        >>> plt.xlabel('$x$')
        >>> plt.ylabel('$erfcx(x)$')
        >>> plt.show()

    erfi = <ufunc 'erfi'>
        erfi(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erfi(z, out=None)

        Imaginary error function, ``-i erf(i z)``.

        Parameters
        ----------
        z : array_like
            Real or complex valued argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the imaginary error function

        See Also
        --------
        erf, erfc, erfcx, dawsn, wofz

        Notes
        -----

        .. versionadded:: 0.12.0

        References
        ----------
        .. [1] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-3, 3)
        >>> plt.plot(x, special.erfi(x))
        >>> plt.xlabel('$x$')
        >>> plt.ylabel('$erfi(x)$')
        >>> plt.show()

    erfinv = <ufunc 'erfinv'>
        erfinv(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        erfinv(y, out=None)

        Inverse of the error function.

        Computes the inverse of the error function.

        In the complex domain, there is no unique complex number w satisfying
        erf(w)=z. This indicates a true inverse function would be multivalued.
        When the domain restricts to the real, -1 < x < 1, there is a unique real
        number satisfying erf(erfinv(x)) = x.

        Parameters
        ----------
        y : ndarray
            Argument at which to evaluate. Domain: [-1, 1]
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        erfinv : scalar or ndarray
            The inverse of erf of y, element-wise

        See Also
        --------
        erf : Error function of a complex argument
        erfc : Complementary error function, ``1 - erf(x)``
        erfcinv : Inverse of the complementary error function

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import erfinv, erf

        >>> erfinv(0.5)
        0.4769362762044699

        >>> y = np.linspace(-1.0, 1.0, num=9)
        >>> x = erfinv(y)
        >>> x
        array([       -inf, -0.81341985, -0.47693628, -0.22531206,  0.        ,
                0.22531206,  0.47693628,  0.81341985,         inf])

        Verify that ``erf(erfinv(y))`` is ``y``.

        >>> erf(x)
        array([-1.  , -0.75, -0.5 , -0.25,  0.  ,  0.25,  0.5 ,  0.75,  1.  ])

        Plot the function:

        >>> y = np.linspace(-1, 1, 200)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(y, erfinv(y))
        >>> ax.grid(True)
        >>> ax.set_xlabel('y')
        >>> ax.set_title('erfinv(y)')
        >>> plt.show()

    eval_chebyc = <ufunc 'eval_chebyc'>
        eval_chebyc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_chebyc(n, x, out=None)

        Evaluate Chebyshev polynomial of the first kind on [-2, 2] at a
        point.

        These polynomials are defined as

        .. math::

            C_n(x) = 2 T_n(x/2)

        where :math:`T_n` is a Chebyshev polynomial of the first kind. See
        22.5.11 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to `eval_chebyt`.
        x : array_like
            Points at which to evaluate the Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        C : scalar or ndarray
            Values of the Chebyshev polynomial

        See Also
        --------
        roots_chebyc : roots and quadrature weights of Chebyshev
                       polynomials of the first kind on [-2, 2]
        chebyc : Chebyshev polynomial object
        numpy.polynomial.chebyshev.Chebyshev : Chebyshev series
        eval_chebyt : evaluate Chebycshev polynomials of the first kind

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        They are a scaled version of the Chebyshev polynomials of the
        first kind.

        >>> x = np.linspace(-2, 2, 6)
        >>> sc.eval_chebyc(3, x)
        array([-2.   ,  1.872,  1.136, -1.136, -1.872,  2.   ])
        >>> 2 * sc.eval_chebyt(3, x / 2)
        array([-2.   ,  1.872,  1.136, -1.136, -1.872,  2.   ])

    eval_chebys = <ufunc 'eval_chebys'>
        eval_chebys(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_chebys(n, x, out=None)

        Evaluate Chebyshev polynomial of the second kind on [-2, 2] at a
        point.

        These polynomials are defined as

        .. math::

            S_n(x) = U_n(x/2)

        where :math:`U_n` is a Chebyshev polynomial of the second
        kind. See 22.5.13 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to `eval_chebyu`.
        x : array_like
            Points at which to evaluate the Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        S : scalar or ndarray
            Values of the Chebyshev polynomial

        See Also
        --------
        roots_chebys : roots and quadrature weights of Chebyshev
                       polynomials of the second kind on [-2, 2]
        chebys : Chebyshev polynomial object
        eval_chebyu : evaluate Chebyshev polynomials of the second kind

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        They are a scaled version of the Chebyshev polynomials of the
        second kind.

        >>> x = np.linspace(-2, 2, 6)
        >>> sc.eval_chebys(3, x)
        array([-4.   ,  0.672,  0.736, -0.736, -0.672,  4.   ])
        >>> sc.eval_chebyu(3, x / 2)
        array([-4.   ,  0.672,  0.736, -0.736, -0.672,  4.   ])

    eval_chebyt = <ufunc 'eval_chebyt'>
        eval_chebyt(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_chebyt(n, x, out=None)

        Evaluate Chebyshev polynomial of the first kind at a point.

        The Chebyshev polynomials of the first kind can be defined via the
        Gauss hypergeometric function :math:`{}_2F_1` as

        .. math::

            T_n(x) = {}_2F_1(n, -n; 1/2; (1 - x)/2).

        When :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.47 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to the Gauss hypergeometric
            function.
        x : array_like
            Points at which to evaluate the Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        T : scalar or ndarray
            Values of the Chebyshev polynomial

        See Also
        --------
        roots_chebyt : roots and quadrature weights of Chebyshev
                       polynomials of the first kind
        chebyu : Chebychev polynomial object
        eval_chebyu : evaluate Chebyshev polynomials of the second kind
        hyp2f1 : Gauss hypergeometric function
        numpy.polynomial.chebyshev.Chebyshev : Chebyshev series

        Notes
        -----
        This routine is numerically stable for `x` in ``[-1, 1]`` at least
        up to order ``10000``.

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_chebyu = <ufunc 'eval_chebyu'>
        eval_chebyu(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_chebyu(n, x, out=None)

        Evaluate Chebyshev polynomial of the second kind at a point.

        The Chebyshev polynomials of the second kind can be defined via
        the Gauss hypergeometric function :math:`{}_2F_1` as

        .. math::

            U_n(x) = (n + 1) {}_2F_1(-n, n + 2; 3/2; (1 - x)/2).

        When :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.48 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to the Gauss hypergeometric
            function.
        x : array_like
            Points at which to evaluate the Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        U : scalar or ndarray
            Values of the Chebyshev polynomial

        See Also
        --------
        roots_chebyu : roots and quadrature weights of Chebyshev
                       polynomials of the second kind
        chebyu : Chebyshev polynomial object
        eval_chebyt : evaluate Chebyshev polynomials of the first kind
        hyp2f1 : Gauss hypergeometric function

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_gegenbauer = <ufunc 'eval_gegenbauer'>
        eval_gegenbauer(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_gegenbauer(n, alpha, x, out=None)

        Evaluate Gegenbauer polynomial at a point.

        The Gegenbauer polynomials can be defined via the Gauss
        hypergeometric function :math:`{}_2F_1` as

        .. math::

            C_n^{(\alpha)} = \frac{(2\alpha)_n}{\Gamma(n + 1)}
              {}_2F_1(-n, 2\alpha + n; \alpha + 1/2; (1 - z)/2).

        When :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.46 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to the Gauss hypergeometric
            function.
        alpha : array_like
            Parameter
        x : array_like
            Points at which to evaluate the Gegenbauer polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        C : scalar or ndarray
            Values of the Gegenbauer polynomial

        See Also
        --------
        roots_gegenbauer : roots and quadrature weights of Gegenbauer
                           polynomials
        gegenbauer : Gegenbauer polynomial object
        hyp2f1 : Gauss hypergeometric function

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_genlaguerre = <ufunc 'eval_genlaguerre'>
        eval_genlaguerre(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_genlaguerre(n, alpha, x, out=None)

        Evaluate generalized Laguerre polynomial at a point.

        The generalized Laguerre polynomials can be defined via the
        confluent hypergeometric function :math:`{}_1F_1` as

        .. math::

            L_n^{(\alpha)}(x) = \binom{n + \alpha}{n}
              {}_1F_1(-n, \alpha + 1, x).

        When :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.54 in [AS]_ for details. The Laguerre
        polynomials are the special case where :math:`\alpha = 0`.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to the confluent hypergeometric
            function.
        alpha : array_like
            Parameter; must have ``alpha > -1``
        x : array_like
            Points at which to evaluate the generalized Laguerre
            polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        L : scalar or ndarray
            Values of the generalized Laguerre polynomial

        See Also
        --------
        roots_genlaguerre : roots and quadrature weights of generalized
                            Laguerre polynomials
        genlaguerre : generalized Laguerre polynomial object
        hyp1f1 : confluent hypergeometric function
        eval_laguerre : evaluate Laguerre polynomials

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_hermite = <ufunc 'eval_hermite'>
        eval_hermite(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_hermite(n, x, out=None)

        Evaluate physicist's Hermite polynomial at a point.

        Defined by

        .. math::

            H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2};

        :math:`H_n` is a polynomial of degree :math:`n`. See 22.11.7 in
        [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial
        x : array_like
            Points at which to evaluate the Hermite polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        H : scalar or ndarray
            Values of the Hermite polynomial

        See Also
        --------
        roots_hermite : roots and quadrature weights of physicist's
                        Hermite polynomials
        hermite : physicist's Hermite polynomial object
        numpy.polynomial.hermite.Hermite : Physicist's Hermite series
        eval_hermitenorm : evaluate Probabilist's Hermite polynomials

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_hermitenorm = <ufunc 'eval_hermitenorm'>
        eval_hermitenorm(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_hermitenorm(n, x, out=None)

        Evaluate probabilist's (normalized) Hermite polynomial at a
        point.

        Defined by

        .. math::

            He_n(x) = (-1)^n e^{x^2/2} \frac{d^n}{dx^n} e^{-x^2/2};

        :math:`He_n` is a polynomial of degree :math:`n`. See 22.11.8 in
        [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial
        x : array_like
            Points at which to evaluate the Hermite polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        He : scalar or ndarray
            Values of the Hermite polynomial

        See Also
        --------
        roots_hermitenorm : roots and quadrature weights of probabilist's
                            Hermite polynomials
        hermitenorm : probabilist's Hermite polynomial object
        numpy.polynomial.hermite_e.HermiteE : Probabilist's Hermite series
        eval_hermite : evaluate physicist's Hermite polynomials

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_jacobi = <ufunc 'eval_jacobi'>
        eval_jacobi(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_jacobi(n, alpha, beta, x, out=None)

        Evaluate Jacobi polynomial at a point.

        The Jacobi polynomials can be defined via the Gauss hypergeometric
        function :math:`{}_2F_1` as

        .. math::

            P_n^{(\alpha, \beta)}(x) = \frac{(\alpha + 1)_n}{\Gamma(n + 1)}
              {}_2F_1(-n, 1 + \alpha + \beta + n; \alpha + 1; (1 - z)/2)

        where :math:`(\cdot)_n` is the Pochhammer symbol; see `poch`. When
        :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.42 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer the result is
            determined via the relation to the Gauss hypergeometric
            function.
        alpha : array_like
            Parameter
        beta : array_like
            Parameter
        x : array_like
            Points at which to evaluate the polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        P : scalar or ndarray
            Values of the Jacobi polynomial

        See Also
        --------
        roots_jacobi : roots and quadrature weights of Jacobi polynomials
        jacobi : Jacobi polynomial object
        hyp2f1 : Gauss hypergeometric function

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_laguerre = <ufunc 'eval_laguerre'>
        eval_laguerre(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_laguerre(n, x, out=None)

        Evaluate Laguerre polynomial at a point.

        The Laguerre polynomials can be defined via the confluent
        hypergeometric function :math:`{}_1F_1` as

        .. math::

            L_n(x) = {}_1F_1(-n, 1, x).

        See 22.5.16 and 22.5.54 in [AS]_ for details. When :math:`n` is an
        integer the result is a polynomial of degree :math:`n`.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer the result is
            determined via the relation to the confluent hypergeometric
            function.
        x : array_like
            Points at which to evaluate the Laguerre polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        L : scalar or ndarray
            Values of the Laguerre polynomial

        See Also
        --------
        roots_laguerre : roots and quadrature weights of Laguerre
                         polynomials
        laguerre : Laguerre polynomial object
        numpy.polynomial.laguerre.Laguerre : Laguerre series
        eval_genlaguerre : evaluate generalized Laguerre polynomials

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_legendre = <ufunc 'eval_legendre'>
        eval_legendre(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_legendre(n, x, out=None)

        Evaluate Legendre polynomial at a point.

        The Legendre polynomials can be defined via the Gauss
        hypergeometric function :math:`{}_2F_1` as

        .. math::

            P_n(x) = {}_2F_1(-n, n + 1; 1; (1 - x)/2).

        When :math:`n` is an integer the result is a polynomial of degree
        :math:`n`. See 22.5.49 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to the Gauss hypergeometric
            function.
        x : array_like
            Points at which to evaluate the Legendre polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        P : scalar or ndarray
            Values of the Legendre polynomial

        See Also
        --------
        roots_legendre : roots and quadrature weights of Legendre
                         polynomials
        legendre : Legendre polynomial object
        hyp2f1 : Gauss hypergeometric function
        numpy.polynomial.legendre.Legendre : Legendre series

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import eval_legendre

        Evaluate the zero-order Legendre polynomial at x = 0

        >>> eval_legendre(0, 0)
        1.0

        Evaluate the first-order Legendre polynomial between -1 and 1

        >>> X = np.linspace(-1, 1, 5)  # Domain of Legendre polynomials
        >>> eval_legendre(1, X)
        array([-1. , -0.5,  0. ,  0.5,  1. ])

        Evaluate Legendre polynomials of order 0 through 4 at x = 0

        >>> N = range(0, 5)
        >>> eval_legendre(N, 0)
        array([ 1.   ,  0.   , -0.5  ,  0.   ,  0.375])

        Plot Legendre polynomials of order 0 through 4

        >>> X = np.linspace(-1, 1)

        >>> import matplotlib.pyplot as plt
        >>> for n in range(0, 5):
        ...     y = eval_legendre(n, X)
        ...     plt.plot(X, y, label=r'$P_{}(x)$'.format(n))

        >>> plt.title("Legendre Polynomials")
        >>> plt.xlabel("x")
        >>> plt.ylabel(r'$P_n(x)$')
        >>> plt.legend(loc='lower right')
        >>> plt.show()

    eval_sh_chebyt = <ufunc 'eval_sh_chebyt'>
        eval_sh_chebyt(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_sh_chebyt(n, x, out=None)

        Evaluate shifted Chebyshev polynomial of the first kind at a
        point.

        These polynomials are defined as

        .. math::

            T_n^*(x) = T_n(2x - 1)

        where :math:`T_n` is a Chebyshev polynomial of the first kind. See
        22.5.14 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to `eval_chebyt`.
        x : array_like
            Points at which to evaluate the shifted Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        T : scalar or ndarray
            Values of the shifted Chebyshev polynomial

        See Also
        --------
        roots_sh_chebyt : roots and quadrature weights of shifted
                          Chebyshev polynomials of the first kind
        sh_chebyt : shifted Chebyshev polynomial object
        eval_chebyt : evaluate Chebyshev polynomials of the first kind
        numpy.polynomial.chebyshev.Chebyshev : Chebyshev series

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_sh_chebyu = <ufunc 'eval_sh_chebyu'>
        eval_sh_chebyu(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_sh_chebyu(n, x, out=None)

        Evaluate shifted Chebyshev polynomial of the second kind at a
        point.

        These polynomials are defined as

        .. math::

            U_n^*(x) = U_n(2x - 1)

        where :math:`U_n` is a Chebyshev polynomial of the first kind. See
        22.5.15 in [AS]_ for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to `eval_chebyu`.
        x : array_like
            Points at which to evaluate the shifted Chebyshev polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        U : scalar or ndarray
            Values of the shifted Chebyshev polynomial

        See Also
        --------
        roots_sh_chebyu : roots and quadrature weights of shifted
                          Chebychev polynomials of the second kind
        sh_chebyu : shifted Chebyshev polynomial object
        eval_chebyu : evaluate Chebyshev polynomials of the second kind

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_sh_jacobi = <ufunc 'eval_sh_jacobi'>
        eval_sh_jacobi(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_sh_jacobi(n, p, q, x, out=None)

        Evaluate shifted Jacobi polynomial at a point.

        Defined by

        .. math::

            G_n^{(p, q)}(x)
              = \binom{2n + p - 1}{n}^{-1} P_n^{(p - q, q - 1)}(2x - 1),

        where :math:`P_n^{(\cdot, \cdot)}` is the n-th Jacobi
        polynomial. See 22.5.2 in [AS]_ for details.

        Parameters
        ----------
        n : int
            Degree of the polynomial. If not an integer, the result is
            determined via the relation to `binom` and `eval_jacobi`.
        p : float
            Parameter
        q : float
            Parameter
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        G : scalar or ndarray
            Values of the shifted Jacobi polynomial.

        See Also
        --------
        roots_sh_jacobi : roots and quadrature weights of shifted Jacobi
                          polynomials
        sh_jacobi : shifted Jacobi polynomial object
        eval_jacobi : evaluate Jacobi polynomials

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    eval_sh_legendre = <ufunc 'eval_sh_legendre'>
        eval_sh_legendre(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        eval_sh_legendre(n, x, out=None)

        Evaluate shifted Legendre polynomial at a point.

        These polynomials are defined as

        .. math::

            P_n^*(x) = P_n(2x - 1)

        where :math:`P_n` is a Legendre polynomial. See 2.2.11 in [AS]_
        for details.

        Parameters
        ----------
        n : array_like
            Degree of the polynomial. If not an integer, the value is
            determined via the relation to `eval_legendre`.
        x : array_like
            Points at which to evaluate the shifted Legendre polynomial
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        P : scalar or ndarray
            Values of the shifted Legendre polynomial

        See Also
        --------
        roots_sh_legendre : roots and quadrature weights of shifted
                            Legendre polynomials
        sh_legendre : shifted Legendre polynomial object
        eval_legendre : evaluate Legendre polynomials
        numpy.polynomial.legendre.Legendre : Legendre series

        References
        ----------
        .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
            Handbook of Mathematical Functions with Formulas,
            Graphs, and Mathematical Tables. New York: Dover, 1972.

    exp1 = <ufunc 'exp1'>
        exp1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        exp1(z, out=None)

        Exponential integral E1.

        For complex :math:`z \ne 0` the exponential integral can be defined as
        [1]_

        .. math::

           E_1(z) = \int_z^\infty \frac{e^{-t}}{t} dt,

        where the path of the integral does not cross the negative real
        axis or pass through the origin.

        Parameters
        ----------
        z: array_like
            Real or complex argument.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the exponential integral E1

        See Also
        --------
        expi : exponential integral :math:`Ei`
        expn : generalization of :math:`E_1`

        Notes
        -----
        For :math:`x > 0` it is related to the exponential integral
        :math:`Ei` (see `expi`) via the relation

        .. math::

           E_1(x) = -Ei(-x).

        References
        ----------
        .. [1] Digital Library of Mathematical Functions, 6.2.1
               https://dlmf.nist.gov/6.2#E1

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It has a pole at 0.

        >>> sc.exp1(0)
        inf

        It has a branch cut on the negative real axis.

        >>> sc.exp1(-1)
        nan
        >>> sc.exp1(complex(-1, 0))
        (-1.8951178163559368-3.141592653589793j)
        >>> sc.exp1(complex(-1, -0.0))
        (-1.8951178163559368+3.141592653589793j)

        It approaches 0 along the positive real axis.

        >>> sc.exp1([1, 10, 100, 1000])
        array([2.19383934e-01, 4.15696893e-06, 3.68359776e-46, 0.00000000e+00])

        It is related to `expi`.

        >>> x = np.array([1, 2, 3, 4])
        >>> sc.exp1(x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])
        >>> -sc.expi(-x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])

    exp10 = <ufunc 'exp10'>
        exp10(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        exp10(x, out=None)

        Compute ``10**x`` element-wise.

        Parameters
        ----------
        x : array_like
            `x` must contain real numbers.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            ``10**x``, computed element-wise.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import exp10

        >>> exp10(3)
        1000.0
        >>> x = np.array([[-1, -0.5, 0], [0.5, 1, 1.5]])
        >>> exp10(x)
        array([[  0.1       ,   0.31622777,   1.        ],
               [  3.16227766,  10.        ,  31.6227766 ]])

    exp2 = <ufunc 'exp2'>
        exp2(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        exp2(x, out=None)

        Compute ``2**x`` element-wise.

        Parameters
        ----------
        x : array_like
            `x` must contain real numbers.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            ``2**x``, computed element-wise.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import exp2

        >>> exp2(3)
        8.0
        >>> x = np.array([[-1, -0.5, 0], [0.5, 1, 1.5]])
        >>> exp2(x)
        array([[ 0.5       ,  0.70710678,  1.        ],
               [ 1.41421356,  2.        ,  2.82842712]])

    expi = <ufunc 'expi'>
        expi(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        expi(x, out=None)

        Exponential integral Ei.

        For real :math:`x`, the exponential integral is defined as [1]_

        .. math::

            Ei(x) = \int_{-\infty}^x \frac{e^t}{t} dt.

        For :math:`x > 0` the integral is understood as a Cauchy principal
        value.

        It is extended to the complex plane by analytic continuation of
        the function on the interval :math:`(0, \infty)`. The complex
        variant has a branch cut on the negative real axis.

        Parameters
        ----------
        x : array_like
            Real or complex valued argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the exponential integral

        See Also
        --------
        exp1 : Exponential integral :math:`E_1`
        expn : Generalized exponential integral :math:`E_n`

        Notes
        -----
        The exponential integrals :math:`E_1` and :math:`Ei` satisfy the
        relation

        .. math::

            E_1(x) = -Ei(-x)

        for :math:`x > 0`.

        References
        ----------
        .. [1] Digital Library of Mathematical Functions, 6.2.5
               https://dlmf.nist.gov/6.2#E5

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is related to `exp1`.

        >>> x = np.array([1, 2, 3, 4])
        >>> -sc.expi(-x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])
        >>> sc.exp1(x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])

        The complex variant has a branch cut on the negative real axis.

        >>> sc.expi(-1 + 1e-12j)
        (-0.21938393439552062+3.1415926535894254j)
        >>> sc.expi(-1 - 1e-12j)
        (-0.21938393439552062-3.1415926535894254j)

        As the complex variant approaches the branch cut, the real parts
        approach the value of the real variant.

        >>> sc.expi(-1)
        -0.21938393439552062

        The SciPy implementation returns the real variant for complex
        values on the branch cut.

        >>> sc.expi(complex(-1, 0.0))
        (-0.21938393439552062-0j)
        >>> sc.expi(complex(-1, -0.0))
        (-0.21938393439552062-0j)

    expit = <ufunc 'expit'>
        expit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        expit(x, out=None)

        Expit (a.k.a. logistic sigmoid) ufunc for ndarrays.

        The expit function, also known as the logistic sigmoid function, is
        defined as ``expit(x) = 1/(1+exp(-x))``.  It is the inverse of the
        logit function.

        Parameters
        ----------
        x : ndarray
            The ndarray to apply expit to element-wise.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            An ndarray of the same shape as x. Its entries
            are `expit` of the corresponding entry of x.

        See Also
        --------
        logit

        Notes
        -----
        As a ufunc expit takes a number of optional
        keyword arguments. For more information
        see `ufuncs <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`_

        .. versionadded:: 0.10.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import expit, logit

        >>> expit([-np.inf, -1.5, 0, 1.5, np.inf])
        array([ 0.        ,  0.18242552,  0.5       ,  0.81757448,  1.        ])

        `logit` is the inverse of `expit`:

        >>> logit(expit([-2.5, 0, 3.1, 5.0]))
        array([-2.5,  0. ,  3.1,  5. ])

        Plot expit(x) for x in [-6, 6]:

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-6, 6, 121)
        >>> y = expit(x)
        >>> plt.plot(x, y)
        >>> plt.grid()
        >>> plt.xlim(-6, 6)
        >>> plt.xlabel('x')
        >>> plt.title('expit(x)')
        >>> plt.show()

    expm1 = <ufunc 'expm1'>
        expm1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        expm1(x, out=None)

        Compute ``exp(x) - 1``.

        When `x` is near zero, ``exp(x)`` is near 1, so the numerical calculation
        of ``exp(x) - 1`` can suffer from catastrophic loss of precision.
        ``expm1(x)`` is implemented to avoid the loss of precision that occurs when
        `x` is near zero.

        Parameters
        ----------
        x : array_like
            `x` must contain real numbers.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            ``exp(x) - 1`` computed element-wise.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import expm1

        >>> expm1(1.0)
        1.7182818284590451
        >>> expm1([-0.2, -0.1, 0, 0.1, 0.2])
        array([-0.18126925, -0.09516258,  0.        ,  0.10517092,  0.22140276])

        The exact value of ``exp(7.5e-13) - 1`` is::

            7.5000000000028125000000007031250000001318...*10**-13.

        Here is what ``expm1(7.5e-13)`` gives:

        >>> expm1(7.5e-13)
        7.5000000000028135e-13

        Compare that to ``exp(7.5e-13) - 1``, where the subtraction results in
        a "catastrophic" loss of precision:

        >>> np.exp(7.5e-13) - 1
        7.5006667543675576e-13

    expn = <ufunc 'expn'>
        expn(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        expn(n, x, out=None)

        Generalized exponential integral En.

        For integer :math:`n \geq 0` and real :math:`x \geq 0` the
        generalized exponential integral is defined as [dlmf]_

        .. math::

            E_n(x) = x^{n - 1} \int_x^\infty \frac{e^{-t}}{t^n} dt.

        Parameters
        ----------
        n : array_like
            Non-negative integers
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the generalized exponential integral

        See Also
        --------
        exp1 : special case of :math:`E_n` for :math:`n = 1`
        expi : related to :math:`E_n` when :math:`n = 1`

        References
        ----------
        .. [dlmf] Digital Library of Mathematical Functions, 8.19.2
                  https://dlmf.nist.gov/8.19#E2

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        Its domain is nonnegative n and x.

        >>> sc.expn(-1, 1.0), sc.expn(1, -1.0)
        (nan, nan)

        It has a pole at ``x = 0`` for ``n = 1, 2``; for larger ``n`` it
        is equal to ``1 / (n - 1)``.

        >>> sc.expn([0, 1, 2, 3, 4], 0)
        array([       inf,        inf, 1.        , 0.5       , 0.33333333])

        For n equal to 0 it reduces to ``exp(-x) / x``.

        >>> x = np.array([1, 2, 3, 4])
        >>> sc.expn(0, x)
        array([0.36787944, 0.06766764, 0.01659569, 0.00457891])
        >>> np.exp(-x) / x
        array([0.36787944, 0.06766764, 0.01659569, 0.00457891])

        For n equal to 1 it reduces to `exp1`.

        >>> sc.expn(1, x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])
        >>> sc.exp1(x)
        array([0.21938393, 0.04890051, 0.01304838, 0.00377935])

    exprel = <ufunc 'exprel'>
        exprel(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        exprel(x, out=None)

        Relative error exponential, ``(exp(x) - 1)/x``.

        When `x` is near zero, ``exp(x)`` is near 1, so the numerical calculation
        of ``exp(x) - 1`` can suffer from catastrophic loss of precision.
        ``exprel(x)`` is implemented to avoid the loss of precision that occurs when
        `x` is near zero.

        Parameters
        ----------
        x : ndarray
            Input array.  `x` must contain real numbers.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            ``(exp(x) - 1)/x``, computed element-wise.

        See Also
        --------
        expm1

        Notes
        -----
        .. versionadded:: 0.17.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import exprel

        >>> exprel(0.01)
        1.0050167084168056
        >>> exprel([-0.25, -0.1, 0, 0.1, 0.25])
        array([ 0.88479687,  0.95162582,  1.        ,  1.05170918,  1.13610167])

        Compare ``exprel(5e-9)`` to the naive calculation.  The exact value
        is ``1.00000000250000000416...``.

        >>> exprel(5e-9)
        1.0000000025

        >>> (np.exp(5e-9) - 1)/5e-9
        0.99999999392252903

    fdtr = <ufunc 'fdtr'>
        fdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        fdtr(dfn, dfd, x, out=None)

        F cumulative distribution function.

        Returns the value of the cumulative distribution function of the
        F-distribution, also known as Snedecor's F-distribution or the
        Fisher-Snedecor distribution.

        The F-distribution with parameters :math:`d_n` and :math:`d_d` is the
        distribution of the random variable,

        .. math::
            X = \frac{U_n/d_n}{U_d/d_d},

        where :math:`U_n` and :math:`U_d` are random variables distributed
        :math:`\chi^2`, with :math:`d_n` and :math:`d_d` degrees of freedom,
        respectively.

        Parameters
        ----------
        dfn : array_like
            First parameter (positive float).
        dfd : array_like
            Second parameter (positive float).
        x : array_like
            Argument (nonnegative float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            The CDF of the F-distribution with parameters `dfn` and `dfd` at `x`.

        See Also
        --------
        fdtrc : F distribution survival function
        fdtri : F distribution inverse cumulative distribution
        scipy.stats.f : F distribution

        Notes
        -----
        The regularized incomplete beta function is used, according to the
        formula,

        .. math::
            F(d_n, d_d; x) = I_{xd_n/(d_d + xd_n)}(d_n/2, d_d/2).

        Wrapper for the Cephes [1]_ routine `fdtr`. The F distribution is also
        available as `scipy.stats.f`. Calling `fdtr` directly can improve
        performance compared to the ``cdf`` method of `scipy.stats.f` (see last
        example below).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function for ``dfn=1`` and ``dfd=2`` at ``x=1``.

        >>> import numpy as np
        >>> from scipy.special import fdtr
        >>> fdtr(1, 2, 1)
        0.5773502691896258

        Calculate the function at several points by providing a NumPy array for
        `x`.

        >>> x = np.array([0.5, 2., 3.])
        >>> fdtr(1, 2, x)
        array([0.4472136 , 0.70710678, 0.77459667])

        Plot the function for several parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> dfn_parameters = [1, 5, 10, 50]
        >>> dfd_parameters = [1, 1, 2, 3]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(dfn_parameters, dfd_parameters,
        ...                            linestyles))
        >>> x = np.linspace(0, 30, 1000)
        >>> fig, ax = plt.subplots()
        >>> for parameter_set in parameters_list:
        ...     dfn, dfd, style = parameter_set
        ...     fdtr_vals = fdtr(dfn, dfd, x)
        ...     ax.plot(x, fdtr_vals, label=rf"$d_n={dfn},\, d_d={dfd}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title("F distribution cumulative distribution function")
        >>> plt.show()

        The F distribution is also available as `scipy.stats.f`. Using `fdtr`
        directly can be much faster than calling the ``cdf`` method of
        `scipy.stats.f`, especially for small arrays or individual values.
        To get the same results one must use the following parametrization:
        ``stats.f(dfn, dfd).cdf(x)=fdtr(dfn, dfd, x)``.

        >>> from scipy.stats import f
        >>> dfn, dfd = 1, 2
        >>> x = 1
        >>> fdtr_res = fdtr(dfn, dfd, x)  # this will often be faster than below
        >>> f_dist_res = f(dfn, dfd).cdf(x)
        >>> fdtr_res == f_dist_res  # test that results are equal
        True

    fdtrc = <ufunc 'fdtrc'>
        fdtrc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        fdtrc(dfn, dfd, x, out=None)

        F survival function.

        Returns the complemented F-distribution function (the integral of the
        density from `x` to infinity).

        Parameters
        ----------
        dfn : array_like
            First parameter (positive float).
        dfd : array_like
            Second parameter (positive float).
        x : array_like
            Argument (nonnegative float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y : scalar or ndarray
            The complemented F-distribution function with parameters `dfn` and
            `dfd` at `x`.

        See Also
        --------
        fdtr : F distribution cumulative distribution function
        fdtri : F distribution inverse cumulative distribution function
        scipy.stats.f : F distribution

        Notes
        -----
        The regularized incomplete beta function is used, according to the
        formula,

        .. math::
            F(d_n, d_d; x) = I_{d_d/(d_d + xd_n)}(d_d/2, d_n/2).

        Wrapper for the Cephes [1]_ routine `fdtrc`. The F distribution is also
        available as `scipy.stats.f`. Calling `fdtrc` directly can improve
        performance compared to the ``sf`` method of `scipy.stats.f` (see last
        example below).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function for ``dfn=1`` and ``dfd=2`` at ``x=1``.

        >>> import numpy as np
        >>> from scipy.special import fdtrc
        >>> fdtrc(1, 2, 1)
        0.42264973081037427

        Calculate the function at several points by providing a NumPy array for
        `x`.

        >>> x = np.array([0.5, 2., 3.])
        >>> fdtrc(1, 2, x)
        array([0.5527864 , 0.29289322, 0.22540333])

        Plot the function for several parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> dfn_parameters = [1, 5, 10, 50]
        >>> dfd_parameters = [1, 1, 2, 3]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(dfn_parameters, dfd_parameters,
        ...                            linestyles))
        >>> x = np.linspace(0, 30, 1000)
        >>> fig, ax = plt.subplots()
        >>> for parameter_set in parameters_list:
        ...     dfn, dfd, style = parameter_set
        ...     fdtrc_vals = fdtrc(dfn, dfd, x)
        ...     ax.plot(x, fdtrc_vals, label=rf"$d_n={dfn},\, d_d={dfd}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title("F distribution survival function")
        >>> plt.show()

        The F distribution is also available as `scipy.stats.f`. Using `fdtrc`
        directly can be much faster than calling the ``sf`` method of
        `scipy.stats.f`, especially for small arrays or individual values.
        To get the same results one must use the following parametrization:
        ``stats.f(dfn, dfd).sf(x)=fdtrc(dfn, dfd, x)``.

        >>> from scipy.stats import f
        >>> dfn, dfd = 1, 2
        >>> x = 1
        >>> fdtrc_res = fdtrc(dfn, dfd, x)  # this will often be faster than below
        >>> f_dist_res = f(dfn, dfd).sf(x)
        >>> f_dist_res == fdtrc_res  # test that results are equal
        True

    fdtri = <ufunc 'fdtri'>
        fdtri(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        fdtri(dfn, dfd, p, out=None)

        The `p`-th quantile of the F-distribution.

        This function is the inverse of the F-distribution CDF, `fdtr`, returning
        the `x` such that `fdtr(dfn, dfd, x) = p`.

        Parameters
        ----------
        dfn : array_like
            First parameter (positive float).
        dfd : array_like
            Second parameter (positive float).
        p : array_like
            Cumulative probability, in [0, 1].
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        x : scalar or ndarray
            The quantile corresponding to `p`.

        See Also
        --------
        fdtr : F distribution cumulative distribution function
        fdtrc : F distribution survival function
        scipy.stats.f : F distribution

        Notes
        -----
        The computation is carried out using the relation to the inverse
        regularized beta function, :math:`I^{-1}_x(a, b)`.  Let
        :math:`z = I^{-1}_p(d_d/2, d_n/2).`  Then,

        .. math::
            x = \frac{d_d (1 - z)}{d_n z}.

        If `p` is such that :math:`x < 0.5`, the following relation is used
        instead for improved stability: let
        :math:`z' = I^{-1}_{1 - p}(d_n/2, d_d/2).` Then,

        .. math::
            x = \frac{d_d z'}{d_n (1 - z')}.

        Wrapper for the Cephes [1]_ routine `fdtri`.

        The F distribution is also available as `scipy.stats.f`. Calling
        `fdtri` directly can improve performance compared to the ``ppf``
        method of `scipy.stats.f` (see last example below).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        `fdtri` represents the inverse of the F distribution CDF which is
        available as `fdtr`. Here, we calculate the CDF for ``df1=1``, ``df2=2``
        at ``x=3``. `fdtri` then returns ``3`` given the same values for `df1`,
        `df2` and the computed CDF value.

        >>> import numpy as np
        >>> from scipy.special import fdtri, fdtr
        >>> df1, df2 = 1, 2
        >>> x = 3
        >>> cdf_value =  fdtr(df1, df2, x)
        >>> fdtri(df1, df2, cdf_value)
        3.000000000000006

        Calculate the function at several points by providing a NumPy array for
        `x`.

        >>> x = np.array([0.1, 0.4, 0.7])
        >>> fdtri(1, 2, x)
        array([0.02020202, 0.38095238, 1.92156863])

        Plot the function for several parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> dfn_parameters = [50, 10, 1, 50]
        >>> dfd_parameters = [0.5, 1, 1, 5]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(dfn_parameters, dfd_parameters,
        ...                            linestyles))
        >>> x = np.linspace(0, 1, 1000)
        >>> fig, ax = plt.subplots()
        >>> for parameter_set in parameters_list:
        ...     dfn, dfd, style = parameter_set
        ...     fdtri_vals = fdtri(dfn, dfd, x)
        ...     ax.plot(x, fdtri_vals, label=rf"$d_n={dfn},\, d_d={dfd}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$x$")
        >>> title = "F distribution inverse cumulative distribution function"
        >>> ax.set_title(title)
        >>> ax.set_ylim(0, 30)
        >>> plt.show()

        The F distribution is also available as `scipy.stats.f`. Using `fdtri`
        directly can be much faster than calling the ``ppf`` method of
        `scipy.stats.f`, especially for small arrays or individual values.
        To get the same results one must use the following parametrization:
        ``stats.f(dfn, dfd).ppf(x)=fdtri(dfn, dfd, x)``.

        >>> from scipy.stats import f
        >>> dfn, dfd = 1, 2
        >>> x = 0.7
        >>> fdtri_res = fdtri(dfn, dfd, x)  # this will often be faster than below
        >>> f_dist_res = f(dfn, dfd).ppf(x)
        >>> f_dist_res == fdtri_res  # test that results are equal
        True

    fdtridfd = <ufunc 'fdtridfd'>
        fdtridfd(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        fdtridfd(dfn, p, x, out=None)

        Inverse to `fdtr` vs dfd

        Finds the F density argument dfd such that ``fdtr(dfn, dfd, x) == p``.

        Parameters
        ----------
        dfn : array_like
            First parameter (positive float).
        p : array_like
            Cumulative probability, in [0, 1].
        x : array_like
            Argument (nonnegative float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        dfd : scalar or ndarray
            `dfd` such that ``fdtr(dfn, dfd, x) == p``.

        See Also
        --------
        fdtr : F distribution cumulative distribution function
        fdtrc : F distribution survival function
        fdtri : F distribution quantile function
        scipy.stats.f : F distribution

        Examples
        --------
        Compute the F distribution cumulative distribution function for one
        parameter set.

        >>> from scipy.special import fdtridfd, fdtr
        >>> dfn, dfd, x = 10, 5, 2
        >>> cdf_value = fdtr(dfn, dfd, x)
        >>> cdf_value
        0.7700248806501017

        Verify that `fdtridfd` recovers the original value for `dfd`:

        >>> fdtridfd(dfn, cdf_value, x)
        5.0

    fresnel = <ufunc 'fresnel'>
        fresnel(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        fresnel(z, out=None)

        Fresnel integrals.

        The Fresnel integrals are defined as

        .. math::

           S(z) &= \int_0^z \sin(\pi t^2 /2) dt \\
           C(z) &= \int_0^z \cos(\pi t^2 /2) dt.

        See [dlmf]_ for details.

        Parameters
        ----------
        z : array_like
            Real or complex valued argument
        out : 2-tuple of ndarrays, optional
            Optional output arrays for the function results

        Returns
        -------
        S, C : 2-tuple of scalar or ndarray
            Values of the Fresnel integrals

        See Also
        --------
        fresnel_zeros : zeros of the Fresnel integrals

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/7.2#iii

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        As z goes to infinity along the real axis, S and C converge to 0.5.

        >>> S, C = sc.fresnel([0.1, 1, 10, 100, np.inf])
        >>> S
        array([0.00052359, 0.43825915, 0.46816998, 0.4968169 , 0.5       ])
        >>> C
        array([0.09999753, 0.7798934 , 0.49989869, 0.4999999 , 0.5       ])

        They are related to the error function `erf`.

        >>> z = np.array([1, 2, 3, 4])
        >>> zeta = 0.5 * np.sqrt(np.pi) * (1 - 1j) * z
        >>> S, C = sc.fresnel(z)
        >>> C + 1j*S
        array([0.7798934 +0.43825915j, 0.48825341+0.34341568j,
               0.60572079+0.496313j  , 0.49842603+0.42051575j])
        >>> 0.5 * (1 + 1j) * sc.erf(zeta)
        array([0.7798934 +0.43825915j, 0.48825341+0.34341568j,
               0.60572079+0.496313j  , 0.49842603+0.42051575j])

    gamma = <ufunc 'gamma'>
        gamma(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        gamma(z, out=None)

        gamma function.

        The gamma function is defined as

        .. math::

           \Gamma(z) = \int_0^\infty t^{z-1} e^{-t} dt

        for :math:`\Re(z) > 0` and is extended to the rest of the complex
        plane by analytic continuation. See [dlmf]_ for more details.

        Parameters
        ----------
        z : array_like
            Real or complex valued argument
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the gamma function

        Notes
        -----
        The gamma function is often referred to as the generalized
        factorial since :math:`\Gamma(n + 1) = n!` for natural numbers
        :math:`n`. More generally it satisfies the recurrence relation
        :math:`\Gamma(z + 1) = z \cdot \Gamma(z)` for complex :math:`z`,
        which, combined with the fact that :math:`\Gamma(1) = 1`, implies
        the above identity for :math:`z = n`.

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/5.2#E1

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import gamma, factorial

        >>> gamma([0, 0.5, 1, 5])
        array([         inf,   1.77245385,   1.        ,  24.        ])

        >>> z = 2.5 + 1j
        >>> gamma(z)
        (0.77476210455108352+0.70763120437959293j)
        >>> gamma(z+1), z*gamma(z)  # Recurrence property
        ((1.2292740569981171+2.5438401155000685j),
         (1.2292740569981158+2.5438401155000658j))

        >>> gamma(0.5)**2  # gamma(0.5) = sqrt(pi)
        3.1415926535897927

        Plot gamma(x) for real x

        >>> x = np.linspace(-3.5, 5.5, 2251)
        >>> y = gamma(x)

        >>> import matplotlib.pyplot as plt
        >>> plt.plot(x, y, 'b', alpha=0.6, label='gamma(x)')
        >>> k = np.arange(1, 7)
        >>> plt.plot(k, factorial(k-1), 'k*', alpha=0.6,
        ...          label='(x-1)!, x = 1, 2, ...')
        >>> plt.xlim(-3.5, 5.5)
        >>> plt.ylim(-10, 25)
        >>> plt.grid()
        >>> plt.xlabel('x')
        >>> plt.legend(loc='lower right')
        >>> plt.show()

    gammainc = <ufunc 'gammainc'>
        gammainc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gammainc(a, x, out=None)

        Regularized lower incomplete gamma function.

        It is defined as

        .. math::

            P(a, x) = \frac{1}{\Gamma(a)} \int_0^x t^{a - 1}e^{-t} dt

        for :math:`a > 0` and :math:`x \geq 0`. See [dlmf]_ for details.

        Parameters
        ----------
        a : array_like
            Positive parameter
        x : array_like
            Nonnegative argument
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the lower incomplete gamma function

        See Also
        --------
        gammaincc : regularized upper incomplete gamma function
        gammaincinv : inverse of the regularized lower incomplete gamma function
        gammainccinv : inverse of the regularized upper incomplete gamma function

        Notes
        -----
        The function satisfies the relation ``gammainc(a, x) +
        gammaincc(a, x) = 1`` where `gammaincc` is the regularized upper
        incomplete gamma function.

        The implementation largely follows that of [boost]_.

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical functions
                  https://dlmf.nist.gov/8.2#E4
        .. [boost] Maddock et. al., "Incomplete Gamma Functions",
           https://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html

        Examples
        --------
        >>> import scipy.special as sc

        It is the CDF of the gamma distribution, so it starts at 0 and
        monotonically increases to 1.

        >>> sc.gammainc(0.5, [0, 1, 10, 100])
        array([0.        , 0.84270079, 0.99999226, 1.        ])

        It is equal to one minus the upper incomplete gamma function.

        >>> a, x = 0.5, 0.4
        >>> sc.gammainc(a, x)
        0.6289066304773024
        >>> 1 - sc.gammaincc(a, x)
        0.6289066304773024

    gammaincc = <ufunc 'gammaincc'>
        gammaincc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gammaincc(a, x, out=None)

        Regularized upper incomplete gamma function.

        It is defined as

        .. math::

            Q(a, x) = \frac{1}{\Gamma(a)} \int_x^\infty t^{a - 1}e^{-t} dt

        for :math:`a > 0` and :math:`x \geq 0`. See [dlmf]_ for details.

        Parameters
        ----------
        a : array_like
            Positive parameter
        x : array_like
            Nonnegative argument
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the upper incomplete gamma function

        See Also
        --------
        gammainc : regularized lower incomplete gamma function
        gammaincinv : inverse of the regularized lower incomplete gamma function
        gammainccinv : inverse of the regularized upper incomplete gamma function

        Notes
        -----
        The function satisfies the relation ``gammainc(a, x) +
        gammaincc(a, x) = 1`` where `gammainc` is the regularized lower
        incomplete gamma function.

        The implementation largely follows that of [boost]_.

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical functions
                  https://dlmf.nist.gov/8.2#E4
        .. [boost] Maddock et. al., "Incomplete Gamma Functions",
           https://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html

        Examples
        --------
        >>> import scipy.special as sc

        It is the survival function of the gamma distribution, so it
        starts at 1 and monotonically decreases to 0.

        >>> sc.gammaincc(0.5, [0, 1, 10, 100, 1000])
        array([1.00000000e+00, 1.57299207e-01, 7.74421643e-06, 2.08848758e-45,
               0.00000000e+00])

        It is equal to one minus the lower incomplete gamma function.

        >>> a, x = 0.5, 0.4
        >>> sc.gammaincc(a, x)
        0.37109336952269756
        >>> 1 - sc.gammainc(a, x)
        0.37109336952269756

    gammainccinv = <ufunc 'gammainccinv'>
        gammainccinv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gammainccinv(a, y, out=None)

        Inverse of the regularized upper incomplete gamma function.

        Given an input :math:`y` between 0 and 1, returns :math:`x` such
        that :math:`y = Q(a, x)`. Here :math:`Q` is the regularized upper
        incomplete gamma function; see `gammaincc`. This is well-defined
        because the upper incomplete gamma function is monotonic as can
        be seen from its definition in [dlmf]_.

        Parameters
        ----------
        a : array_like
            Positive parameter
        y : array_like
            Argument between 0 and 1, inclusive
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the inverse of the upper incomplete gamma function

        See Also
        --------
        gammaincc : regularized upper incomplete gamma function
        gammainc : regularized lower incomplete gamma function
        gammaincinv : inverse of the regularized lower incomplete gamma function

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/8.2#E4

        Examples
        --------
        >>> import scipy.special as sc

        It starts at infinity and monotonically decreases to 0.

        >>> sc.gammainccinv(0.5, [0, 0.1, 0.5, 1])
        array([       inf, 1.35277173, 0.22746821, 0.        ])

        It inverts the upper incomplete gamma function.

        >>> a, x = 0.5, [0, 0.1, 0.5, 1]
        >>> sc.gammaincc(a, sc.gammainccinv(a, x))
        array([0. , 0.1, 0.5, 1. ])

        >>> a, x = 0.5, [0, 10, 50]
        >>> sc.gammainccinv(a, sc.gammaincc(a, x))
        array([ 0., 10., 50.])

    gammaincinv = <ufunc 'gammaincinv'>
        gammaincinv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gammaincinv(a, y, out=None)

        Inverse to the regularized lower incomplete gamma function.

        Given an input :math:`y` between 0 and 1, returns :math:`x` such
        that :math:`y = P(a, x)`. Here :math:`P` is the regularized lower
        incomplete gamma function; see `gammainc`. This is well-defined
        because the lower incomplete gamma function is monotonic as can be
        seen from its definition in [dlmf]_.

        Parameters
        ----------
        a : array_like
            Positive parameter
        y : array_like
            Parameter between 0 and 1, inclusive
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the inverse of the lower incomplete gamma function

        See Also
        --------
        gammainc : regularized lower incomplete gamma function
        gammaincc : regularized upper incomplete gamma function
        gammainccinv : inverse of the regularized upper incomplete gamma function

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/8.2#E4

        Examples
        --------
        >>> import scipy.special as sc

        It starts at 0 and monotonically increases to infinity.

        >>> sc.gammaincinv(0.5, [0, 0.1 ,0.5, 1])
        array([0.        , 0.00789539, 0.22746821,        inf])

        It inverts the lower incomplete gamma function.

        >>> a, x = 0.5, [0, 0.1, 0.5, 1]
        >>> sc.gammainc(a, sc.gammaincinv(a, x))
        array([0. , 0.1, 0.5, 1. ])

        >>> a, x = 0.5, [0, 10, 25]
        >>> sc.gammaincinv(a, sc.gammainc(a, x))
        array([ 0.        , 10.        , 25.00001465])

    gammaln = <ufunc 'gammaln'>
        gammaln(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        gammaln(x, out=None)

        Logarithm of the absolute value of the gamma function.

        Defined as

        .. math::

           \ln(\lvert\Gamma(x)\rvert)

        where :math:`\Gamma` is the gamma function. For more details on
        the gamma function, see [dlmf]_.

        Parameters
        ----------
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the log of the absolute value of gamma

        See Also
        --------
        gammasgn : sign of the gamma function
        loggamma : principal branch of the logarithm of the gamma function

        Notes
        -----
        It is the same function as the Python standard library function
        :func:`math.lgamma`.

        When used in conjunction with `gammasgn`, this function is useful
        for working in logspace on the real axis without having to deal
        with complex numbers via the relation ``exp(gammaln(x)) =
        gammasgn(x) * gamma(x)``.

        For complex-valued log-gamma, use `loggamma` instead of `gammaln`.

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/5

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It has two positive zeros.

        >>> sc.gammaln([1, 2])
        array([0., 0.])

        It has poles at nonpositive integers.

        >>> sc.gammaln([0, -1, -2, -3, -4])
        array([inf, inf, inf, inf, inf])

        It asymptotically approaches ``x * log(x)`` (Stirling's formula).

        >>> x = np.array([1e10, 1e20, 1e40, 1e80])
        >>> sc.gammaln(x)
        array([2.20258509e+11, 4.50517019e+21, 9.11034037e+41, 1.83206807e+82])
        >>> x * np.log(x)
        array([2.30258509e+11, 4.60517019e+21, 9.21034037e+41, 1.84206807e+82])

    gammasgn = <ufunc 'gammasgn'>
        gammasgn(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gammasgn(x, out=None)

        Sign of the gamma function.

        It is defined as

        .. math::

           \text{gammasgn}(x) =
           \begin{cases}
             +1 & \Gamma(x) > 0 \\
             -1 & \Gamma(x) < 0
           \end{cases}

        where :math:`\Gamma` is the gamma function; see `gamma`. This
        definition is complete since the gamma function is never zero;
        see the discussion after [dlmf]_.

        Parameters
        ----------
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Sign of the gamma function

        See Also
        --------
        gamma : the gamma function
        gammaln : log of the absolute value of the gamma function
        loggamma : analytic continuation of the log of the gamma function

        Notes
        -----
        The gamma function can be computed as ``gammasgn(x) *
        np.exp(gammaln(x))``.

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/5.2#E1

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is 1 for `x > 0`.

        >>> sc.gammasgn([1, 2, 3, 4])
        array([1., 1., 1., 1.])

        It alternates between -1 and 1 for negative integers.

        >>> sc.gammasgn([-0.5, -1.5, -2.5, -3.5])
        array([-1.,  1., -1.,  1.])

        It can be used to compute the gamma function.

        >>> x = [1.5, 0.5, -0.5, -1.5]
        >>> sc.gammasgn(x) * np.exp(sc.gammaln(x))
        array([ 0.88622693,  1.77245385, -3.5449077 ,  2.3632718 ])
        >>> sc.gamma(x)
        array([ 0.88622693,  1.77245385, -3.5449077 ,  2.3632718 ])

    gdtr = <ufunc 'gdtr'>
        gdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gdtr(a, b, x, out=None)

        Gamma distribution cumulative distribution function.

        Returns the integral from zero to `x` of the gamma probability density
        function,

        .. math::

            F = \int_0^x \frac{a^b}{\Gamma(b)} t^{b-1} e^{-at}\,dt,

        where :math:`\Gamma` is the gamma function.

        Parameters
        ----------
        a : array_like
            The rate parameter of the gamma distribution, sometimes denoted
            :math:`\beta` (float).  It is also the reciprocal of the scale
            parameter :math:`\theta`.
        b : array_like
            The shape parameter of the gamma distribution, sometimes denoted
            :math:`\alpha` (float).
        x : array_like
            The quantile (upper limit of integration; float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        F : scalar or ndarray
            The CDF of the gamma distribution with parameters `a` and `b`
            evaluated at `x`.

        See Also
        --------
        gdtrc : 1 - CDF of the gamma distribution.
        scipy.stats.gamma: Gamma distribution

        Notes
        -----
        The evaluation is carried out using the relation to the incomplete gamma
        integral (regularized gamma function).

        Wrapper for the Cephes [1]_ routine `gdtr`. Calling `gdtr` directly can
        improve performance compared to the ``cdf`` method of `scipy.stats.gamma`
        (see last example below).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Compute the function for ``a=1``, ``b=2`` at ``x=5``.

        >>> import numpy as np
        >>> from scipy.special import gdtr
        >>> import matplotlib.pyplot as plt
        >>> gdtr(1., 2., 5.)
        0.9595723180054873

        Compute the function for ``a=1`` and ``b=2`` at several points by
        providing a NumPy array for `x`.

        >>> xvalues = np.array([1., 2., 3., 4])
        >>> gdtr(1., 1., xvalues)
        array([0.63212056, 0.86466472, 0.95021293, 0.98168436])

        `gdtr` can evaluate different parameter sets by providing arrays with
        broadcasting compatible shapes for `a`, `b` and `x`. Here we compute the
        function for three different `a` at four positions `x` and ``b=3``,
        resulting in a 3x4 array.

        >>> a = np.array([[0.5], [1.5], [2.5]])
        >>> x = np.array([1., 2., 3., 4])
        >>> a.shape, x.shape
        ((3, 1), (4,))

        >>> gdtr(a, 3., x)
        array([[0.01438768, 0.0803014 , 0.19115317, 0.32332358],
               [0.19115317, 0.57680992, 0.82642193, 0.9380312 ],
               [0.45618688, 0.87534798, 0.97974328, 0.9972306 ]])

        Plot the function for four different parameter sets.

        >>> a_parameters = [0.3, 1, 2, 6]
        >>> b_parameters = [2, 10, 15, 20]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(a_parameters, b_parameters, linestyles))
        >>> x = np.linspace(0, 30, 1000)
        >>> fig, ax = plt.subplots()
        >>> for parameter_set in parameters_list:
        ...     a, b, style = parameter_set
        ...     gdtr_vals = gdtr(a, b, x)
        ...     ax.plot(x, gdtr_vals, label=fr"$a= {a},\, b={b}$", ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title("Gamma distribution cumulative distribution function")
        >>> plt.show()

        The gamma distribution is also available as `scipy.stats.gamma`. Using
        `gdtr` directly can be much faster than calling the ``cdf`` method of
        `scipy.stats.gamma`, especially for small arrays or individual values.
        To get the same results one must use the following parametrization:
        ``stats.gamma(b, scale=1/a).cdf(x)=gdtr(a, b, x)``.

        >>> from scipy.stats import gamma
        >>> a = 2.
        >>> b = 3
        >>> x = 1.
        >>> gdtr_result = gdtr(a, b, x)  # this will often be faster than below
        >>> gamma_dist_result = gamma(b, scale=1/a).cdf(x)
        >>> gdtr_result == gamma_dist_result  # test that results are equal
        True

    gdtrc = <ufunc 'gdtrc'>
        gdtrc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gdtrc(a, b, x, out=None)

        Gamma distribution survival function.

        Integral from `x` to infinity of the gamma probability density function,

        .. math::

            F = \int_x^\infty \frac{a^b}{\Gamma(b)} t^{b-1} e^{-at}\,dt,

        where :math:`\Gamma` is the gamma function.

        Parameters
        ----------
        a : array_like
            The rate parameter of the gamma distribution, sometimes denoted
            :math:`\beta` (float). It is also the reciprocal of the scale
            parameter :math:`\theta`.
        b : array_like
            The shape parameter of the gamma distribution, sometimes denoted
            :math:`\alpha` (float).
        x : array_like
            The quantile (lower limit of integration; float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        F : scalar or ndarray
            The survival function of the gamma distribution with parameters `a`
            and `b` evaluated at `x`.

        See Also
        --------
        gdtr: Gamma distribution cumulative distribution function
        scipy.stats.gamma: Gamma distribution
        gdtrix

        Notes
        -----
        The evaluation is carried out using the relation to the incomplete gamma
        integral (regularized gamma function).

        Wrapper for the Cephes [1]_ routine `gdtrc`. Calling `gdtrc` directly can
        improve performance compared to the ``sf`` method of `scipy.stats.gamma`
        (see last example below).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Compute the function for ``a=1`` and ``b=2`` at ``x=5``.

        >>> import numpy as np
        >>> from scipy.special import gdtrc
        >>> import matplotlib.pyplot as plt
        >>> gdtrc(1., 2., 5.)
        0.04042768199451279

        Compute the function for ``a=1``, ``b=2`` at several points by providing
        a NumPy array for `x`.

        >>> xvalues = np.array([1., 2., 3., 4])
        >>> gdtrc(1., 1., xvalues)
        array([0.36787944, 0.13533528, 0.04978707, 0.01831564])

        `gdtrc` can evaluate different parameter sets by providing arrays with
        broadcasting compatible shapes for `a`, `b` and `x`. Here we compute the
        function for three different `a` at four positions `x` and ``b=3``,
        resulting in a 3x4 array.

        >>> a = np.array([[0.5], [1.5], [2.5]])
        >>> x = np.array([1., 2., 3., 4])
        >>> a.shape, x.shape
        ((3, 1), (4,))

        >>> gdtrc(a, 3., x)
        array([[0.98561232, 0.9196986 , 0.80884683, 0.67667642],
               [0.80884683, 0.42319008, 0.17357807, 0.0619688 ],
               [0.54381312, 0.12465202, 0.02025672, 0.0027694 ]])

        Plot the function for four different parameter sets.

        >>> a_parameters = [0.3, 1, 2, 6]
        >>> b_parameters = [2, 10, 15, 20]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(a_parameters, b_parameters, linestyles))
        >>> x = np.linspace(0, 30, 1000)
        >>> fig, ax = plt.subplots()
        >>> for parameter_set in parameters_list:
        ...     a, b, style = parameter_set
        ...     gdtrc_vals = gdtrc(a, b, x)
        ...     ax.plot(x, gdtrc_vals, label=fr"$a= {a},\, b={b}$", ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title("Gamma distribution survival function")
        >>> plt.show()

        The gamma distribution is also available as `scipy.stats.gamma`.
        Using `gdtrc` directly can be much faster than calling the ``sf`` method
        of `scipy.stats.gamma`, especially for small arrays or individual
        values. To get the same results one must use the following parametrization:
        ``stats.gamma(b, scale=1/a).sf(x)=gdtrc(a, b, x)``.

        >>> from scipy.stats import gamma
        >>> a = 2
        >>> b = 3
        >>> x = 1.
        >>> gdtrc_result = gdtrc(a, b, x)  # this will often be faster than below
        >>> gamma_dist_result = gamma(b, scale=1/a).sf(x)
        >>> gdtrc_result == gamma_dist_result  # test that results are equal
        True

    gdtria = <ufunc 'gdtria'>
        gdtria(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gdtria(p, b, x, out=None)

        Inverse of `gdtr` vs a.

        Returns the inverse with respect to the parameter `a` of ``p =
        gdtr(a, b, x)``, the cumulative distribution function of the gamma
        distribution.

        Parameters
        ----------
        p : array_like
            Probability values.
        b : array_like
            `b` parameter values of `gdtr(a, b, x)`. `b` is the "shape" parameter
            of the gamma distribution.
        x : array_like
            Nonnegative real values, from the domain of the gamma distribution.
        out : ndarray, optional
            If a fourth argument is given, it must be a numpy.ndarray whose size
            matches the broadcast result of `a`, `b` and `x`.  `out` is then the
            array returned by the function.

        Returns
        -------
        a : scalar or ndarray
            Values of the `a` parameter such that `p = gdtr(a, b, x)`.  `1/a`
            is the "scale" parameter of the gamma distribution.

        See Also
        --------
        gdtr : CDF of the gamma distribution.
        gdtrib : Inverse with respect to `b` of `gdtr(a, b, x)`.
        gdtrix : Inverse with respect to `x` of `gdtr(a, b, x)`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfgam`.

        The cumulative distribution function `p` is computed using a routine by
        DiDinato and Morris [2]_. Computation of `a` involves a search for a value
        that produces the desired value of `p`. The search relies on the
        monotonicity of `p` with `a`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] DiDinato, A. R. and Morris, A. H.,
               Computation of the incomplete gamma function ratios and their
               inverse.  ACM Trans. Math. Softw. 12 (1986), 377-393.

        Examples
        --------
        First evaluate `gdtr`.

        >>> from scipy.special import gdtr, gdtria
        >>> p = gdtr(1.2, 3.4, 5.6)
        >>> print(p)
        0.94378087442

        Verify the inverse.

        >>> gdtria(p, 3.4, 5.6)
        1.2

    gdtrib = <ufunc 'gdtrib'>
        gdtrib(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gdtrib(a, p, x, out=None)

        Inverse of `gdtr` vs b.

        Returns the inverse with respect to the parameter `b` of ``p =
        gdtr(a, b, x)``, the cumulative distribution function of the gamma
        distribution.

        Parameters
        ----------
        a : array_like
            `a` parameter values of `gdtr(a, b, x)`. `1/a` is the "scale"
            parameter of the gamma distribution.
        p : array_like
            Probability values.
        x : array_like
            Nonnegative real values, from the domain of the gamma distribution.
        out : ndarray, optional
            If a fourth argument is given, it must be a numpy.ndarray whose size
            matches the broadcast result of `a`, `b` and `x`.  `out` is then the
            array returned by the function.

        Returns
        -------
        b : scalar or ndarray
            Values of the `b` parameter such that `p = gdtr(a, b, x)`.  `b` is
            the "shape" parameter of the gamma distribution.

        See Also
        --------
        gdtr : CDF of the gamma distribution.
        gdtria : Inverse with respect to `a` of `gdtr(a, b, x)`.
        gdtrix : Inverse with respect to `x` of `gdtr(a, b, x)`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfgam`.

        The cumulative distribution function `p` is computed using a routine by
        DiDinato and Morris [2]_. Computation of `b` involves a search for a value
        that produces the desired value of `p`. The search relies on the
        monotonicity of `p` with `b`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] DiDinato, A. R. and Morris, A. H.,
               Computation of the incomplete gamma function ratios and their
               inverse.  ACM Trans. Math. Softw. 12 (1986), 377-393.

        Examples
        --------
        First evaluate `gdtr`.

        >>> from scipy.special import gdtr, gdtrib
        >>> p = gdtr(1.2, 3.4, 5.6)
        >>> print(p)
        0.94378087442

        Verify the inverse.

        >>> gdtrib(1.2, p, 5.6)
        3.3999999999723882

    gdtrix = <ufunc 'gdtrix'>
        gdtrix(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        gdtrix(a, b, p, out=None)

        Inverse of `gdtr` vs x.

        Returns the inverse with respect to the parameter `x` of ``p =
        gdtr(a, b, x)``, the cumulative distribution function of the gamma
        distribution. This is also known as the pth quantile of the
        distribution.

        Parameters
        ----------
        a : array_like
            `a` parameter values of `gdtr(a, b, x)`. `1/a` is the "scale"
            parameter of the gamma distribution.
        b : array_like
            `b` parameter values of `gdtr(a, b, x)`. `b` is the "shape" parameter
            of the gamma distribution.
        p : array_like
            Probability values.
        out : ndarray, optional
            If a fourth argument is given, it must be a numpy.ndarray whose size
            matches the broadcast result of `a`, `b` and `x`. `out` is then the
            array returned by the function.

        Returns
        -------
        x : scalar or ndarray
            Values of the `x` parameter such that `p = gdtr(a, b, x)`.

        See Also
        --------
        gdtr : CDF of the gamma distribution.
        gdtria : Inverse with respect to `a` of `gdtr(a, b, x)`.
        gdtrib : Inverse with respect to `b` of `gdtr(a, b, x)`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfgam`.

        The cumulative distribution function `p` is computed using a routine by
        DiDinato and Morris [2]_. Computation of `x` involves a search for a value
        that produces the desired value of `p`. The search relies on the
        monotonicity of `p` with `x`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] DiDinato, A. R. and Morris, A. H.,
               Computation of the incomplete gamma function ratios and their
               inverse.  ACM Trans. Math. Softw. 12 (1986), 377-393.

        Examples
        --------
        First evaluate `gdtr`.

        >>> from scipy.special import gdtr, gdtrix
        >>> p = gdtr(1.2, 3.4, 5.6)
        >>> print(p)
        0.94378087442

        Verify the inverse.

        >>> gdtrix(1.2, 3.4, p)
        5.5999999999999996

    hankel1 = <ufunc 'hankel1'>
        hankel1(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        hankel1(v, z, out=None)

        Hankel function of the first kind

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the Hankel function of the first kind.

        See Also
        --------
        hankel1e : ndarray
            This function with leading exponential behavior stripped off.

        Notes
        -----
        A wrapper for the AMOS [1]_ routine `zbesh`, which carries out the
        computation using the relation,

        .. math:: H^{(1)}_v(z) =
                  \frac{2}{\imath\pi} \exp(-\imath \pi v/2) K_v(z \exp(-\imath\pi/2))

        where :math:`K_v` is the modified Bessel function of the second kind.
        For negative orders, the relation

        .. math:: H^{(1)}_{-v}(z) = H^{(1)}_v(z) \exp(\imath\pi v)

        is used.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

    hankel1e = <ufunc 'hankel1e'>
        hankel1e(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        hankel1e(v, z, out=None)

        Exponentially scaled Hankel function of the first kind

        Defined as::

            hankel1e(v, z) = hankel1(v, z) * exp(-1j * z)

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the exponentially scaled Hankel function.

        Notes
        -----
        A wrapper for the AMOS [1]_ routine `zbesh`, which carries out the
        computation using the relation,

        .. math:: H^{(1)}_v(z) =
                  \frac{2}{\imath\pi} \exp(-\imath \pi v/2) K_v(z \exp(-\imath\pi/2))

        where :math:`K_v` is the modified Bessel function of the second kind.
        For negative orders, the relation

        .. math:: H^{(1)}_{-v}(z) = H^{(1)}_v(z) \exp(\imath\pi v)

        is used.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

    hankel2 = <ufunc 'hankel2'>
        hankel2(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        hankel2(v, z, out=None)

        Hankel function of the second kind

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the Hankel function of the second kind.

        See Also
        --------
        hankel2e : this function with leading exponential behavior stripped off.

        Notes
        -----
        A wrapper for the AMOS [1]_ routine `zbesh`, which carries out the
        computation using the relation,

        .. math:: H^{(2)}_v(z) =
                  -\frac{2}{\imath\pi} \exp(\imath \pi v/2) K_v(z \exp(\imath\pi/2))

        where :math:`K_v` is the modified Bessel function of the second kind.
        For negative orders, the relation

        .. math:: H^{(2)}_{-v}(z) = H^{(2)}_v(z) \exp(-\imath\pi v)

        is used.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

    hankel2e = <ufunc 'hankel2e'>
        hankel2e(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        hankel2e(v, z, out=None)

        Exponentially scaled Hankel function of the second kind

        Defined as::

            hankel2e(v, z) = hankel2(v, z) * exp(1j * z)

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the exponentially scaled Hankel function of the second kind.

        Notes
        -----
        A wrapper for the AMOS [1]_ routine `zbesh`, which carries out the
        computation using the relation,

        .. math:: H^{(2)}_v(z) = -\frac{2}{\imath\pi}
                  \exp(\frac{\imath \pi v}{2}) K_v(z exp(\frac{\imath\pi}{2}))

        where :math:`K_v` is the modified Bessel function of the second kind.
        For negative orders, the relation

        .. math:: H^{(2)}_{-v}(z) = H^{(2)}_v(z) \exp(-\imath\pi v)

        is used.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

    huber = <ufunc 'huber'>
        huber(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        huber(delta, r, out=None)

        Huber loss function.

        .. math:: \text{huber}(\delta, r) = \begin{cases} \infty & \delta < 0  \\
                  \frac{1}{2}r^2 & 0 \le \delta, | r | \le \delta \\
                  \delta ( |r| - \frac{1}{2}\delta ) & \text{otherwise} \end{cases}

        Parameters
        ----------
        delta : ndarray
            Input array, indicating the quadratic vs. linear loss changepoint.
        r : ndarray
            Input array, possibly representing residuals.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            The computed Huber loss function values.

        See Also
        --------
        pseudo_huber : smooth approximation of this function

        Notes
        -----
        `huber` is useful as a loss function in robust statistics or machine
        learning to reduce the influence of outliers as compared to the common
        squared error loss, residuals with a magnitude higher than `delta` are
        not squared [1]_.

        Typically, `r` represents residuals, the difference
        between a model prediction and data. Then, for :math:`|r|\leq\delta`,
        `huber` resembles the squared error and for :math:`|r|>\delta` the
        absolute error. This way, the Huber loss often achieves
        a fast convergence in model fitting for small residuals like the squared
        error loss function and still reduces the influence of outliers
        (:math:`|r|>\delta`) like the absolute error loss. As :math:`\delta` is
        the cutoff between squared and absolute error regimes, it has
        to be tuned carefully for each problem. `huber` is also
        convex, making it suitable for gradient based optimization.

        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Peter Huber. "Robust Estimation of a Location Parameter",
               1964. Annals of Statistics. 53 (1): 73 - 101.

        Examples
        --------
        Import all necessary modules.

        >>> import numpy as np
        >>> from scipy.special import huber
        >>> import matplotlib.pyplot as plt

        Compute the function for ``delta=1`` at ``r=2``

        >>> huber(1., 2.)
        1.5

        Compute the function for different `delta` by providing a NumPy array or
        list for `delta`.

        >>> huber([1., 3., 5.], 4.)
        array([3.5, 7.5, 8. ])

        Compute the function at different points by providing a NumPy array or
        list for `r`.

        >>> huber(2., np.array([1., 1.5, 3.]))
        array([0.5  , 1.125, 4.   ])

        The function can be calculated for different `delta` and `r` by
        providing arrays for both with compatible shapes for broadcasting.

        >>> r = np.array([1., 2.5, 8., 10.])
        >>> deltas = np.array([[1.], [5.], [9.]])
        >>> print(r.shape, deltas.shape)
        (4,) (3, 1)

        >>> huber(deltas, r)
        array([[ 0.5  ,  2.   ,  7.5  ,  9.5  ],
               [ 0.5  ,  3.125, 27.5  , 37.5  ],
               [ 0.5  ,  3.125, 32.   , 49.5  ]])

        Plot the function for different `delta`.

        >>> x = np.linspace(-4, 4, 500)
        >>> deltas = [1, 2, 3]
        >>> linestyles = ["dashed", "dotted", "dashdot"]
        >>> fig, ax = plt.subplots()
        >>> combined_plot_parameters = list(zip(deltas, linestyles))
        >>> for delta, style in combined_plot_parameters:
        ...     ax.plot(x, huber(delta, x), label=fr"$\delta={delta}$", ls=style)
        >>> ax.legend(loc="upper center")
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title(r"Huber loss function $h_{\delta}(x)$")
        >>> ax.set_xlim(-4, 4)
        >>> ax.set_ylim(0, 8)
        >>> plt.show()

    hyp0f1 = <ufunc 'hyp0f1'>
        hyp0f1(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        hyp0f1(v, z, out=None)

        Confluent hypergeometric limit function 0F1.

        Parameters
        ----------
        v : array_like
            Real-valued parameter
        z : array_like
            Real- or complex-valued argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The confluent hypergeometric limit function

        Notes
        -----
        This function is defined as:

        .. math:: _0F_1(v, z) = \sum_{k=0}^{\infty}\frac{z^k}{(v)_k k!}.

        It's also the limit as :math:`q \to \infty` of :math:`_1F_1(q; v; z/q)`,
        and satisfies the differential equation :math:`f''(z) + vf'(z) =
        f(z)`. See [1]_ for more information.

        References
        ----------
        .. [1] Wolfram MathWorld, "Confluent Hypergeometric Limit Function",
               http://mathworld.wolfram.com/ConfluentHypergeometricLimitFunction.html

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is one when `z` is zero.

        >>> sc.hyp0f1(1, 0)
        1.0

        It is the limit of the confluent hypergeometric function as `q`
        goes to infinity.

        >>> q = np.array([1, 10, 100, 1000])
        >>> v = 1
        >>> z = 1
        >>> sc.hyp1f1(q, v, z / q)
        array([2.71828183, 2.31481985, 2.28303778, 2.27992985])
        >>> sc.hyp0f1(v, z)
        2.2795853023360673

        It is related to Bessel functions.

        >>> n = 1
        >>> x = np.linspace(0, 1, 5)
        >>> sc.jv(n, x)
        array([0.        , 0.12402598, 0.24226846, 0.3492436 , 0.44005059])
        >>> (0.5 * x)**n / sc.factorial(n) * sc.hyp0f1(n + 1, -0.25 * x**2)
        array([0.        , 0.12402598, 0.24226846, 0.3492436 , 0.44005059])

    hyp1f1 = <ufunc 'hyp1f1'>
        hyp1f1(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        hyp1f1(a, b, x, out=None)

        Confluent hypergeometric function 1F1.

        The confluent hypergeometric function is defined by the series

        .. math::

           {}_1F_1(a; b; x) = \sum_{k = 0}^\infty \frac{(a)_k}{(b)_k k!} x^k.

        See [dlmf]_ for more details. Here :math:`(\cdot)_k` is the
        Pochhammer symbol; see `poch`.

        Parameters
        ----------
        a, b : array_like
            Real parameters
        x : array_like
            Real or complex argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the confluent hypergeometric function

        See Also
        --------
        hyperu : another confluent hypergeometric function
        hyp0f1 : confluent hypergeometric limit function
        hyp2f1 : Gaussian hypergeometric function

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/13.2#E2

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is one when `x` is zero:

        >>> sc.hyp1f1(0.5, 0.5, 0)
        1.0

        It is singular when `b` is a nonpositive integer.

        >>> sc.hyp1f1(0.5, -1, 0)
        inf

        It is a polynomial when `a` is a nonpositive integer.

        >>> a, b, x = -1, 0.5, np.array([1.0, 2.0, 3.0, 4.0])
        >>> sc.hyp1f1(a, b, x)
        array([-1., -3., -5., -7.])
        >>> 1 + (a / b) * x
        array([-1., -3., -5., -7.])

        It reduces to the exponential function when `a = b`.

        >>> sc.hyp1f1(2, 2, [1, 2, 3, 4])
        array([ 2.71828183,  7.3890561 , 20.08553692, 54.59815003])
        >>> np.exp([1, 2, 3, 4])
        array([ 2.71828183,  7.3890561 , 20.08553692, 54.59815003])

    hyp2f1 = <ufunc 'hyp2f1'>
        hyp2f1(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        hyp2f1(a, b, c, z, out=None)

        Gauss hypergeometric function 2F1(a, b; c; z)

        Parameters
        ----------
        a, b, c : array_like
            Arguments, should be real-valued.
        z : array_like
            Argument, real or complex.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        hyp2f1 : scalar or ndarray
            The values of the gaussian hypergeometric function.

        See Also
        --------
        hyp0f1 : confluent hypergeometric limit function.
        hyp1f1 : Kummer's (confluent hypergeometric) function.

        Notes
        -----
        This function is defined for :math:`|z| < 1` as

        .. math::

           \mathrm{hyp2f1}(a, b, c, z) = \sum_{n=0}^\infty
           \frac{(a)_n (b)_n}{(c)_n}\frac{z^n}{n!},

        and defined on the rest of the complex z-plane by analytic
        continuation [1]_.
        Here :math:`(\cdot)_n` is the Pochhammer symbol; see `poch`. When
        :math:`n` is an integer the result is a polynomial of degree :math:`n`.

        The implementation for complex values of ``z`` is described in [2]_,
        except for ``z`` in the region defined by

        .. math::

             0.9 <= \left|z\right| < 1.1,
             \left|1 - z\right| >= 0.9,
             \mathrm{real}(z) >= 0

        in which the implementation follows [4]_.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/15.2
        .. [2] S. Zhang and J.M. Jin, "Computation of Special Functions", Wiley 1996
        .. [3] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [4] J.L. Lopez and N.M. Temme, "New series expansions of the Gauss
               hypergeometric function", Adv Comput Math 39, 349-365 (2013).
               https://doi.org/10.1007/s10444-012-9283-y

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It has poles when `c` is a negative integer.

        >>> sc.hyp2f1(1, 1, -2, 1)
        inf

        It is a polynomial when `a` or `b` is a negative integer.

        >>> a, b, c = -1, 1, 1.5
        >>> z = np.linspace(0, 1, 5)
        >>> sc.hyp2f1(a, b, c, z)
        array([1.        , 0.83333333, 0.66666667, 0.5       , 0.33333333])
        >>> 1 + a * b * z / c
        array([1.        , 0.83333333, 0.66666667, 0.5       , 0.33333333])

        It is symmetric in `a` and `b`.

        >>> a = np.linspace(0, 1, 5)
        >>> b = np.linspace(0, 1, 5)
        >>> sc.hyp2f1(a, b, 1, 0.5)
        array([1.        , 1.03997334, 1.1803406 , 1.47074441, 2.        ])
        >>> sc.hyp2f1(b, a, 1, 0.5)
        array([1.        , 1.03997334, 1.1803406 , 1.47074441, 2.        ])

        It contains many other functions as special cases.

        >>> z = 0.5
        >>> sc.hyp2f1(1, 1, 2, z)
        1.3862943611198901
        >>> -np.log(1 - z) / z
        1.3862943611198906

        >>> sc.hyp2f1(0.5, 1, 1.5, z**2)
        1.098612288668109
        >>> np.log((1 + z) / (1 - z)) / (2 * z)
        1.0986122886681098

        >>> sc.hyp2f1(0.5, 1, 1.5, -z**2)
        0.9272952180016117
        >>> np.arctan(z) / z
        0.9272952180016122

    hyperu = <ufunc 'hyperu'>
        hyperu(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        hyperu(a, b, x, out=None)

        Confluent hypergeometric function U

        It is defined as the solution to the equation

        .. math::

           x \frac{d^2w}{dx^2} + (b - x) \frac{dw}{dx} - aw = 0

        which satisfies the property

        .. math::

           U(a, b, x) \sim x^{-a}

        as :math:`x \to \infty`. See [dlmf]_ for more details.

        Parameters
        ----------
        a, b : array_like
            Real-valued parameters
        x : array_like
            Real-valued argument
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of `U`

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematics Functions
                  https://dlmf.nist.gov/13.2#E6

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It has a branch cut along the negative `x` axis.

        >>> x = np.linspace(-0.1, -10, 5)
        >>> sc.hyperu(1, 1, x)
        array([nan, nan, nan, nan, nan])

        It approaches zero as `x` goes to infinity.

        >>> x = np.array([1, 10, 100])
        >>> sc.hyperu(1, 1, x)
        array([0.59634736, 0.09156333, 0.00990194])

        It satisfies Kummer's transformation.

        >>> a, b, x = 2, 1, 1
        >>> sc.hyperu(a, b, x)
        0.1926947246463881
        >>> x**(1 - b) * sc.hyperu(a - b + 1, 2 - b, x)
        0.1926947246463881

    i0 = <ufunc 'i0'>
        i0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        i0(x, out=None)

        Modified Bessel function of order 0.

        Defined as,

        .. math::
            I_0(x) = \sum_{k=0}^\infty \frac{(x^2/4)^k}{(k!)^2} = J_0(\imath x),

        where :math:`J_0` is the Bessel function of the first kind of order 0.

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            Value of the modified Bessel function of order 0 at `x`.

        See Also
        --------
        iv: Modified Bessel function of any order
        i0e: Exponentially scaled modified Bessel function of order 0

        Notes
        -----
        The range is partitioned into the two intervals [0, 8] and (8, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `i0`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import i0
        >>> i0(1.)
        1.2660658777520082

        Calculate at several points:

        >>> import numpy as np
        >>> i0(np.array([-2., 0., 3.5]))
        array([2.2795853 , 1.        , 7.37820343])

        Plot the function from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> y = i0(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    i0e = <ufunc 'i0e'>
        i0e(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        i0e(x, out=None)

        Exponentially scaled modified Bessel function of order 0.

        Defined as::

            i0e(x) = exp(-abs(x)) * i0(x).

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            Value of the exponentially scaled modified Bessel function of order 0
            at `x`.

        See Also
        --------
        iv: Modified Bessel function of the first kind
        i0: Modified Bessel function of order 0

        Notes
        -----
        The range is partitioned into the two intervals [0, 8] and (8, infinity).
        Chebyshev polynomial expansions are employed in each interval. The
        polynomial expansions used are the same as those in `i0`, but
        they are not multiplied by the dominant exponential factor.

        This function is a wrapper for the Cephes [1]_ routine `i0e`. `i0e`
        is useful for large arguments `x`: for these, `i0` quickly overflows.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        In the following example `i0` returns infinity whereas `i0e` still returns
        a finite number.

        >>> from scipy.special import i0, i0e
        >>> i0(1000.), i0e(1000.)
        (inf, 0.012617240455891257)

        Calculate the function at several points by providing a NumPy array or
        list for `x`:

        >>> import numpy as np
        >>> i0e(np.array([-2., 0., 3.]))
        array([0.30850832, 1.        , 0.24300035])

        Plot the function from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> y = i0e(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    i1 = <ufunc 'i1'>
        i1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        i1(x, out=None)

        Modified Bessel function of order 1.

        Defined as,

        .. math::
            I_1(x) = \frac{1}{2}x \sum_{k=0}^\infty \frac{(x^2/4)^k}{k! (k + 1)!}
                   = -\imath J_1(\imath x),

        where :math:`J_1` is the Bessel function of the first kind of order 1.

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            Value of the modified Bessel function of order 1 at `x`.

        See Also
        --------
        iv: Modified Bessel function of the first kind
        i1e: Exponentially scaled modified Bessel function of order 1

        Notes
        -----
        The range is partitioned into the two intervals [0, 8] and (8, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `i1`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import i1
        >>> i1(1.)
        0.5651591039924851

        Calculate the function at several points:

        >>> import numpy as np
        >>> i1(np.array([-2., 0., 6.]))
        array([-1.59063685,  0.        , 61.34193678])

        Plot the function between -10 and 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> y = i1(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    i1e = <ufunc 'i1e'>
        i1e(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        i1e(x, out=None)

        Exponentially scaled modified Bessel function of order 1.

        Defined as::

            i1e(x) = exp(-abs(x)) * i1(x)

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            Value of the exponentially scaled modified Bessel function of order 1
            at `x`.

        See Also
        --------
        iv: Modified Bessel function of the first kind
        i1: Modified Bessel function of order 1

        Notes
        -----
        The range is partitioned into the two intervals [0, 8] and (8, infinity).
        Chebyshev polynomial expansions are employed in each interval. The
        polynomial expansions used are the same as those in `i1`, but
        they are not multiplied by the dominant exponential factor.

        This function is a wrapper for the Cephes [1]_ routine `i1e`. `i1e`
        is useful for large arguments `x`: for these, `i1` quickly overflows.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        In the following example `i1` returns infinity whereas `i1e` still returns
        a finite number.

        >>> from scipy.special import i1, i1e
        >>> i1(1000.), i1e(1000.)
        (inf, 0.01261093025692863)

        Calculate the function at several points by providing a NumPy array or
        list for `x`:

        >>> import numpy as np
        >>> i1e(np.array([-2., 0., 6.]))
        array([-0.21526929,  0.        ,  0.15205146])

        Plot the function between -10 and 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> y = i1e(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    inv_boxcox = <ufunc 'inv_boxcox'>
        inv_boxcox(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        inv_boxcox(y, lmbda, out=None)

        Compute the inverse of the Box-Cox transformation.

        Find ``x`` such that::

            y = (x**lmbda - 1) / lmbda  if lmbda != 0
                log(x)                  if lmbda == 0

        Parameters
        ----------
        y : array_like
            Data to be transformed.
        lmbda : array_like
            Power parameter of the Box-Cox transform.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        x : scalar or ndarray
            Transformed data.

        Notes
        -----

        .. versionadded:: 0.16.0

        Examples
        --------
        >>> from scipy.special import boxcox, inv_boxcox
        >>> y = boxcox([1, 4, 10], 2.5)
        >>> inv_boxcox(y, 2.5)
        array([1., 4., 10.])

    inv_boxcox1p = <ufunc 'inv_boxcox1p'>
        inv_boxcox1p(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        inv_boxcox1p(y, lmbda, out=None)

        Compute the inverse of the Box-Cox transformation.

        Find ``x`` such that::

            y = ((1+x)**lmbda - 1) / lmbda  if lmbda != 0
                log(1+x)                    if lmbda == 0

        Parameters
        ----------
        y : array_like
            Data to be transformed.
        lmbda : array_like
            Power parameter of the Box-Cox transform.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        x : scalar or ndarray
            Transformed data.

        Notes
        -----

        .. versionadded:: 0.16.0

        Examples
        --------
        >>> from scipy.special import boxcox1p, inv_boxcox1p
        >>> y = boxcox1p([1, 4, 10], 2.5)
        >>> inv_boxcox1p(y, 2.5)
        array([1., 4., 10.])

    it2i0k0 = <ufunc 'it2i0k0'>
        it2i0k0(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        it2i0k0(x, out=None)

        Integrals related to modified Bessel functions of order 0.

        Computes the integrals

        .. math::

            \int_0^x \frac{I_0(t) - 1}{t} dt \\
            \int_x^\infty \frac{K_0(t)}{t} dt.

        Parameters
        ----------
        x : array_like
            Values at which to evaluate the integrals.
        out : tuple of ndarrays, optional
            Optional output arrays for the function results.

        Returns
        -------
        ii0 : scalar or ndarray
            The integral for `i0`
        ik0 : scalar or ndarray
            The integral for `k0`

        References
        ----------
        .. [1] S. Zhang and J.M. Jin, "Computation of Special Functions",
               Wiley 1996

        Examples
        --------
        Evaluate the functions at one point.

        >>> from scipy.special import it2i0k0
        >>> int_i, int_k = it2i0k0(1.)
        >>> int_i, int_k
        (0.12897944249456852, 0.2085182909001295)

        Evaluate the functions at several points.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> int_i, int_k = it2i0k0(points)
        >>> int_i, int_k
        (array([0.03149527, 0.30187149, 1.50012461]),
         array([0.66575102, 0.0823715 , 0.00823631]))

        Plot the functions from 0 to 5.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 5., 1000)
        >>> int_i, int_k = it2i0k0(x)
        >>> ax.plot(x, int_i, label=r"$\int_0^x \frac{I_0(t)-1}{t}\,dt$")
        >>> ax.plot(x, int_k, label=r"$\int_x^{\infty} \frac{K_0(t)}{t}\,dt$")
        >>> ax.legend()
        >>> ax.set_ylim(0, 10)
        >>> plt.show()

    it2j0y0 = <ufunc 'it2j0y0'>
        it2j0y0(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        it2j0y0(x, out=None)

        Integrals related to Bessel functions of the first kind of order 0.

        Computes the integrals

        .. math::

            \int_0^x \frac{1 - J_0(t)}{t} dt \\
            \int_x^\infty \frac{Y_0(t)}{t} dt.

        For more on :math:`J_0` and :math:`Y_0` see `j0` and `y0`.

        Parameters
        ----------
        x : array_like
            Values at which to evaluate the integrals.
        out : tuple of ndarrays, optional
            Optional output arrays for the function results.

        Returns
        -------
        ij0 : scalar or ndarray
            The integral for `j0`
        iy0 : scalar or ndarray
            The integral for `y0`

        References
        ----------
        .. [1] S. Zhang and J.M. Jin, "Computation of Special Functions",
               Wiley 1996

        Examples
        --------
        Evaluate the functions at one point.

        >>> from scipy.special import it2j0y0
        >>> int_j, int_y = it2j0y0(1.)
        >>> int_j, int_y
        (0.12116524699506871, 0.39527290169929336)

        Evaluate the functions at several points.

        >>> import numpy as np
        >>> points = np.array([0.5, 1.5, 3.])
        >>> int_j, int_y = it2j0y0(points)
        >>> int_j, int_y
        (array([0.03100699, 0.26227724, 0.85614669]),
         array([ 0.26968854,  0.29769696, -0.02987272]))

        Plot the functions from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> int_j, int_y = it2j0y0(x)
        >>> ax.plot(x, int_j, label=r"$\int_0^x \frac{1-J_0(t)}{t}\,dt$")
        >>> ax.plot(x, int_y, label=r"$\int_x^{\infty} \frac{Y_0(t)}{t}\,dt$")
        >>> ax.legend()
        >>> ax.set_ylim(-2.5, 2.5)
        >>> plt.show()

    it2struve0 = <ufunc 'it2struve0'>
        it2struve0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        it2struve0(x, out=None)

        Integral related to the Struve function of order 0.

        Returns the integral,

        .. math::
            \int_x^\infty \frac{H_0(t)}{t}\,dt

        where :math:`H_0` is the Struve function of order 0.

        Parameters
        ----------
        x : array_like
            Lower limit of integration.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            The value of the integral.

        See Also
        --------
        struve

        Notes
        -----
        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f_src/special_functions/special_functions.html

        Examples
        --------
        Evaluate the function at one point.

        >>> import numpy as np
        >>> from scipy.special import it2struve0
        >>> it2struve0(1.)
        0.9571973506383524

        Evaluate the function at several points by supplying
        an array for `x`.

        >>> points = np.array([1., 2., 3.5])
        >>> it2struve0(points)
        array([0.95719735, 0.46909296, 0.10366042])

        Plot the function from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-10., 10., 1000)
        >>> it2struve0_values = it2struve0(x)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, it2struve0_values)
        >>> ax.set_xlabel(r'$x$')
        >>> ax.set_ylabel(r'$\int_x^{\infty}\frac{H_0(t)}{t}\,dt$')
        >>> plt.show()

    itairy = <ufunc 'itairy'>
        itairy(x[, out1, out2, out3, out4], / [, out=(None, None, None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        itairy(x, out=None)

        Integrals of Airy functions

        Calculates the integrals of Airy functions from 0 to `x`.

        Parameters
        ----------

        x : array_like
            Upper limit of integration (float).
        out : tuple of ndarray, optional
            Optional output arrays for the function values

        Returns
        -------
        Apt : scalar or ndarray
            Integral of Ai(t) from 0 to x.
        Bpt : scalar or ndarray
            Integral of Bi(t) from 0 to x.
        Ant : scalar or ndarray
            Integral of Ai(-t) from 0 to x.
        Bnt : scalar or ndarray
            Integral of Bi(-t) from 0 to x.

        Notes
        -----

        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------

        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f_src/special_functions/special_functions.html

        Examples
        --------
        Compute the functions at ``x=1.``.

        >>> import numpy as np
        >>> from scipy.special import itairy
        >>> import matplotlib.pyplot as plt
        >>> apt, bpt, ant, bnt = itairy(1.)
        >>> apt, bpt, ant, bnt
        (0.23631734191710949,
         0.8727691167380077,
         0.46567398346706845,
         0.3730050096342943)

        Compute the functions at several points by providing a NumPy array for `x`.

        >>> x = np.array([1., 1.5, 2.5, 5])
        >>> apt, bpt, ant, bnt = itairy(x)
        >>> apt, bpt, ant, bnt
        (array([0.23631734, 0.28678675, 0.324638  , 0.33328759]),
         array([  0.87276912,   1.62470809,   5.20906691, 321.47831857]),
         array([0.46567398, 0.72232876, 0.93187776, 0.7178822 ]),
         array([ 0.37300501,  0.35038814, -0.02812939,  0.15873094]))

        Plot the functions from -10 to 10.

        >>> x = np.linspace(-10, 10, 500)
        >>> apt, bpt, ant, bnt = itairy(x)
        >>> fig, ax = plt.subplots(figsize=(6, 5))
        >>> ax.plot(x, apt, label=r"$\int_0^x\, Ai(t)\, dt$")
        >>> ax.plot(x, bpt, ls="dashed", label=r"$\int_0^x\, Bi(t)\, dt$")
        >>> ax.plot(x, ant, ls="dashdot", label=r"$\int_0^x\, Ai(-t)\, dt$")
        >>> ax.plot(x, bnt, ls="dotted", label=r"$\int_0^x\, Bi(-t)\, dt$")
        >>> ax.set_ylim(-2, 1.5)
        >>> ax.legend(loc="lower right")
        >>> plt.show()

    iti0k0 = <ufunc 'iti0k0'>
        iti0k0(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        iti0k0(x, out=None)

        Integrals of modified Bessel functions of order 0.

        Computes the integrals

        .. math::

            \int_0^x I_0(t) dt \\
            \int_0^x K_0(t) dt.

        For more on :math:`I_0` and :math:`K_0` see `i0` and `k0`.

        Parameters
        ----------
        x : array_like
            Values at which to evaluate the integrals.
        out : tuple of ndarrays, optional
            Optional output arrays for the function results.

        Returns
        -------
        ii0 : scalar or ndarray
            The integral for `i0`
        ik0 : scalar or ndarray
            The integral for `k0`

        References
        ----------
        .. [1] S. Zhang and J.M. Jin, "Computation of Special Functions",
               Wiley 1996

        Examples
        --------
        Evaluate the functions at one point.

        >>> from scipy.special import iti0k0
        >>> int_i, int_k = iti0k0(1.)
        >>> int_i, int_k
        (1.0865210970235892, 1.2425098486237771)

        Evaluate the functions at several points.

        >>> import numpy as np
        >>> points = np.array([0., 1.5, 3.])
        >>> int_i, int_k = iti0k0(points)
        >>> int_i, int_k
        (array([0.        , 1.80606937, 6.16096149]),
         array([0.        , 1.39458246, 1.53994809]))

        Plot the functions from 0 to 5.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 5., 1000)
        >>> int_i, int_k = iti0k0(x)
        >>> ax.plot(x, int_i, label=r"$\int_0^x I_0(t)\,dt$")
        >>> ax.plot(x, int_k, label=r"$\int_0^x K_0(t)\,dt$")
        >>> ax.legend()
        >>> plt.show()

    itj0y0 = <ufunc 'itj0y0'>
        itj0y0(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        itj0y0(x, out=None)

        Integrals of Bessel functions of the first kind of order 0.

        Computes the integrals

        .. math::

            \int_0^x J_0(t) dt \\
            \int_0^x Y_0(t) dt.

        For more on :math:`J_0` and :math:`Y_0` see `j0` and `y0`.

        Parameters
        ----------
        x : array_like
            Values at which to evaluate the integrals.
        out : tuple of ndarrays, optional
            Optional output arrays for the function results.

        Returns
        -------
        ij0 : scalar or ndarray
            The integral of `j0`
        iy0 : scalar or ndarray
            The integral of `y0`

        References
        ----------
        .. [1] S. Zhang and J.M. Jin, "Computation of Special Functions",
               Wiley 1996

        Examples
        --------
        Evaluate the functions at one point.

        >>> from scipy.special import itj0y0
        >>> int_j, int_y = itj0y0(1.)
        >>> int_j, int_y
        (0.9197304100897596, -0.637069376607422)

        Evaluate the functions at several points.

        >>> import numpy as np
        >>> points = np.array([0., 1.5, 3.])
        >>> int_j, int_y = itj0y0(points)
        >>> int_j, int_y
        (array([0.        , 1.24144951, 1.38756725]),
         array([ 0.        , -0.51175903,  0.19765826]))

        Plot the functions from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> int_j, int_y = itj0y0(x)
        >>> ax.plot(x, int_j, label=r"$\int_0^x J_0(t)\,dt$")
        >>> ax.plot(x, int_y, label=r"$\int_0^x Y_0(t)\,dt$")
        >>> ax.legend()
        >>> plt.show()

    itmodstruve0 = <ufunc 'itmodstruve0'>
        itmodstruve0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        itmodstruve0(x, out=None)

        Integral of the modified Struve function of order 0.

        .. math::
            I = \int_0^x L_0(t)\,dt

        Parameters
        ----------
        x : array_like
            Upper limit of integration (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            The integral of :math:`L_0` from 0 to `x`.

        See Also
        --------
        modstruve: Modified Struve function which is integrated by this function

        Notes
        -----
        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f_src/special_functions/special_functions.html

        Examples
        --------
        Evaluate the function at one point.

        >>> import numpy as np
        >>> from scipy.special import itmodstruve0
        >>> itmodstruve0(1.)
        0.3364726286440384

        Evaluate the function at several points by supplying
        an array for `x`.

        >>> points = np.array([1., 2., 3.5])
        >>> itmodstruve0(points)
        array([0.33647263, 1.588285  , 7.60382578])

        Plot the function from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-10., 10., 1000)
        >>> itmodstruve0_values = itmodstruve0(x)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, itmodstruve0_values)
        >>> ax.set_xlabel(r'$x$')
        >>> ax.set_ylabel(r'$\int_0^xL_0(t)\,dt$')
        >>> plt.show()

    itstruve0 = <ufunc 'itstruve0'>
        itstruve0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        itstruve0(x, out=None)

        Integral of the Struve function of order 0.

        .. math::
            I = \int_0^x H_0(t)\,dt

        Parameters
        ----------
        x : array_like
            Upper limit of integration (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        I : scalar or ndarray
            The integral of :math:`H_0` from 0 to `x`.

        See Also
        --------
        struve: Function which is integrated by this function

        Notes
        -----
        Wrapper for a Fortran routine created by Shanjie Zhang and Jianming
        Jin [1]_.

        References
        ----------
        .. [1] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f_src/special_functions/special_functions.html

        Examples
        --------
        Evaluate the function at one point.

        >>> import numpy as np
        >>> from scipy.special import itstruve0
        >>> itstruve0(1.)
        0.30109042670805547

        Evaluate the function at several points by supplying
        an array for `x`.

        >>> points = np.array([1., 2., 3.5])
        >>> itstruve0(points)
        array([0.30109043, 1.01870116, 1.96804581])

        Plot the function from -20 to 20.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-20., 20., 1000)
        >>> istruve0_values = itstruve0(x)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, istruve0_values)
        >>> ax.set_xlabel(r'$x$')
        >>> ax.set_ylabel(r'$\int_0^{x}H_0(t)\,dt$')
        >>> plt.show()

    iv = <ufunc 'iv'>
        iv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        iv(v, z, out=None)

        Modified Bessel function of the first kind of real order.

        Parameters
        ----------
        v : array_like
            Order. If `z` is of real type and negative, `v` must be integer
            valued.
        z : array_like of float or complex
            Argument.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the modified Bessel function.

        See Also
        --------
        ive : This function with leading exponential behavior stripped off.
        i0 : Faster version of this function for order 0.
        i1 : Faster version of this function for order 1.

        Notes
        -----
        For real `z` and :math:`v \in [-50, 50]`, the evaluation is carried out
        using Temme's method [1]_.  For larger orders, uniform asymptotic
        expansions are applied.

        For complex `z` and positive `v`, the AMOS [2]_ `zbesi` routine is
        called. It uses a power series for small `z`, the asymptotic expansion
        for large `abs(z)`, the Miller algorithm normalized by the Wronskian
        and a Neumann series for intermediate magnitudes, and the uniform
        asymptotic expansions for :math:`I_v(z)` and :math:`J_v(z)` for large
        orders. Backward recurrence is used to generate sequences or reduce
        orders when necessary.

        The calculations above are done in the right half plane and continued
        into the left half plane by the formula,

        .. math:: I_v(z \exp(\pm\imath\pi)) = \exp(\pm\pi v) I_v(z)

        (valid when the real part of `z` is positive).  For negative `v`, the
        formula

        .. math:: I_{-v}(z) = I_v(z) + \frac{2}{\pi} \sin(\pi v) K_v(z)

        is used, where :math:`K_v(z)` is the modified Bessel function of the
        second kind, evaluated using the AMOS routine `zbesk`.

        References
        ----------
        .. [1] Temme, Journal of Computational Physics, vol 21, 343 (1976)
        .. [2] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Evaluate the function of order 0 at one point.

        >>> from scipy.special import iv
        >>> iv(0, 1.)
        1.2660658777520084

        Evaluate the function at one point for different orders.

        >>> iv(0, 1.), iv(1, 1.), iv(1.5, 1.)
        (1.2660658777520084, 0.565159103992485, 0.2935253263474798)

        The evaluation for different orders can be carried out in one call by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> iv([0, 1, 1.5], 1.)
        array([1.26606588, 0.5651591 , 0.29352533])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> import numpy as np
        >>> points = np.array([-2., 0., 3.])
        >>> iv(0, points)
        array([2.2795853 , 1.        , 4.88079259])

        If `z` is an array, the order parameter `v` must be broadcastable to
        the correct shape if different orders shall be computed in one call.
        To calculate the orders 0 and 1 for an 1D array:

        >>> orders = np.array([[0], [1]])
        >>> orders.shape
        (2, 1)

        >>> iv(orders, points)
        array([[ 2.2795853 ,  1.        ,  4.88079259],
               [-1.59063685,  0.        ,  3.95337022]])

        Plot the functions of order 0 to 3 from -5 to 5.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-5., 5., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, iv(i, x), label=f'$I_{i!r}$')
        >>> ax.legend()
        >>> plt.show()

    ive = <ufunc 'ive'>
        ive(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        ive(v, z, out=None)

        Exponentially scaled modified Bessel function of the first kind.

        Defined as::

            ive(v, z) = iv(v, z) * exp(-abs(z.real))

        For imaginary numbers without a real part, returns the unscaled
        Bessel function of the first kind `iv`.

        Parameters
        ----------
        v : array_like of float
            Order.
        z : array_like of float or complex
            Argument.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            Values of the exponentially scaled modified Bessel function.

        See Also
        --------
        iv: Modified Bessel function of the first kind
        i0e: Faster implementation of this function for order 0
        i1e: Faster implementation of this function for order 1

        Notes
        -----
        For positive `v`, the AMOS [1]_ `zbesi` routine is called. It uses a
        power series for small `z`, the asymptotic expansion for large
        `abs(z)`, the Miller algorithm normalized by the Wronskian and a
        Neumann series for intermediate magnitudes, and the uniform asymptotic
        expansions for :math:`I_v(z)` and :math:`J_v(z)` for large orders.
        Backward recurrence is used to generate sequences or reduce orders when
        necessary.

        The calculations above are done in the right half plane and continued
        into the left half plane by the formula,

        .. math:: I_v(z \exp(\pm\imath\pi)) = \exp(\pm\pi v) I_v(z)

        (valid when the real part of `z` is positive).  For negative `v`, the
        formula

        .. math:: I_{-v}(z) = I_v(z) + \frac{2}{\pi} \sin(\pi v) K_v(z)

        is used, where :math:`K_v(z)` is the modified Bessel function of the
        second kind, evaluated using the AMOS routine `zbesk`.

        `ive` is useful for large arguments `z`: for these, `iv` easily overflows,
        while `ive` does not due to the exponential scaling.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        In the following example `iv` returns infinity whereas `ive` still returns
        a finite number.

        >>> from scipy.special import iv, ive
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> iv(3, 1000.), ive(3, 1000.)
        (inf, 0.01256056218254712)

        Evaluate the function at one point for different orders by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> ive([0, 1, 1.5], 1.)
        array([0.46575961, 0.20791042, 0.10798193])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> points = np.array([-2., 0., 3.])
        >>> ive(0, points)
        array([0.30850832, 1.        , 0.24300035])

        Evaluate the function at several points for different orders by
        providing arrays for both `v` for `z`. Both arrays have to be
        broadcastable to the correct shape. To calculate the orders 0, 1
        and 2 for a 1D array of points:

        >>> ive([[0], [1], [2]], points)
        array([[ 0.30850832,  1.        ,  0.24300035],
               [-0.21526929,  0.        ,  0.19682671],
               [ 0.09323903,  0.        ,  0.11178255]])

        Plot the functions of order 0 to 3 from -5 to 5.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-5., 5., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, ive(i, x), label=fr'$I_{i!r}(z)\cdot e^{{-|z|}}$')
        >>> ax.legend()
        >>> ax.set_xlabel(r"$z$")
        >>> plt.show()

    j0 = <ufunc 'j0'>
        j0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        j0(x, out=None)

        Bessel function of the first kind of order 0.

        Parameters
        ----------
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        J : scalar or ndarray
            Value of the Bessel function of the first kind of order 0 at `x`.

        See Also
        --------
        jv : Bessel function of real order and complex argument.
        spherical_jn : spherical Bessel functions.

        Notes
        -----
        The domain is divided into the intervals [0, 5] and (5, infinity). In the
        first interval the following rational approximation is used:

        .. math::

            J_0(x) \approx (w - r_1^2)(w - r_2^2) \frac{P_3(w)}{Q_8(w)},

        where :math:`w = x^2` and :math:`r_1`, :math:`r_2` are the zeros of
        :math:`J_0`, and :math:`P_3` and :math:`Q_8` are polynomials of degrees 3
        and 8, respectively.

        In the second interval, the Hankel asymptotic expansion is employed with
        two rational functions of degree 6/6 and 7/7.

        This function is a wrapper for the Cephes [1]_ routine `j0`.
        It should not be confused with the spherical Bessel functions (see
        `spherical_jn`).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import j0
        >>> j0(1.)
        0.7651976865579665

        Calculate the function at several points:

        >>> import numpy as np
        >>> j0(np.array([-2., 0., 4.]))
        array([ 0.22389078,  1.        , -0.39714981])

        Plot the function from -20 to 20.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-20., 20., 1000)
        >>> y = j0(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    j1 = <ufunc 'j1'>
        j1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        j1(x, out=None)

        Bessel function of the first kind of order 1.

        Parameters
        ----------
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        J : scalar or ndarray
            Value of the Bessel function of the first kind of order 1 at `x`.

        See Also
        --------
        jv: Bessel function of the first kind
        spherical_jn: spherical Bessel functions.

        Notes
        -----
        The domain is divided into the intervals [0, 8] and (8, infinity). In the
        first interval a 24 term Chebyshev expansion is used. In the second, the
        asymptotic trigonometric representation is employed using two rational
        functions of degree 5/5.

        This function is a wrapper for the Cephes [1]_ routine `j1`.
        It should not be confused with the spherical Bessel functions (see
        `spherical_jn`).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import j1
        >>> j1(1.)
        0.44005058574493355

        Calculate the function at several points:

        >>> import numpy as np
        >>> j1(np.array([-2., 0., 4.]))
        array([-0.57672481,  0.        , -0.06604333])

        Plot the function from -20 to 20.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-20., 20., 1000)
        >>> y = j1(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    jn = <ufunc 'jv'>
        jv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        jv(v, z, out=None)

        Bessel function of the first kind of real order and complex argument.

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        J : scalar or ndarray
            Value of the Bessel function, :math:`J_v(z)`.

        See Also
        --------
        jve : :math:`J_v` with leading exponential behavior stripped off.
        spherical_jn : spherical Bessel functions.
        j0 : faster version of this function for order 0.
        j1 : faster version of this function for order 1.

        Notes
        -----
        For positive `v` values, the computation is carried out using the AMOS
        [1]_ `zbesj` routine, which exploits the connection to the modified
        Bessel function :math:`I_v`,

        .. math::
            J_v(z) = \exp(v\pi\imath/2) I_v(-\imath z)\qquad (\Im z > 0)

            J_v(z) = \exp(-v\pi\imath/2) I_v(\imath z)\qquad (\Im z < 0)

        For negative `v` values the formula,

        .. math:: J_{-v}(z) = J_v(z) \cos(\pi v) - Y_v(z) \sin(\pi v)

        is used, where :math:`Y_v(z)` is the Bessel function of the second
        kind, computed using the AMOS routine `zbesy`.  Note that the second
        term is exactly zero for integer `v`; to improve accuracy the second
        term is explicitly omitted for `v` values such that `v = floor(v)`.

        Not to be confused with the spherical Bessel functions (see `spherical_jn`).

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Evaluate the function of order 0 at one point.

        >>> from scipy.special import jv
        >>> jv(0, 1.)
        0.7651976865579666

        Evaluate the function at one point for different orders.

        >>> jv(0, 1.), jv(1, 1.), jv(1.5, 1.)
        (0.7651976865579666, 0.44005058574493355, 0.24029783912342725)

        The evaluation for different orders can be carried out in one call by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> jv([0, 1, 1.5], 1.)
        array([0.76519769, 0.44005059, 0.24029784])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> import numpy as np
        >>> points = np.array([-2., 0., 3.])
        >>> jv(0, points)
        array([ 0.22389078,  1.        , -0.26005195])

        If `z` is an array, the order parameter `v` must be broadcastable to
        the correct shape if different orders shall be computed in one call.
        To calculate the orders 0 and 1 for an 1D array:

        >>> orders = np.array([[0], [1]])
        >>> orders.shape
        (2, 1)

        >>> jv(orders, points)
        array([[ 0.22389078,  1.        , -0.26005195],
               [-0.57672481,  0.        ,  0.33905896]])

        Plot the functions of order 0 to 3 from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, jv(i, x), label=f'$J_{i!r}$')
        >>> ax.legend()
        >>> plt.show()

    jv = <ufunc 'jv'>
        jv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        jv(v, z, out=None)

        Bessel function of the first kind of real order and complex argument.

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        J : scalar or ndarray
            Value of the Bessel function, :math:`J_v(z)`.

        See Also
        --------
        jve : :math:`J_v` with leading exponential behavior stripped off.
        spherical_jn : spherical Bessel functions.
        j0 : faster version of this function for order 0.
        j1 : faster version of this function for order 1.

        Notes
        -----
        For positive `v` values, the computation is carried out using the AMOS
        [1]_ `zbesj` routine, which exploits the connection to the modified
        Bessel function :math:`I_v`,

        .. math::
            J_v(z) = \exp(v\pi\imath/2) I_v(-\imath z)\qquad (\Im z > 0)

            J_v(z) = \exp(-v\pi\imath/2) I_v(\imath z)\qquad (\Im z < 0)

        For negative `v` values the formula,

        .. math:: J_{-v}(z) = J_v(z) \cos(\pi v) - Y_v(z) \sin(\pi v)

        is used, where :math:`Y_v(z)` is the Bessel function of the second
        kind, computed using the AMOS routine `zbesy`.  Note that the second
        term is exactly zero for integer `v`; to improve accuracy the second
        term is explicitly omitted for `v` values such that `v = floor(v)`.

        Not to be confused with the spherical Bessel functions (see `spherical_jn`).

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Evaluate the function of order 0 at one point.

        >>> from scipy.special import jv
        >>> jv(0, 1.)
        0.7651976865579666

        Evaluate the function at one point for different orders.

        >>> jv(0, 1.), jv(1, 1.), jv(1.5, 1.)
        (0.7651976865579666, 0.44005058574493355, 0.24029783912342725)

        The evaluation for different orders can be carried out in one call by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> jv([0, 1, 1.5], 1.)
        array([0.76519769, 0.44005059, 0.24029784])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> import numpy as np
        >>> points = np.array([-2., 0., 3.])
        >>> jv(0, points)
        array([ 0.22389078,  1.        , -0.26005195])

        If `z` is an array, the order parameter `v` must be broadcastable to
        the correct shape if different orders shall be computed in one call.
        To calculate the orders 0 and 1 for an 1D array:

        >>> orders = np.array([[0], [1]])
        >>> orders.shape
        (2, 1)

        >>> jv(orders, points)
        array([[ 0.22389078,  1.        , -0.26005195],
               [-0.57672481,  0.        ,  0.33905896]])

        Plot the functions of order 0 to 3 from -10 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, jv(i, x), label=f'$J_{i!r}$')
        >>> ax.legend()
        >>> plt.show()

    jve = <ufunc 'jve'>
        jve(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        jve(v, z, out=None)

        Exponentially scaled Bessel function of the first kind of order `v`.

        Defined as::

            jve(v, z) = jv(v, z) * exp(-abs(z.imag))

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        J : scalar or ndarray
            Value of the exponentially scaled Bessel function.

        See Also
        --------
        jv: Unscaled Bessel function of the first kind

        Notes
        -----
        For positive `v` values, the computation is carried out using the AMOS
        [1]_ `zbesj` routine, which exploits the connection to the modified
        Bessel function :math:`I_v`,

        .. math::
            J_v(z) = \exp(v\pi\imath/2) I_v(-\imath z)\qquad (\Im z > 0)

            J_v(z) = \exp(-v\pi\imath/2) I_v(\imath z)\qquad (\Im z < 0)

        For negative `v` values the formula,

        .. math:: J_{-v}(z) = J_v(z) \cos(\pi v) - Y_v(z) \sin(\pi v)

        is used, where :math:`Y_v(z)` is the Bessel function of the second
        kind, computed using the AMOS routine `zbesy`.  Note that the second
        term is exactly zero for integer `v`; to improve accuracy the second
        term is explicitly omitted for `v` values such that `v = floor(v)`.

        Exponentially scaled Bessel functions are useful for large arguments `z`:
        for these, the unscaled Bessel functions can easily under-or overflow.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Compare the output of `jv` and `jve` for large complex arguments for `z`
        by computing their values for order ``v=1`` at ``z=1000j``. We see that
        `jv` overflows but `jve` returns a finite number:

        >>> import numpy as np
        >>> from scipy.special import jv, jve
        >>> v = 1
        >>> z = 1000j
        >>> jv(v, z), jve(v, z)
        ((inf+infj), (7.721967686709077e-19+0.012610930256928629j))

        For real arguments for `z`, `jve` returns the same as `jv`.

        >>> v, z = 1, 1000
        >>> jv(v, z), jve(v, z)
        (0.004728311907089523, 0.004728311907089523)

        The function can be evaluated for several orders at the same time by
        providing a list or NumPy array for `v`:

        >>> jve([1, 3, 5], 1j)
        array([1.27304208e-17+2.07910415e-01j, -4.99352086e-19-8.15530777e-03j,
               6.11480940e-21+9.98657141e-05j])

        In the same way, the function can be evaluated at several points in one
        call by providing a list or NumPy array for `z`:

        >>> jve(1, np.array([1j, 2j, 3j]))
        array([1.27308412e-17+0.20791042j, 1.31814423e-17+0.21526929j,
               1.20521602e-17+0.19682671j])

        It is also possible to evaluate several orders at several points
        at the same time by providing arrays for `v` and `z` with
        compatible shapes for broadcasting. Compute `jve` for two different orders
        `v` and three points `z` resulting in a 2x3 array.

        >>> v = np.array([[1], [3]])
        >>> z = np.array([1j, 2j, 3j])
        >>> v.shape, z.shape
        ((2, 1), (3,))

        >>> jve(v, z)
        array([[1.27304208e-17+0.20791042j,  1.31810070e-17+0.21526929j,
                1.20517622e-17+0.19682671j],
               [-4.99352086e-19-0.00815531j, -1.76289571e-18-0.02879122j,
                -2.92578784e-18-0.04778332j]])

    k0 = <ufunc 'k0'>
        k0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        k0(x, out=None)

        Modified Bessel function of the second kind of order 0, :math:`K_0`.

        This function is also sometimes referred to as the modified Bessel
        function of the third kind of order 0.

        Parameters
        ----------
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the modified Bessel function :math:`K_0` at `x`.

        See Also
        --------
        kv: Modified Bessel function of the second kind of any order
        k0e: Exponentially scaled modified Bessel function of the second kind

        Notes
        -----
        The range is partitioned into the two intervals [0, 2] and (2, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `k0`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import k0
        >>> k0(1.)
        0.42102443824070823

        Calculate the function at several points:

        >>> import numpy as np
        >>> k0(np.array([0.5, 2., 3.]))
        array([0.92441907, 0.11389387, 0.0347395 ])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = k0(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    k0e = <ufunc 'k0e'>
        k0e(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        k0e(x, out=None)

        Exponentially scaled modified Bessel function K of order 0

        Defined as::

            k0e(x) = exp(x) * k0(x).

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the exponentially scaled modified Bessel function K of order
            0 at `x`.

        See Also
        --------
        kv: Modified Bessel function of the second kind of any order
        k0: Modified Bessel function of the second kind

        Notes
        -----
        The range is partitioned into the two intervals [0, 2] and (2, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `k0e`. `k0e` is
        useful for large arguments: for these, `k0` easily underflows.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        In the following example `k0` returns 0 whereas `k0e` still returns a
        useful finite number:

        >>> from scipy.special import k0, k0e
        >>> k0(1000.), k0e(1000)
        (0., 0.03962832160075422)

        Calculate the function at several points by providing a NumPy array or
        list for `x`:

        >>> import numpy as np
        >>> k0e(np.array([0.5, 2., 3.]))
        array([1.52410939, 0.84156822, 0.6977616 ])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = k0e(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    k1 = <ufunc 'k1'>
        k1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        k1(x, out=None)

        Modified Bessel function of the second kind of order 1, :math:`K_1(x)`.

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the modified Bessel function K of order 1 at `x`.

        See Also
        --------
        kv: Modified Bessel function of the second kind of any order
        k1e: Exponentially scaled modified Bessel function K of order 1

        Notes
        -----
        The range is partitioned into the two intervals [0, 2] and (2, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `k1`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import k1
        >>> k1(1.)
        0.6019072301972346

        Calculate the function at several points:

        >>> import numpy as np
        >>> k1(np.array([0.5, 2., 3.]))
        array([1.65644112, 0.13986588, 0.04015643])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = k1(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    k1e = <ufunc 'k1e'>
        k1e(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        k1e(x, out=None)

        Exponentially scaled modified Bessel function K of order 1

        Defined as::

            k1e(x) = exp(x) * k1(x)

        Parameters
        ----------
        x : array_like
            Argument (float)
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        K : scalar or ndarray
            Value of the exponentially scaled modified Bessel function K of order
            1 at `x`.

        See Also
        --------
        kv: Modified Bessel function of the second kind of any order
        k1: Modified Bessel function of the second kind of order 1

        Notes
        -----
        The range is partitioned into the two intervals [0, 2] and (2, infinity).
        Chebyshev polynomial expansions are employed in each interval.

        This function is a wrapper for the Cephes [1]_ routine `k1e`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        In the following example `k1` returns 0 whereas `k1e` still returns a
        useful floating point number.

        >>> from scipy.special import k1, k1e
        >>> k1(1000.), k1e(1000.)
        (0., 0.03964813081296021)

        Calculate the function at several points by providing a NumPy array or
        list for `x`:

        >>> import numpy as np
        >>> k1e(np.array([0.5, 2., 3.]))
        array([2.73100971, 1.03347685, 0.80656348])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = k1e(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    kei = <ufunc 'kei'>
        kei(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        kei(x, out=None)

        Kelvin function kei.

        Defined as

        .. math::

            \mathrm{kei}(x) = \Im[K_0(x e^{\pi i / 4})]

        where :math:`K_0` is the modified Bessel function of the second
        kind (see `kv`). See [dlmf]_ for more details.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the Kelvin function.

        See Also
        --------
        ker : the corresponding real part
        keip : the derivative of kei
        kv : modified Bessel function of the second kind

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10.61

        Examples
        --------
        It can be expressed using the modified Bessel function of the
        second kind.

        >>> import numpy as np
        >>> import scipy.special as sc
        >>> x = np.array([1.0, 2.0, 3.0, 4.0])
        >>> sc.kv(0, x * np.exp(np.pi * 1j / 4)).imag
        array([-0.49499464, -0.20240007, -0.05112188,  0.0021984 ])
        >>> sc.kei(x)
        array([-0.49499464, -0.20240007, -0.05112188,  0.0021984 ])

    keip = <ufunc 'keip'>
        keip(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        keip(x, out=None)

        Derivative of the Kelvin function kei.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            The values of the derivative of kei.

        See Also
        --------
        kei

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10#PT5

    kelvin = <ufunc 'kelvin'>
        kelvin(x[, out1, out2, out3, out4], / [, out=(None, None, None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        kelvin(x, out=None)

        Kelvin functions as complex numbers

        Parameters
        ----------
        x : array_like
            Argument
        out : tuple of ndarray, optional
            Optional output arrays for the function values

        Returns
        -------
        Be, Ke, Bep, Kep : 4-tuple of scalar or ndarray
            The tuple (Be, Ke, Bep, Kep) contains complex numbers
            representing the real and imaginary Kelvin functions and their
            derivatives evaluated at `x`.  For example, kelvin(x)[0].real =
            ber x and kelvin(x)[0].imag = bei x with similar relationships
            for ker and kei.

    ker = <ufunc 'ker'>
        ker(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        ker(x, out=None)

        Kelvin function ker.

        Defined as

        .. math::

            \mathrm{ker}(x) = \Re[K_0(x e^{\pi i / 4})]

        Where :math:`K_0` is the modified Bessel function of the second
        kind (see `kv`). See [dlmf]_ for more details.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the Kelvin function.

        See Also
        --------
        kei : the corresponding imaginary part
        kerp : the derivative of ker
        kv : modified Bessel function of the second kind

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10.61

        Examples
        --------
        It can be expressed using the modified Bessel function of the
        second kind.

        >>> import numpy as np
        >>> import scipy.special as sc
        >>> x = np.array([1.0, 2.0, 3.0, 4.0])
        >>> sc.kv(0, x * np.exp(np.pi * 1j / 4)).real
        array([ 0.28670621, -0.04166451, -0.06702923, -0.03617885])
        >>> sc.ker(x)
        array([ 0.28670621, -0.04166451, -0.06702923, -0.03617885])

    kerp = <ufunc 'kerp'>
        kerp(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        kerp(x, out=None)

        Derivative of the Kelvin function ker.

        Parameters
        ----------
        x : array_like
            Real argument.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the derivative of ker.

        See Also
        --------
        ker

        References
        ----------
        .. [dlmf] NIST, Digital Library of Mathematical Functions,
            https://dlmf.nist.gov/10#PT5

    kl_div = <ufunc 'kl_div'>
        kl_div(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        kl_div(x, y, out=None)

        Elementwise function for computing Kullback-Leibler divergence.

        .. math::

            \mathrm{kl\_div}(x, y) =
              \begin{cases}
                x \log(x / y) - x + y & x > 0, y > 0 \\
                y & x = 0, y \ge 0 \\
                \infty & \text{otherwise}
              \end{cases}

        Parameters
        ----------
        x, y : array_like
            Real arguments
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the Kullback-Liebler divergence.

        See Also
        --------
        entr, rel_entr, scipy.stats.entropy

        Notes
        -----
        .. versionadded:: 0.15.0

        This function is non-negative and is jointly convex in `x` and `y`.

        The origin of this function is in convex programming; see [1]_ for
        details. This is why the function contains the extra :math:`-x
        + y` terms over what might be expected from the Kullback-Leibler
        divergence. For a version of the function without the extra terms,
        see `rel_entr`.

        References
        ----------
        .. [1] Boyd, Stephen and Lieven Vandenberghe. *Convex optimization*.
               Cambridge University Press, 2004.
               :doi:`https://doi.org/10.1017/CBO9780511804441`

    kn = <ufunc 'kn'>
        kn(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        kn(n, x, out=None)

        Modified Bessel function of the second kind of integer order `n`

        Returns the modified Bessel function of the second kind for integer order
        `n` at real `z`.

        These are also sometimes called functions of the third kind, Basset
        functions, or Macdonald functions.

        Parameters
        ----------
        n : array_like of int
            Order of Bessel functions (floats will truncate with a warning)
        x : array_like of float
            Argument at which to evaluate the Bessel functions
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Value of the Modified Bessel function of the second kind,
            :math:`K_n(x)`.

        See Also
        --------
        kv : Same function, but accepts real order and complex argument
        kvp : Derivative of this function

        Notes
        -----
        Wrapper for AMOS [1]_ routine `zbesk`.  For a discussion of the
        algorithm used, see [2]_ and the references therein.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/
        .. [2] Donald E. Amos, "Algorithm 644: A portable package for Bessel
               functions of a complex argument and nonnegative order", ACM
               TOMS Vol. 12 Issue 3, Sept. 1986, p. 265

        Examples
        --------
        Plot the function of several orders for real input:

        >>> import numpy as np
        >>> from scipy.special import kn
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0, 5, 1000)
        >>> for N in range(6):
        ...     plt.plot(x, kn(N, x), label='$K_{}(x)$'.format(N))
        >>> plt.ylim(0, 10)
        >>> plt.legend()
        >>> plt.title(r'Modified Bessel function of the second kind $K_n(x)$')
        >>> plt.show()

        Calculate for a single value at multiple orders:

        >>> kn([4, 5, 6], 1)
        array([   44.23241585,   360.9605896 ,  3653.83831186])

    kolmogi = <ufunc 'kolmogi'>
        kolmogi(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        kolmogi(p, out=None)

        Inverse Survival Function of Kolmogorov distribution

        It is the inverse function to `kolmogorov`.
        Returns y such that ``kolmogorov(y) == p``.

        Parameters
        ----------
        p : float array_like
            Probability
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value(s) of kolmogi(p)

        See Also
        --------
        kolmogorov : The Survival Function for the distribution
        scipy.stats.kstwobign : Provides the functionality as a continuous distribution
        smirnov, smirnovi : Functions for the one-sided distribution

        Notes
        -----
        `kolmogorov` is used by `stats.kstest` in the application of the
        Kolmogorov-Smirnov Goodness of Fit test. For historical reasons this
        function is exposed in `scpy.special`, but the recommended way to achieve
        the most accurate CDF/SF/PDF/PPF/ISF computations is to use the
        `stats.kstwobign` distribution.

        Examples
        --------
        >>> from scipy.special import kolmogi
        >>> kolmogi([0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0])
        array([        inf,  1.22384787,  1.01918472,  0.82757356,  0.67644769,
                0.57117327,  0.        ])

    kolmogorov = <ufunc 'kolmogorov'>
        kolmogorov(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        kolmogorov(y, out=None)

        Complementary cumulative distribution (Survival Function) function of
        Kolmogorov distribution.

        Returns the complementary cumulative distribution function of
        Kolmogorov's limiting distribution (``D_n*\sqrt(n)`` as n goes to infinity)
        of a two-sided test for equality between an empirical and a theoretical
        distribution. It is equal to the (limit as n->infinity of the)
        probability that ``sqrt(n) * max absolute deviation > y``.

        Parameters
        ----------
        y : float array_like
          Absolute deviation between the Empirical CDF (ECDF) and the target CDF,
          multiplied by sqrt(n).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value(s) of kolmogorov(y)

        See Also
        --------
        kolmogi : The Inverse Survival Function for the distribution
        scipy.stats.kstwobign : Provides the functionality as a continuous distribution
        smirnov, smirnovi : Functions for the one-sided distribution

        Notes
        -----
        `kolmogorov` is used by `stats.kstest` in the application of the
        Kolmogorov-Smirnov Goodness of Fit test. For historical reasons this
        function is exposed in `scpy.special`, but the recommended way to achieve
        the most accurate CDF/SF/PDF/PPF/ISF computations is to use the
        `stats.kstwobign` distribution.

        Examples
        --------
        Show the probability of a gap at least as big as 0, 0.5 and 1.0.

        >>> import numpy as np
        >>> from scipy.special import kolmogorov
        >>> from scipy.stats import kstwobign
        >>> kolmogorov([0, 0.5, 1.0])
        array([ 1.        ,  0.96394524,  0.26999967])

        Compare a sample of size 1000 drawn from a Laplace(0, 1) distribution against
        the target distribution, a Normal(0, 1) distribution.

        >>> from scipy.stats import norm, laplace
        >>> rng = np.random.default_rng()
        >>> n = 1000
        >>> lap01 = laplace(0, 1)
        >>> x = np.sort(lap01.rvs(n, random_state=rng))
        >>> np.mean(x), np.std(x)
        (-0.05841730131499543, 1.3968109101997568)

        Construct the Empirical CDF and the K-S statistic Dn.

        >>> target = norm(0,1)  # Normal mean 0, stddev 1
        >>> cdfs = target.cdf(x)
        >>> ecdfs = np.arange(n+1, dtype=float)/n
        >>> gaps = np.column_stack([cdfs - ecdfs[:n], ecdfs[1:] - cdfs])
        >>> Dn = np.max(gaps)
        >>> Kn = np.sqrt(n) * Dn
        >>> print('Dn=%f, sqrt(n)*Dn=%f' % (Dn, Kn))
        Dn=0.043363, sqrt(n)*Dn=1.371265
        >>> print(chr(10).join(['For a sample of size n drawn from a N(0, 1) distribution:',
        ...   ' the approximate Kolmogorov probability that sqrt(n)*Dn>=%f is %f' %
        ...    (Kn, kolmogorov(Kn)),
        ...   ' the approximate Kolmogorov probability that sqrt(n)*Dn<=%f is %f' %
        ...    (Kn, kstwobign.cdf(Kn))]))
        For a sample of size n drawn from a N(0, 1) distribution:
         the approximate Kolmogorov probability that sqrt(n)*Dn>=1.371265 is 0.046533
         the approximate Kolmogorov probability that sqrt(n)*Dn<=1.371265 is 0.953467

        Plot the Empirical CDF against the target N(0, 1) CDF.

        >>> import matplotlib.pyplot as plt
        >>> plt.step(np.concatenate([[-3], x]), ecdfs, where='post', label='Empirical CDF')
        >>> x3 = np.linspace(-3, 3, 100)
        >>> plt.plot(x3, target.cdf(x3), label='CDF for N(0, 1)')
        >>> plt.ylim([0, 1]); plt.grid(True); plt.legend();
        >>> # Add vertical lines marking Dn+ and Dn-
        >>> iminus, iplus = np.argmax(gaps, axis=0)
        >>> plt.vlines([x[iminus]], ecdfs[iminus], cdfs[iminus],
        ...            color='r', linestyle='dashed', lw=4)
        >>> plt.vlines([x[iplus]], cdfs[iplus], ecdfs[iplus+1],
        ...            color='r', linestyle='dashed', lw=4)
        >>> plt.show()

    kv = <ufunc 'kv'>
        kv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        kv(v, z, out=None)

        Modified Bessel function of the second kind of real order `v`

        Returns the modified Bessel function of the second kind for real order
        `v` at complex `z`.

        These are also sometimes called functions of the third kind, Basset
        functions, or Macdonald functions.  They are defined as those solutions
        of the modified Bessel equation for which,

        .. math::
            K_v(x) \sim \sqrt{\pi/(2x)} \exp(-x)

        as :math:`x \to \infty` [3]_.

        Parameters
        ----------
        v : array_like of float
            Order of Bessel functions
        z : array_like of complex
            Argument at which to evaluate the Bessel functions
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The results. Note that input must be of complex type to get complex
            output, e.g. ``kv(3, -2+0j)`` instead of ``kv(3, -2)``.

        See Also
        --------
        kve : This function with leading exponential behavior stripped off.
        kvp : Derivative of this function

        Notes
        -----
        Wrapper for AMOS [1]_ routine `zbesk`.  For a discussion of the
        algorithm used, see [2]_ and the references therein.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/
        .. [2] Donald E. Amos, "Algorithm 644: A portable package for Bessel
               functions of a complex argument and nonnegative order", ACM
               TOMS Vol. 12 Issue 3, Sept. 1986, p. 265
        .. [3] NIST Digital Library of Mathematical Functions,
               Eq. 10.25.E3. https://dlmf.nist.gov/10.25.E3

        Examples
        --------
        Plot the function of several orders for real input:

        >>> import numpy as np
        >>> from scipy.special import kv
        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0, 5, 1000)
        >>> for N in np.linspace(0, 6, 5):
        ...     plt.plot(x, kv(N, x), label='$K_{{{}}}(x)$'.format(N))
        >>> plt.ylim(0, 10)
        >>> plt.legend()
        >>> plt.title(r'Modified Bessel function of the second kind $K_\nu(x)$')
        >>> plt.show()

        Calculate for a single value at multiple orders:

        >>> kv([4, 4.5, 5], 1+2j)
        array([ 0.1992+2.3892j,  2.3493+3.6j   ,  7.2827+3.8104j])

    kve = <ufunc 'kve'>
        kve(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        kve(v, z, out=None)

        Exponentially scaled modified Bessel function of the second kind.

        Returns the exponentially scaled, modified Bessel function of the
        second kind (sometimes called the third kind) for real order `v` at
        complex `z`::

            kve(v, z) = kv(v, z) * exp(z)

        Parameters
        ----------
        v : array_like of float
            Order of Bessel functions
        z : array_like of complex
            Argument at which to evaluate the Bessel functions
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The exponentially scaled modified Bessel function of the second kind.

        See Also
        --------
        kv : This function without exponential scaling.
        k0e : Faster version of this function for order 0.
        k1e : Faster version of this function for order 1.

        Notes
        -----
        Wrapper for AMOS [1]_ routine `zbesk`.  For a discussion of the
        algorithm used, see [2]_ and the references therein.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/
        .. [2] Donald E. Amos, "Algorithm 644: A portable package for Bessel
               functions of a complex argument and nonnegative order", ACM
               TOMS Vol. 12 Issue 3, Sept. 1986, p. 265

        Examples
        --------
        In the following example `kv` returns 0 whereas `kve` still returns
        a useful finite number.

        >>> import numpy as np
        >>> from scipy.special import kv, kve
        >>> import matplotlib.pyplot as plt
        >>> kv(3, 1000.), kve(3, 1000.)
        (0.0, 0.03980696128440973)

        Evaluate the function at one point for different orders by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> kve([0, 1, 1.5], 1.)
        array([1.14446308, 1.63615349, 2.50662827])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> points = np.array([1., 3., 10.])
        >>> kve(0, points)
        array([1.14446308, 0.6977616 , 0.39163193])

        Evaluate the function at several points for different orders by
        providing arrays for both `v` for `z`. Both arrays have to be
        broadcastable to the correct shape. To calculate the orders 0, 1
        and 2 for a 1D array of points:

        >>> kve([[0], [1], [2]], points)
        array([[1.14446308, 0.6977616 , 0.39163193],
               [1.63615349, 0.80656348, 0.41076657],
               [4.41677005, 1.23547058, 0.47378525]])

        Plot the functions of order 0 to 3 from 0 to 5.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 5., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, kve(i, x), label=fr'$K_{i!r}(z)\cdot e^z$')
        >>> ax.legend()
        >>> ax.set_xlabel(r"$z$")
        >>> ax.set_ylim(0, 4)
        >>> ax.set_xlim(0, 5)
        >>> plt.show()

    log1p = <ufunc 'log1p'>
        log1p(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        log1p(x, out=None)

        Calculates log(1 + x) for use when `x` is near zero.

        Parameters
        ----------
        x : array_like
            Real or complex valued input.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of ``log(1 + x)``.

        See Also
        --------
        expm1, cosm1

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than using ``log(1 + x)`` directly for ``x``
        near 0. Note that in the below example ``1 + 1e-17 == 1`` to
        double precision.

        >>> sc.log1p(1e-17)
        1e-17
        >>> np.log(1 + 1e-17)
        0.0

    log_expit = <ufunc 'log_expit'>
        log_expit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        log_expit(x, out=None)

        Logarithm of the logistic sigmoid function.

        The SciPy implementation of the logistic sigmoid function is
        `scipy.special.expit`, so this function is called ``log_expit``.

        The function is mathematically equivalent to ``log(expit(x))``, but
        is formulated to avoid loss of precision for inputs with large
        (positive or negative) magnitude.

        Parameters
        ----------
        x : array_like
            The values to apply ``log_expit`` to element-wise.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        out : scalar or ndarray
            The computed values, an ndarray of the same shape as ``x``.

        See Also
        --------
        expit

        Notes
        -----
        As a ufunc, ``log_expit`` takes a number of optional keyword arguments.
        For more information see
        `ufuncs <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`_

        .. versionadded:: 1.8.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import log_expit, expit

        >>> log_expit([-3.0, 0.25, 2.5, 5.0])
        array([-3.04858735, -0.57593942, -0.07888973, -0.00671535])

        Large negative values:

        >>> log_expit([-100, -500, -1000])
        array([ -100.,  -500., -1000.])

        Note that ``expit(-1000)`` returns 0, so the naive implementation
        ``log(expit(-1000))`` return ``-inf``.

        Large positive values:

        >>> log_expit([29, 120, 400])
        array([-2.54366565e-013, -7.66764807e-053, -1.91516960e-174])

        Compare that to the naive implementation:

        >>> np.log(expit([29, 120, 400]))
        array([-2.54463117e-13,  0.00000000e+00,  0.00000000e+00])

        The first value is accurate to only 3 digits, and the larger inputs
        lose all precision and return 0.

    log_ndtr = <ufunc 'log_ndtr'>
        log_ndtr(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        log_ndtr(x, out=None)

        Logarithm of Gaussian cumulative distribution function.

        Returns the log of the area under the standard Gaussian probability
        density function, integrated from minus infinity to `x`::

            log(1/sqrt(2*pi) * integral(exp(-t**2 / 2), t=-inf..x))

        Parameters
        ----------
        x : array_like, real or complex
            Argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value of the log of the normal CDF evaluated at `x`

        See Also
        --------
        erf
        erfc
        scipy.stats.norm
        ndtr

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import log_ndtr, ndtr

        The benefit of ``log_ndtr(x)`` over the naive implementation
        ``np.log(ndtr(x))`` is most evident with moderate to large positive
        values of ``x``:

        >>> x = np.array([6, 7, 9, 12, 15, 25])
        >>> log_ndtr(x)
        array([-9.86587646e-010, -1.27981254e-012, -1.12858841e-019,
               -1.77648211e-033, -3.67096620e-051, -3.05669671e-138])

        The results of the naive calculation for the moderate ``x`` values
        have only 5 or 6 correct significant digits. For values of ``x``
        greater than approximately 8.3, the naive expression returns 0:

        >>> np.log(ndtr(x))
        array([-9.86587701e-10, -1.27986510e-12,  0.00000000e+00,
                0.00000000e+00,  0.00000000e+00,  0.00000000e+00])

    log_wright_bessel = <ufunc 'log_wright_bessel'>
        log_wright_bessel(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        log_wright_bessel(a, b, x, out=None)

        Natural logarithm of Wright's generalized Bessel function, see `wright_bessel`.
        This function comes in handy in particular for large values of x.

        Parameters
        ----------
        a : array_like of float
            a >= 0
        b : array_like of float
            b >= 0
        x : array_like of float
            x >= 0
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Value of the logarithm of Wright's generalized Bessel function

        Notes
        -----
        Due to the complexity of the function with its three parameters, only
        non-negative arguments are implemented.

        .. versionadded:: 1.14.0

        Examples
        --------
        >>> from scipy.special import log_wright_bessel
        >>> a, b, x = 1.5, 1.1, 2.5
        >>> log_wright_bessel(a, b, x)
        1.1947654935299217

    loggamma = <ufunc 'loggamma'>
        loggamma(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        loggamma(z, out=None)

        Principal branch of the logarithm of the gamma function.

        Defined to be :math:`\log(\Gamma(x))` for :math:`x > 0` and
        extended to the complex plane by analytic continuation. The
        function has a single branch cut on the negative real axis.

        .. versionadded:: 0.18.0

        Parameters
        ----------
        z : array_like
            Values in the complex plane at which to compute ``loggamma``
        out : ndarray, optional
            Output array for computed values of ``loggamma``

        Returns
        -------
        loggamma : scalar or ndarray
            Values of ``loggamma`` at z.

        See Also
        --------
        gammaln : logarithm of the absolute value of the gamma function
        gammasgn : sign of the gamma function

        Notes
        -----
        It is not generally true that :math:`\log\Gamma(z) =
        \log(\Gamma(z))`, though the real parts of the functions do
        agree. The benefit of not defining `loggamma` as
        :math:`\log(\Gamma(z))` is that the latter function has a
        complicated branch cut structure whereas `loggamma` is analytic
        except for on the negative real axis.

        The identities

        .. math::
          \exp(\log\Gamma(z)) &= \Gamma(z) \\
          \log\Gamma(z + 1) &= \log(z) + \log\Gamma(z)

        make `loggamma` useful for working in complex logspace.

        On the real line `loggamma` is related to `gammaln` via
        ``exp(loggamma(x + 0j)) = gammasgn(x)*exp(gammaln(x))``, up to
        rounding error.

        The implementation here is based on [hare1997]_.

        References
        ----------
        .. [hare1997] D.E.G. Hare,
          *Computing the Principal Branch of log-Gamma*,
          Journal of Algorithms, Volume 25, Issue 2, November 1997, pages 221-236.

    logit = <ufunc 'logit'>
        logit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        """
        logit(x, out=None)

        Logit ufunc for ndarrays.

        The logit function is defined as logit(p) = log(p/(1-p)).
        Note that logit(0) = -inf, logit(1) = inf, and logit(p)
        for p<0 or p>1 yields nan.

        Parameters
        ----------
        x : ndarray
            The ndarray to apply logit to element-wise.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            An ndarray of the same shape as x. Its entries
            are logit of the corresponding entry of x.

        See Also
        --------
        expit

        Notes
        -----
        As a ufunc logit takes a number of optional
        keyword arguments. For more information
        see `ufuncs <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`_

        .. versionadded:: 0.10.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import logit, expit

        >>> logit([0, 0.25, 0.5, 0.75, 1])
        array([       -inf, -1.09861229,  0.        ,  1.09861229,         inf])

        `expit` is the inverse of `logit`:

        >>> expit(logit([0.1, 0.75, 0.999]))
        array([ 0.1  ,  0.75 ,  0.999])

        Plot logit(x) for x in [0, 1]:

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0, 1, 501)
        >>> y = logit(x)
        >>> plt.plot(x, y)
        >>> plt.grid()
        >>> plt.ylim(-6, 6)
        >>> plt.xlabel('x')
        >>> plt.title('logit(x)')
        >>> plt.show()

    lpmv = <ufunc 'lpmv'>
        lpmv(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        lpmv(m, v, x, out=None)

        Associated Legendre function of integer order and real degree.

        Defined as

        .. math::

            P_v^m = (-1)^m (1 - x^2)^{m/2} \frac{d^m}{dx^m} P_v(x)

        where

        .. math::

            P_v = \sum_{k = 0}^\infty \frac{(-v)_k (v + 1)_k}{(k!)^2}
                    \left(\frac{1 - x}{2}\right)^k

        is the Legendre function of the first kind. Here :math:`(\cdot)_k`
        is the Pochhammer symbol; see `poch`.

        Parameters
        ----------
        m : array_like
            Order (int or float). If passed a float not equal to an
            integer the function returns NaN.
        v : array_like
            Degree (float).
        x : array_like
            Argument (float). Must have ``|x| <= 1``.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        pmv : scalar or ndarray
            Value of the associated Legendre function.

        See Also
        --------
        lpmn : Compute the associated Legendre function for all orders
               ``0, ..., m`` and degrees ``0, ..., n``.
        clpmn : Compute the associated Legendre function at complex
                arguments.

        Notes
        -----
        Note that this implementation includes the Condon-Shortley phase.

        References
        ----------
        .. [1] Zhang, Jin, "Computation of Special Functions", John Wiley
               and Sons, Inc, 1996.

    mathieu_a = <ufunc 'mathieu_a'>
        mathieu_a(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_a(m, q, out=None)

        Characteristic value of even Mathieu functions

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Characteristic value for the even solution, ``ce_m(z, q)``, of
            Mathieu's equation.

        See Also
        --------
        mathieu_b, mathieu_cem, mathieu_sem

    mathieu_b = <ufunc 'mathieu_b'>
        mathieu_b(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_b(m, q, out=None)

        Characteristic value of odd Mathieu functions

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Characteristic value for the odd solution, ``se_m(z, q)``, of Mathieu's
            equation.

        See Also
        --------
        mathieu_a, mathieu_cem, mathieu_sem

    mathieu_cem = <ufunc 'mathieu_cem'>
        mathieu_cem(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_cem(m, q, x, out=None)

        Even Mathieu function and its derivative

        Returns the even Mathieu function, ``ce_m(x, q)``, of order `m` and
        parameter `q` evaluated at `x` (given in degrees).  Also returns the
        derivative with respect to `x` of ce_m(x, q)

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_a, mathieu_b, mathieu_sem

    mathieu_modcem1 = <ufunc 'mathieu_modcem1'>
        mathieu_modcem1(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_modcem1(m, q, x, out=None)

        Even modified Mathieu function of the first kind and its derivative

        Evaluates the even modified Mathieu function of the first kind,
        ``Mc1m(x, q)``, and its derivative at `x` for order `m` and parameter
        `q`.

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_modsem1

    mathieu_modcem2 = <ufunc 'mathieu_modcem2'>
        mathieu_modcem2(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_modcem2(m, q, x, out=None)

        Even modified Mathieu function of the second kind and its derivative

        Evaluates the even modified Mathieu function of the second kind,
        Mc2m(x, q), and its derivative at `x` (given in degrees) for order `m`
        and parameter `q`.

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_modsem2

    mathieu_modsem1 = <ufunc 'mathieu_modsem1'>
        mathieu_modsem1(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_modsem1(m, q, x, out=None)

        Odd modified Mathieu function of the first kind and its derivative

        Evaluates the odd modified Mathieu function of the first kind,
        Ms1m(x, q), and its derivative at `x` (given in degrees) for order `m`
        and parameter `q`.

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_modcem1

    mathieu_modsem2 = <ufunc 'mathieu_modsem2'>
        mathieu_modsem2(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_modsem2(m, q, x, out=None)

        Odd modified Mathieu function of the second kind and its derivative

        Evaluates the odd modified Mathieu function of the second kind,
        Ms2m(x, q), and its derivative at `x` (given in degrees) for order `m`
        and parameter q.

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_modcem2

    mathieu_sem = <ufunc 'mathieu_sem'>
        mathieu_sem(x1, x2, x3[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        mathieu_sem(m, q, x, out=None)

        Odd Mathieu function and its derivative

        Returns the odd Mathieu function, se_m(x, q), of order `m` and
        parameter `q` evaluated at `x` (given in degrees).  Also returns the
        derivative with respect to `x` of se_m(x, q).

        Parameters
        ----------
        m : array_like
            Order of the function
        q : array_like
            Parameter of the function
        x : array_like
            Argument of the function, *given in degrees, not radians*.
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        y : scalar or ndarray
            Value of the function
        yp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        mathieu_a, mathieu_b, mathieu_cem

    modfresnelm = <ufunc 'modfresnelm'>
        modfresnelm(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        modfresnelm(x, out=None)

        Modified Fresnel negative integrals

        Parameters
        ----------
        x : array_like
            Function argument
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        fm : scalar or ndarray
            Integral ``F_-(x)``: ``integral(exp(-1j*t*t), t=x..inf)``
        km : scalar or ndarray
            Integral ``K_-(x)``: ``1/sqrt(pi)*exp(1j*(x*x+pi/4))*fp``

        See Also
        --------
        modfresnelp

    modfresnelp = <ufunc 'modfresnelp'>
        modfresnelp(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        modfresnelp(x, out=None)

        Modified Fresnel positive integrals

        Parameters
        ----------
        x : array_like
            Function argument
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        fp : scalar or ndarray
            Integral ``F_+(x)``: ``integral(exp(1j*t*t), t=x..inf)``
        kp : scalar or ndarray
            Integral ``K_+(x)``: ``1/sqrt(pi)*exp(-1j*(x*x+pi/4))*fp``

        See Also
        --------
        modfresnelm

    modstruve = <ufunc 'modstruve'>
        modstruve(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        modstruve(v, x, out=None)

        Modified Struve function.

        Return the value of the modified Struve function of order `v` at `x`.  The
        modified Struve function is defined as,

        .. math::
            L_v(x) = -\imath \exp(-\pi\imath v/2) H_v(\imath x),

        where :math:`H_v` is the Struve function.

        Parameters
        ----------
        v : array_like
            Order of the modified Struve function (float).
        x : array_like
            Argument of the Struve function (float; must be positive unless `v` is
            an integer).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        L : scalar or ndarray
            Value of the modified Struve function of order `v` at `x`.

        See Also
        --------
        struve

        Notes
        -----
        Three methods discussed in [1]_ are used to evaluate the function:

        - power series
        - expansion in Bessel functions (if :math:`|x| < |v| + 20`)
        - asymptotic large-x expansion (if :math:`x \geq 0.7v + 12`)

        Rounding errors are estimated based on the largest terms in the sums, and
        the result associated with the smallest error is returned.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/11

        Examples
        --------
        Calculate the modified Struve function of order 1 at 2.

        >>> import numpy as np
        >>> from scipy.special import modstruve
        >>> import matplotlib.pyplot as plt
        >>> modstruve(1, 2.)
        1.102759787367716

        Calculate the modified Struve function at 2 for orders 1, 2 and 3 by
        providing a list for the order parameter `v`.

        >>> modstruve([1, 2, 3], 2.)
        array([1.10275979, 0.41026079, 0.11247294])

        Calculate the modified Struve function of order 1 for several points
        by providing an array for `x`.

        >>> points = np.array([2., 5., 8.])
        >>> modstruve(1, points)
        array([  1.10275979,  23.72821578, 399.24709139])

        Compute the modified Struve function for several orders at several
        points by providing arrays for `v` and `z`. The arrays have to be
        broadcastable to the correct shapes.

        >>> orders = np.array([[1], [2], [3]])
        >>> points.shape, orders.shape
        ((3,), (3, 1))

        >>> modstruve(orders, points)
        array([[1.10275979e+00, 2.37282158e+01, 3.99247091e+02],
               [4.10260789e-01, 1.65535979e+01, 3.25973609e+02],
               [1.12472937e-01, 9.42430454e+00, 2.33544042e+02]])

        Plot the modified Struve functions of order 0 to 3 from -5 to 5.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-5., 5., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, modstruve(i, x), label=f'$L_{i!r}$')
        >>> ax.legend(ncol=2)
        >>> ax.set_xlim(-5, 5)
        >>> ax.set_title(r"Modified Struve functions $L_{\nu}$")
        >>> plt.show()

    nbdtr = <ufunc 'nbdtr'>
        nbdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nbdtr(k, n, p, out=None)

        Negative binomial cumulative distribution function.

        Returns the sum of the terms 0 through `k` of the negative binomial
        distribution probability mass function,

        .. math::

            F = \sum_{j=0}^k {{n + j - 1}\choose{j}} p^n (1 - p)^j.

        In a sequence of Bernoulli trials with individual success probabilities
        `p`, this is the probability that `k` or fewer failures precede the nth
        success.

        Parameters
        ----------
        k : array_like
            The maximum number of allowed failures (nonnegative int).
        n : array_like
            The target number of successes (positive int).
        p : array_like
            Probability of success in a single event (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        F : scalar or ndarray
            The probability of `k` or fewer failures before `n` successes in a
            sequence of events with individual success probability `p`.

        See Also
        --------
        nbdtrc : Negative binomial survival function
        nbdtrik : Negative binomial quantile function
        scipy.stats.nbinom : Negative binomial distribution

        Notes
        -----
        If floating point values are passed for `k` or `n`, they will be truncated
        to integers.

        The terms are not summed directly; instead the regularized incomplete beta
        function is employed, according to the formula,

        .. math::
            \mathrm{nbdtr}(k, n, p) = I_{p}(n, k + 1).

        Wrapper for the Cephes [1]_ routine `nbdtr`.

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. Using `nbdtr` directly can improve performance
        compared to the ``cdf`` method of `scipy.stats.nbinom` (see last example).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Compute the function for ``k=10`` and ``n=5`` at ``p=0.5``.

        >>> import numpy as np
        >>> from scipy.special import nbdtr
        >>> nbdtr(10, 5, 0.5)
        0.940765380859375

        Compute the function for ``n=10`` and ``p=0.5`` at several points by
        providing a NumPy array or list for `k`.

        >>> nbdtr([5, 10, 15], 10, 0.5)
        array([0.15087891, 0.58809853, 0.88523853])

        Plot the function for four different parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> k = np.arange(130)
        >>> n_parameters = [20, 20, 20, 80]
        >>> p_parameters = [0.2, 0.5, 0.8, 0.5]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(p_parameters, n_parameters,
        ...                            linestyles))
        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> for parameter_set in parameters_list:
        ...     p, n, style = parameter_set
        ...     nbdtr_vals = nbdtr(k, n, p)
        ...     ax.plot(k, nbdtr_vals, label=rf"$n={n},\, p={p}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$k$")
        >>> ax.set_title("Negative binomial cumulative distribution function")
        >>> plt.show()

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. Using `nbdtr` directly can be much faster than
        calling the ``cdf`` method of `scipy.stats.nbinom`, especially for small
        arrays or individual values. To get the same results one must use the
        following parametrization: ``nbinom(n, p).cdf(k)=nbdtr(k, n, p)``.

        >>> from scipy.stats import nbinom
        >>> k, n, p = 5, 3, 0.5
        >>> nbdtr_res = nbdtr(k, n, p)  # this will often be faster than below
        >>> stats_res = nbinom(n, p).cdf(k)
        >>> stats_res, nbdtr_res  # test that results are equal
        (0.85546875, 0.85546875)

        `nbdtr` can evaluate different parameter sets by providing arrays with
        shapes compatible for broadcasting for `k`, `n` and `p`. Here we compute
        the function for three different `k` at four locations `p`, resulting in
        a 3x4 array.

        >>> k = np.array([[5], [10], [15]])
        >>> p = np.array([0.3, 0.5, 0.7, 0.9])
        >>> k.shape, p.shape
        ((3, 1), (4,))

        >>> nbdtr(k, 5, p)
        array([[0.15026833, 0.62304687, 0.95265101, 0.9998531 ],
               [0.48450894, 0.94076538, 0.99932777, 0.99999999],
               [0.76249222, 0.99409103, 0.99999445, 1.        ]])

    nbdtrc = <ufunc 'nbdtrc'>
        nbdtrc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nbdtrc(k, n, p, out=None)

        Negative binomial survival function.

        Returns the sum of the terms `k + 1` to infinity of the negative binomial
        distribution probability mass function,

        .. math::

            F = \sum_{j=k + 1}^\infty {{n + j - 1}\choose{j}} p^n (1 - p)^j.

        In a sequence of Bernoulli trials with individual success probabilities
        `p`, this is the probability that more than `k` failures precede the nth
        success.

        Parameters
        ----------
        k : array_like
            The maximum number of allowed failures (nonnegative int).
        n : array_like
            The target number of successes (positive int).
        p : array_like
            Probability of success in a single event (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        F : scalar or ndarray
            The probability of `k + 1` or more failures before `n` successes in a
            sequence of events with individual success probability `p`.

        See Also
        --------
        nbdtr : Negative binomial cumulative distribution function
        nbdtrik : Negative binomial percentile function
        scipy.stats.nbinom : Negative binomial distribution

        Notes
        -----
        If floating point values are passed for `k` or `n`, they will be truncated
        to integers.

        The terms are not summed directly; instead the regularized incomplete beta
        function is employed, according to the formula,

        .. math::
            \mathrm{nbdtrc}(k, n, p) = I_{1 - p}(k + 1, n).

        Wrapper for the Cephes [1]_ routine `nbdtrc`.

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. Using `nbdtrc` directly can improve performance
        compared to the ``sf`` method of `scipy.stats.nbinom` (see last example).

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Compute the function for ``k=10`` and ``n=5`` at ``p=0.5``.

        >>> import numpy as np
        >>> from scipy.special import nbdtrc
        >>> nbdtrc(10, 5, 0.5)
        0.059234619140624986

        Compute the function for ``n=10`` and ``p=0.5`` at several points by
        providing a NumPy array or list for `k`.

        >>> nbdtrc([5, 10, 15], 10, 0.5)
        array([0.84912109, 0.41190147, 0.11476147])

        Plot the function for four different parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> k = np.arange(130)
        >>> n_parameters = [20, 20, 20, 80]
        >>> p_parameters = [0.2, 0.5, 0.8, 0.5]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(p_parameters, n_parameters,
        ...                            linestyles))
        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> for parameter_set in parameters_list:
        ...     p, n, style = parameter_set
        ...     nbdtrc_vals = nbdtrc(k, n, p)
        ...     ax.plot(k, nbdtrc_vals, label=rf"$n={n},\, p={p}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_xlabel("$k$")
        >>> ax.set_title("Negative binomial distribution survival function")
        >>> plt.show()

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. Using `nbdtrc` directly can be much faster than
        calling the ``sf`` method of `scipy.stats.nbinom`, especially for small
        arrays or individual values. To get the same results one must use the
        following parametrization: ``nbinom(n, p).sf(k)=nbdtrc(k, n, p)``.

        >>> from scipy.stats import nbinom
        >>> k, n, p = 3, 5, 0.5
        >>> nbdtr_res = nbdtrc(k, n, p)  # this will often be faster than below
        >>> stats_res = nbinom(n, p).sf(k)
        >>> stats_res, nbdtr_res  # test that results are equal
        (0.6367187499999999, 0.6367187499999999)

        `nbdtrc` can evaluate different parameter sets by providing arrays with
        shapes compatible for broadcasting for `k`, `n` and `p`. Here we compute
        the function for three different `k` at four locations `p`, resulting in
        a 3x4 array.

        >>> k = np.array([[5], [10], [15]])
        >>> p = np.array([0.3, 0.5, 0.7, 0.9])
        >>> k.shape, p.shape
        ((3, 1), (4,))

        >>> nbdtrc(k, 5, p)
        array([[8.49731667e-01, 3.76953125e-01, 4.73489874e-02, 1.46902600e-04],
               [5.15491059e-01, 5.92346191e-02, 6.72234070e-04, 9.29610100e-09],
               [2.37507779e-01, 5.90896606e-03, 5.55025308e-06, 3.26346760e-13]])

    nbdtri = <ufunc 'nbdtri'>
        nbdtri(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nbdtri(k, n, y, out=None)

        Returns the inverse with respect to the parameter `p` of
        `y = nbdtr(k, n, p)`, the negative binomial cumulative distribution
        function.

        Parameters
        ----------
        k : array_like
            The maximum number of allowed failures (nonnegative int).
        n : array_like
            The target number of successes (positive int).
        y : array_like
            The probability of `k` or fewer failures before `n` successes (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        p : scalar or ndarray
            Probability of success in a single event (float) such that
            `nbdtr(k, n, p) = y`.

        See Also
        --------
        nbdtr : Cumulative distribution function of the negative binomial.
        nbdtrc : Negative binomial survival function.
        scipy.stats.nbinom : negative binomial distribution.
        nbdtrik : Inverse with respect to `k` of `nbdtr(k, n, p)`.
        nbdtrin : Inverse with respect to `n` of `nbdtr(k, n, p)`.
        scipy.stats.nbinom : Negative binomial distribution

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `nbdtri`.

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. Using `nbdtri` directly can improve performance
        compared to the ``ppf`` method of `scipy.stats.nbinom`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        `nbdtri` is the inverse of `nbdtr` with respect to `p`.
        Up to floating point errors the following holds:
        ``nbdtri(k, n, nbdtr(k, n, p))=p``.

        >>> import numpy as np
        >>> from scipy.special import nbdtri, nbdtr
        >>> k, n, y = 5, 10, 0.2
        >>> cdf_val = nbdtr(k, n, y)
        >>> nbdtri(k, n, cdf_val)
        0.20000000000000004

        Compute the function for ``k=10`` and ``n=5`` at several points by
        providing a NumPy array or list for `y`.

        >>> y = np.array([0.1, 0.4, 0.8])
        >>> nbdtri(3, 5, y)
        array([0.34462319, 0.51653095, 0.69677416])

        Plot the function for three different parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> n_parameters = [5, 20, 30, 30]
        >>> k_parameters = [20, 20, 60, 80]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(n_parameters, k_parameters, linestyles))
        >>> cdf_vals = np.linspace(0, 1, 1000)
        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> for parameter_set in parameters_list:
        ...     n, k, style = parameter_set
        ...     nbdtri_vals = nbdtri(k, n, cdf_vals)
        ...     ax.plot(cdf_vals, nbdtri_vals, label=rf"$k={k},\ n={n}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_ylabel("$p$")
        >>> ax.set_xlabel("$CDF$")
        >>> title = "nbdtri: inverse of negative binomial CDF with respect to $p$"
        >>> ax.set_title(title)
        >>> plt.show()

        `nbdtri` can evaluate different parameter sets by providing arrays with
        shapes compatible for broadcasting for `k`, `n` and `p`. Here we compute
        the function for three different `k` at four locations `p`, resulting in
        a 3x4 array.

        >>> k = np.array([[5], [10], [15]])
        >>> y = np.array([0.3, 0.5, 0.7, 0.9])
        >>> k.shape, y.shape
        ((3, 1), (4,))

        >>> nbdtri(k, 5, y)
        array([[0.37258157, 0.45169416, 0.53249956, 0.64578407],
               [0.24588501, 0.30451981, 0.36778453, 0.46397088],
               [0.18362101, 0.22966758, 0.28054743, 0.36066188]])

    nbdtrik = <ufunc 'nbdtrik'>
        nbdtrik(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nbdtrik(y, n, p, out=None)

        Negative binomial percentile function.

        Returns the inverse with respect to the parameter `k` of
        `y = nbdtr(k, n, p)`, the negative binomial cumulative distribution
        function.

        Parameters
        ----------
        y : array_like
            The probability of `k` or fewer failures before `n` successes (float).
        n : array_like
            The target number of successes (positive int).
        p : array_like
            Probability of success in a single event (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        k : scalar or ndarray
            The maximum number of allowed failures such that `nbdtr(k, n, p) = y`.

        See Also
        --------
        nbdtr : Cumulative distribution function of the negative binomial.
        nbdtrc : Survival function of the negative binomial.
        nbdtri : Inverse with respect to `p` of `nbdtr(k, n, p)`.
        nbdtrin : Inverse with respect to `n` of `nbdtr(k, n, p)`.
        scipy.stats.nbinom : Negative binomial distribution

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfnbn`.

        Formula 26.5.26 of [2]_,

        .. math::
            \sum_{j=k + 1}^\infty {{n + j - 1}
            \choose{j}} p^n (1 - p)^j = I_{1 - p}(k + 1, n),

        is used to reduce calculation of the cumulative distribution function to
        that of a regularized incomplete beta :math:`I`.

        Computation of `k` involves a search for a value that produces the desired
        value of `y`.  The search relies on the monotonicity of `y` with `k`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        Compute the negative binomial cumulative distribution function for an
        exemplary parameter set.

        >>> import numpy as np
        >>> from scipy.special import nbdtr, nbdtrik
        >>> k, n, p = 5, 2, 0.5
        >>> cdf_value = nbdtr(k, n, p)
        >>> cdf_value
        0.9375

        Verify that `nbdtrik` recovers the original value for `k`.

        >>> nbdtrik(cdf_value, n, p)
        5.0

        Plot the function for different parameter sets.

        >>> import matplotlib.pyplot as plt
        >>> p_parameters = [0.2, 0.5, 0.7, 0.5]
        >>> n_parameters = [30, 30, 30, 80]
        >>> linestyles = ['solid', 'dashed', 'dotted', 'dashdot']
        >>> parameters_list = list(zip(p_parameters, n_parameters, linestyles))
        >>> cdf_vals = np.linspace(0, 1, 1000)
        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> for parameter_set in parameters_list:
        ...     p, n, style = parameter_set
        ...     nbdtrik_vals = nbdtrik(cdf_vals, n, p)
        ...     ax.plot(cdf_vals, nbdtrik_vals, label=rf"$n={n},\ p={p}$",
        ...             ls=style)
        >>> ax.legend()
        >>> ax.set_ylabel("$k$")
        >>> ax.set_xlabel("$CDF$")
        >>> ax.set_title("Negative binomial percentile function")
        >>> plt.show()

        The negative binomial distribution is also available as
        `scipy.stats.nbinom`. The percentile function  method ``ppf``
        returns the result of `nbdtrik` rounded up to integers:

        >>> from scipy.stats import nbinom
        >>> q, n, p = 0.6, 5, 0.5
        >>> nbinom.ppf(q, n, p), nbdtrik(q, n, p)
        (5.0, 4.800428460273882)

    nbdtrin = <ufunc 'nbdtrin'>
        nbdtrin(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nbdtrin(k, y, p, out=None)

        Inverse of `nbdtr` vs `n`.

        Returns the inverse with respect to the parameter `n` of
        `y = nbdtr(k, n, p)`, the negative binomial cumulative distribution
        function.

        Parameters
        ----------
        k : array_like
            The maximum number of allowed failures (nonnegative int).
        y : array_like
            The probability of `k` or fewer failures before `n` successes (float).
        p : array_like
            Probability of success in a single event (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        n : scalar or ndarray
            The number of successes `n` such that `nbdtr(k, n, p) = y`.

        See Also
        --------
        nbdtr : Cumulative distribution function of the negative binomial.
        nbdtri : Inverse with respect to `p` of `nbdtr(k, n, p)`.
        nbdtrik : Inverse with respect to `k` of `nbdtr(k, n, p)`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdfnbn`.

        Formula 26.5.26 of [2]_,

        .. math::
            \sum_{j=k + 1}^\infty {{n + j - 1}
            \choose{j}} p^n (1 - p)^j = I_{1 - p}(k + 1, n),

        is used to reduce calculation of the cumulative distribution function to
        that of a regularized incomplete beta :math:`I`.

        Computation of `n` involves a search for a value that produces the desired
        value of `y`.  The search relies on the monotonicity of `y` with `n`.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        Compute the negative binomial cumulative distribution function for an
        exemplary parameter set.

        >>> from scipy.special import nbdtr, nbdtrin
        >>> k, n, p = 5, 2, 0.5
        >>> cdf_value = nbdtr(k, n, p)
        >>> cdf_value
        0.9375

        Verify that `nbdtrin` recovers the original value for `n` up to floating
        point accuracy.

        >>> nbdtrin(k, cdf_value, p)
        1.999999999998137

    ncfdtr = <ufunc 'ncfdtr'>
        ncfdtr(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ncfdtr(dfn, dfd, nc, f, out=None)

        Cumulative distribution function of the non-central F distribution.

        The non-central F describes the distribution of,

        .. math::
            Z = \frac{X/d_n}{Y/d_d}

        where :math:`X` and :math:`Y` are independently distributed, with
        :math:`X` distributed non-central :math:`\chi^2` with noncentrality
        parameter `nc` and :math:`d_n` degrees of freedom, and :math:`Y`
        distributed :math:`\chi^2` with :math:`d_d` degrees of freedom.

        Parameters
        ----------
        dfn : array_like
            Degrees of freedom of the numerator sum of squares.  Range (0, inf).
        dfd : array_like
            Degrees of freedom of the denominator sum of squares.  Range (0, inf).
        nc : array_like
            Noncentrality parameter.  Should be in range (0, 1e4).
        f : array_like
            Quantiles, i.e. the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        cdf : scalar or ndarray
            The calculated CDF.  If all inputs are scalar, the return will be a
            float.  Otherwise it will be an array.

        See Also
        --------
        ncfdtri : Quantile function; inverse of `ncfdtr` with respect to `f`.
        ncfdtridfd : Inverse of `ncfdtr` with respect to `dfd`.
        ncfdtridfn : Inverse of `ncfdtr` with respect to `dfn`.
        ncfdtrinc : Inverse of `ncfdtr` with respect to `nc`.

        Notes
        -----
        Wrapper for the CDFLIB [1]_ Fortran routine `cdffnc`.

        The cumulative distribution function is computed using Formula 26.6.20 of
        [2]_:

        .. math::
            F(d_n, d_d, n_c, f) = \sum_{j=0}^\infty e^{-n_c/2}
            \frac{(n_c/2)^j}{j!} I_{x}(\frac{d_n}{2} + j, \frac{d_d}{2}),

        where :math:`I` is the regularized incomplete beta function, and
        :math:`x = f d_n/(f d_n + d_d)`.

        The computation time required for this routine is proportional to the
        noncentrality parameter `nc`.  Very large values of this parameter can
        consume immense computer resources.  This is why the search range is
        bounded by 10,000.

        References
        ----------
        .. [1] Barry Brown, James Lovato, and Kathy Russell,
               CDFLIB: Library of Fortran Routines for Cumulative Distribution
               Functions, Inverses, and Other Parameters.
        .. [2] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        Plot the CDF of the non-central F distribution, for nc=0.  Compare with the
        F-distribution from scipy.stats:

        >>> x = np.linspace(-1, 8, num=500)
        >>> dfn = 3
        >>> dfd = 2
        >>> ncf_stats = stats.f.cdf(x, dfn, dfd)
        >>> ncf_special = special.ncfdtr(dfn, dfd, 0, x)

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, ncf_stats, 'b-', lw=3)
        >>> ax.plot(x, ncf_special, 'r-')
        >>> plt.show()

    ncfdtri = <ufunc 'ncfdtri'>
        ncfdtri(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ncfdtri(dfn, dfd, nc, p, out=None)

        Inverse with respect to `f` of the CDF of the non-central F distribution.

        See `ncfdtr` for more details.

        Parameters
        ----------
        dfn : array_like
            Degrees of freedom of the numerator sum of squares.  Range (0, inf).
        dfd : array_like
            Degrees of freedom of the denominator sum of squares.  Range (0, inf).
        nc : array_like
            Noncentrality parameter.  Should be in range (0, 1e4).
        p : array_like
            Value of the cumulative distribution function.  Must be in the
            range [0, 1].
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        f : scalar or ndarray
            Quantiles, i.e., the upper limit of integration.

        See Also
        --------
        ncfdtr : CDF of the non-central F distribution.
        ncfdtridfd : Inverse of `ncfdtr` with respect to `dfd`.
        ncfdtridfn : Inverse of `ncfdtr` with respect to `dfn`.
        ncfdtrinc : Inverse of `ncfdtr` with respect to `nc`.

        Examples
        --------
        >>> from scipy.special import ncfdtr, ncfdtri

        Compute the CDF for several values of `f`:

        >>> f = [0.5, 1, 1.5]
        >>> p = ncfdtr(2, 3, 1.5, f)
        >>> p
        array([ 0.20782291,  0.36107392,  0.47345752])

        Compute the inverse.  We recover the values of `f`, as expected:

        >>> ncfdtri(2, 3, 1.5, p)
        array([ 0.5,  1. ,  1.5])

    ncfdtridfd = <ufunc 'ncfdtridfd'>
        ncfdtridfd(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ncfdtridfd(dfn, p, nc, f, out=None)

        Calculate degrees of freedom (denominator) for the noncentral F-distribution.

        This is the inverse with respect to `dfd` of `ncfdtr`.
        See `ncfdtr` for more details.

        Parameters
        ----------
        dfn : array_like
            Degrees of freedom of the numerator sum of squares.  Range (0, inf).
        p : array_like
            Value of the cumulative distribution function.  Must be in the
            range [0, 1].
        nc : array_like
            Noncentrality parameter.  Should be in range (0, 1e4).
        f : array_like
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        dfd : scalar or ndarray
            Degrees of freedom of the denominator sum of squares.

        See Also
        --------
        ncfdtr : CDF of the non-central F distribution.
        ncfdtri : Quantile function; inverse of `ncfdtr` with respect to `f`.
        ncfdtridfn : Inverse of `ncfdtr` with respect to `dfn`.
        ncfdtrinc : Inverse of `ncfdtr` with respect to `nc`.

        Notes
        -----
        The value of the cumulative noncentral F distribution is not necessarily
        monotone in either degrees of freedom. There thus may be two values that
        provide a given CDF value. This routine assumes monotonicity and will
        find an arbitrary one of the two values.

        Examples
        --------
        >>> from scipy.special import ncfdtr, ncfdtridfd

        Compute the CDF for several values of `dfd`:

        >>> dfd = [1, 2, 3]
        >>> p = ncfdtr(2, dfd, 0.25, 15)
        >>> p
        array([ 0.8097138 ,  0.93020416,  0.96787852])

        Compute the inverse.  We recover the values of `dfd`, as expected:

        >>> ncfdtridfd(2, p, 0.25, 15)
        array([ 1.,  2.,  3.])

    ncfdtridfn = <ufunc 'ncfdtridfn'>
        ncfdtridfn(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ncfdtridfn(p, dfd, nc, f, out=None)

        Calculate degrees of freedom (numerator) for the noncentral F-distribution.

        This is the inverse with respect to `dfn` of `ncfdtr`.
        See `ncfdtr` for more details.

        Parameters
        ----------
        p : array_like
            Value of the cumulative distribution function. Must be in the
            range [0, 1].
        dfd : array_like
            Degrees of freedom of the denominator sum of squares. Range (0, inf).
        nc : array_like
            Noncentrality parameter.  Should be in range (0, 1e4).
        f : float
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        dfn : scalar or ndarray
            Degrees of freedom of the numerator sum of squares.

        See Also
        --------
        ncfdtr : CDF of the non-central F distribution.
        ncfdtri : Quantile function; inverse of `ncfdtr` with respect to `f`.
        ncfdtridfd : Inverse of `ncfdtr` with respect to `dfd`.
        ncfdtrinc : Inverse of `ncfdtr` with respect to `nc`.

        Notes
        -----
        The value of the cumulative noncentral F distribution is not necessarily
        monotone in either degrees of freedom. There thus may be two values that
        provide a given CDF value. This routine assumes monotonicity and will
        find an arbitrary one of the two values.

        Examples
        --------
        >>> from scipy.special import ncfdtr, ncfdtridfn

        Compute the CDF for several values of `dfn`:

        >>> dfn = [1, 2, 3]
        >>> p = ncfdtr(dfn, 2, 0.25, 15)
        >>> p
        array([ 0.92562363,  0.93020416,  0.93188394])

        Compute the inverse. We recover the values of `dfn`, as expected:

        >>> ncfdtridfn(p, 2, 0.25, 15)
        array([ 1.,  2.,  3.])

    ncfdtrinc = <ufunc 'ncfdtrinc'>
        ncfdtrinc(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ncfdtrinc(dfn, dfd, p, f, out=None)

        Calculate non-centrality parameter for non-central F distribution.

        This is the inverse with respect to `nc` of `ncfdtr`.
        See `ncfdtr` for more details.

        Parameters
        ----------
        dfn : array_like
            Degrees of freedom of the numerator sum of squares. Range (0, inf).
        dfd : array_like
            Degrees of freedom of the denominator sum of squares. Range (0, inf).
        p : array_like
            Value of the cumulative distribution function. Must be in the
            range [0, 1].
        f : array_like
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        nc : scalar or ndarray
            Noncentrality parameter.

        See Also
        --------
        ncfdtr : CDF of the non-central F distribution.
        ncfdtri : Quantile function; inverse of `ncfdtr` with respect to `f`.
        ncfdtridfd : Inverse of `ncfdtr` with respect to `dfd`.
        ncfdtridfn : Inverse of `ncfdtr` with respect to `dfn`.

        Examples
        --------
        >>> from scipy.special import ncfdtr, ncfdtrinc

        Compute the CDF for several values of `nc`:

        >>> nc = [0.5, 1.5, 2.0]
        >>> p = ncfdtr(2, 3, nc, 15)
        >>> p
        array([ 0.96309246,  0.94327955,  0.93304098])

        Compute the inverse. We recover the values of `nc`, as expected:

        >>> ncfdtrinc(2, 3, p, 15)
        array([ 0.5,  1.5,  2. ])

    nctdtr = <ufunc 'nctdtr'>
        nctdtr(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nctdtr(df, nc, t, out=None)

        Cumulative distribution function of the non-central `t` distribution.

        Parameters
        ----------
        df : array_like
            Degrees of freedom of the distribution. Should be in range (0, inf).
        nc : array_like
            Noncentrality parameter. Should be in range (-1e6, 1e6).
        t : array_like
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        cdf : scalar or ndarray
            The calculated CDF. If all inputs are scalar, the return will be a
            float. Otherwise, it will be an array.

        See Also
        --------
        nctdtrit : Inverse CDF (iCDF) of the non-central t distribution.
        nctdtridf : Calculate degrees of freedom, given CDF and iCDF values.
        nctdtrinc : Calculate non-centrality parameter, given CDF iCDF values.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        Plot the CDF of the non-central t distribution, for nc=0. Compare with the
        t-distribution from scipy.stats:

        >>> x = np.linspace(-5, 5, num=500)
        >>> df = 3
        >>> nct_stats = stats.t.cdf(x, df)
        >>> nct_special = special.nctdtr(df, 0, x)

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, nct_stats, 'b-', lw=3)
        >>> ax.plot(x, nct_special, 'r-')
        >>> plt.show()

    nctdtridf = <ufunc 'nctdtridf'>
        nctdtridf(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nctdtridf(p, nc, t, out=None)

        Calculate degrees of freedom for non-central t distribution.

        See `nctdtr` for more details.

        Parameters
        ----------
        p : array_like
            CDF values, in range (0, 1].
        nc : array_like
            Noncentrality parameter. Should be in range (-1e6, 1e6).
        t : array_like
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        df : scalar or ndarray
            The degrees of freedom. If all inputs are scalar, the return will be a
            float. Otherwise, it will be an array.

        See Also
        --------
        nctdtr :  CDF of the non-central `t` distribution.
        nctdtrit : Inverse CDF (iCDF) of the non-central t distribution.
        nctdtrinc : Calculate non-centrality parameter, given CDF iCDF values.

        Examples
        --------
        >>> from scipy.special import nctdtr, nctdtridf

        Compute the CDF for several values of `df`:

        >>> df = [1, 2, 3]
        >>> p = nctdtr(df, 0.25, 1)
        >>> p
        array([0.67491974, 0.716464  , 0.73349456])

        Compute the inverse. We recover the values of `df`, as expected:

        >>> nctdtridf(p, 0.25, 1)
        array([1., 2., 3.])

    nctdtrinc = <ufunc 'nctdtrinc'>
        nctdtrinc(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nctdtrinc(df, p, t, out=None)

        Calculate non-centrality parameter for non-central t distribution.

        See `nctdtr` for more details.

        Parameters
        ----------
        df : array_like
            Degrees of freedom of the distribution. Should be in range (0, inf).
        p : array_like
            CDF values, in range (0, 1].
        t : array_like
            Quantiles, i.e., the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        nc : scalar or ndarray
            Noncentrality parameter

        See Also
        --------
        nctdtr :  CDF of the non-central `t` distribution.
        nctdtrit : Inverse CDF (iCDF) of the non-central t distribution.
        nctdtridf : Calculate degrees of freedom, given CDF and iCDF values.

        Examples
        --------
        >>> from scipy.special import nctdtr, nctdtrinc

        Compute the CDF for several values of `nc`:

        >>> nc = [0.5, 1.5, 2.5]
        >>> p = nctdtr(3, nc, 1.5)
        >>> p
        array([0.77569497, 0.45524533, 0.1668691 ])

        Compute the inverse. We recover the values of `nc`, as expected:

        >>> nctdtrinc(3, p, 1.5)
        array([0.5, 1.5, 2.5])

    nctdtrit = <ufunc 'nctdtrit'>
        nctdtrit(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nctdtrit(df, nc, p, out=None)

        Inverse cumulative distribution function of the non-central t distribution.

        See `nctdtr` for more details.

        Parameters
        ----------
        df : array_like
            Degrees of freedom of the distribution. Should be in range (0, inf).
        nc : array_like
            Noncentrality parameter. Should be in range (-1e6, 1e6).
        p : array_like
            CDF values, in range (0, 1].
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        t : scalar or ndarray
            Quantiles

        See Also
        --------
        nctdtr :  CDF of the non-central `t` distribution.
        nctdtridf : Calculate degrees of freedom, given CDF and iCDF values.
        nctdtrinc : Calculate non-centrality parameter, given CDF iCDF values.

        Examples
        --------
        >>> from scipy.special import nctdtr, nctdtrit

        Compute the CDF for several values of `t`:

        >>> t = [0.5, 1, 1.5]
        >>> p = nctdtr(3, 1, t)
        >>> p
        array([0.29811049, 0.46922687, 0.6257559 ])

        Compute the inverse. We recover the values of `t`, as expected:

        >>> nctdtrit(3, 1, p)
        array([0.5, 1. , 1.5])

    ndtr = <ufunc 'ndtr'>
        ndtr(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ndtr(x, out=None)

        Cumulative distribution of the standard normal distribution.

        Returns the area under the standard Gaussian probability
        density function, integrated from minus infinity to `x`

        .. math::

           \frac{1}{\sqrt{2\pi}} \int_{-\infty}^x \exp(-t^2/2) dt

        Parameters
        ----------
        x : array_like, real or complex
            Argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value of the normal CDF evaluated at `x`

        See Also
        --------
        log_ndtr : Logarithm of ndtr
        ndtri : Inverse of ndtr, standard normal percentile function
        erf : Error function
        erfc : 1 - erf
        scipy.stats.norm : Normal distribution

        Examples
        --------
        Evaluate `ndtr` at one point.

        >>> import numpy as np
        >>> from scipy.special import ndtr
        >>> ndtr(0.5)
        0.6914624612740131

        Evaluate the function at several points by providing a NumPy array
        or list for `x`.

        >>> ndtr([0, 0.5, 2])
        array([0.5       , 0.69146246, 0.97724987])

        Plot the function.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(-5, 5, 100)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, ndtr(x))
        >>> ax.set_title(r"Standard normal cumulative distribution function $\Phi$")
        >>> plt.show()

    ndtri = <ufunc 'ndtri'>
        ndtri(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ndtri(y, out=None)

        Inverse of `ndtr` vs x

        Returns the argument x for which the area under the standard normal
        probability density function (integrated from minus infinity to `x`)
        is equal to y.

        Parameters
        ----------
        p : array_like
            Probability
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        x : scalar or ndarray
            Value of x such that ``ndtr(x) == p``.

        See Also
        --------
        ndtr : Standard normal cumulative probability distribution
        ndtri_exp : Inverse of log_ndtr

        Examples
        --------
        `ndtri` is the percentile function of the standard normal distribution.
        This means it returns the inverse of the cumulative density `ndtr`. First,
        let us compute a cumulative density value.

        >>> import numpy as np
        >>> from scipy.special import ndtri, ndtr
        >>> cdf_val = ndtr(2)
        >>> cdf_val
        0.9772498680518208

        Verify that `ndtri` yields the original value for `x` up to floating point
        errors.

        >>> ndtri(cdf_val)
        2.0000000000000004

        Plot the function. For that purpose, we provide a NumPy array as argument.

        >>> import matplotlib.pyplot as plt
        >>> x = np.linspace(0.01, 1, 200)
        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, ndtri(x))
        >>> ax.set_title("Standard normal percentile function")
        >>> plt.show()

    ndtri_exp = <ufunc 'ndtri_exp'>
        ndtri_exp(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        ndtri_exp(y, out=None)

        Inverse of `log_ndtr` vs x. Allows for greater precision than
        `ndtri` composed with `numpy.exp` for very small values of y and for
        y close to 0.

        Parameters
        ----------
        y : array_like of float
            Function argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Inverse of the log CDF of the standard normal distribution, evaluated
            at y.

        See Also
        --------
        log_ndtr : log of the standard normal cumulative distribution function
        ndtr : standard normal cumulative distribution function
        ndtri : standard normal percentile function

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        `ndtri_exp` agrees with the naive implementation when the latter does
        not suffer from underflow.

        >>> sc.ndtri_exp(-1)
        -0.33747496376420244
        >>> sc.ndtri(np.exp(-1))
        -0.33747496376420244

        For extreme values of y, the naive approach fails

        >>> sc.ndtri(np.exp(-800))
        -inf
        >>> sc.ndtri(np.exp(-1e-20))
        inf

        whereas `ndtri_exp` is still able to compute the result to high precision.

        >>> sc.ndtri_exp(-800)
        -39.88469483825668
        >>> sc.ndtri_exp(-1e-20)
        9.262340089798409

    nrdtrimn = <ufunc 'nrdtrimn'>
        nrdtrimn(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nrdtrimn(p, std, x, out=None)

        Calculate mean of normal distribution given other params.

        Parameters
        ----------
        p : array_like
            CDF values, in range (0, 1].
        std : array_like
            Standard deviation.
        x : array_like
            Quantiles, i.e. the upper limit of integration.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        mn : scalar or ndarray
            The mean of the normal distribution.

        See Also
        --------
        scipy.stats.norm : Normal distribution
        ndtr : Standard normal cumulative probability distribution
        ndtri : Inverse of standard normal CDF with respect to quantile
        nrdtrisd : Inverse of normal distribution CDF with respect to
                   standard deviation

        Examples
        --------
        `nrdtrimn` can be used to recover the mean of a normal distribution
        if we know the CDF value `p` for a given quantile `x` and the
        standard deviation `std`. First, we calculate
        the normal distribution CDF for an exemplary parameter set.

        >>> from scipy.stats import norm
        >>> mean = 3.
        >>> std = 2.
        >>> x = 6.
        >>> p = norm.cdf(x, loc=mean, scale=std)
        >>> p
        0.9331927987311419

        Verify that `nrdtrimn` returns the original value for `mean`.

        >>> from scipy.special import nrdtrimn
        >>> nrdtrimn(p, std, x)
        3.0000000000000004

    nrdtrisd = <ufunc 'nrdtrisd'>
        nrdtrisd(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        nrdtrisd(mn, p, x, out=None)

        Calculate standard deviation of normal distribution given other params.

        Parameters
        ----------
        mn : scalar or ndarray
            The mean of the normal distribution.
        p : array_like
            CDF values, in range (0, 1].
        x : array_like
            Quantiles, i.e. the upper limit of integration.

        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        std : scalar or ndarray
            Standard deviation.

        See Also
        --------
        scipy.stats.norm : Normal distribution
        ndtr : Standard normal cumulative probability distribution
        ndtri : Inverse of standard normal CDF with respect to quantile
        nrdtrimn : Inverse of normal distribution CDF with respect to
                   mean

        Examples
        --------
        `nrdtrisd` can be used to recover the standard deviation of a normal
        distribution if we know the CDF value `p` for a given quantile `x` and
        the mean `mn`. First, we calculate the normal distribution CDF for an
        exemplary parameter set.

        >>> from scipy.stats import norm
        >>> mean = 3.
        >>> std = 2.
        >>> x = 6.
        >>> p = norm.cdf(x, loc=mean, scale=std)
        >>> p
        0.9331927987311419

        Verify that `nrdtrisd` returns the original value for `std`.

        >>> from scipy.special import nrdtrisd
        >>> nrdtrisd(mean, p, x)
        2.0000000000000004

    obl_ang1 = <ufunc 'obl_ang1'>
        obl_ang1(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_ang1(m, n, c, x, out=None)

        Oblate spheroidal angular function of the first kind and its derivative

        Computes the oblate spheroidal angular function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_ang1_cv

    obl_ang1_cv = <ufunc 'obl_ang1_cv'>
        obl_ang1_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_ang1_cv(m, n, c, cv, x, out=None)

        Oblate spheroidal angular function obl_ang1 for precomputed characteristic value

        Computes the oblate spheroidal angular function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_ang1

    obl_cv = <ufunc 'obl_cv'>
        obl_cv(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_cv(m, n, c, out=None)

        Characteristic value of oblate spheroidal function

        Computes the characteristic value of oblate spheroidal wave
        functions of order `m`, `n` (n>=m) and spheroidal parameter `c`.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        cv : scalar or ndarray
            Characteristic value

    obl_rad1 = <ufunc 'obl_rad1'>
        obl_rad1(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_rad1(m, n, c, x, out=None)

        Oblate spheroidal radial function of the first kind and its derivative

        Computes the oblate spheroidal radial function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_rad1_cv

    obl_rad1_cv = <ufunc 'obl_rad1_cv'>
        obl_rad1_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_rad1_cv(m, n, c, cv, x, out=None)

        Oblate spheroidal radial function obl_rad1 for precomputed characteristic value

        Computes the oblate spheroidal radial function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_rad1

    obl_rad2 = <ufunc 'obl_rad2'>
        obl_rad2(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_rad2(m, n, c, x, out=None)

        Oblate spheroidal radial function of the second kind and its derivative.

        Computes the oblate spheroidal radial function of the second kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_rad2_cv

    obl_rad2_cv = <ufunc 'obl_rad2_cv'>
        obl_rad2_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        obl_rad2_cv(m, n, c, cv, x, out=None)

        Oblate spheroidal radial function obl_rad2 for precomputed characteristic value

        Computes the oblate spheroidal radial function of the second kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Mode parameter m (nonnegative)
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Parameter x (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

        See Also
        --------
        obl_rad2

    owens_t = <ufunc 'owens_t'>
        owens_t(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        owens_t(h, a, out=None)

        Owen's T Function.

        The function T(h, a) gives the probability of the event
        (X > h and 0 < Y < a * X) where X and Y are independent
        standard normal random variables.

        Parameters
        ----------
        h: array_like
            Input value.
        a: array_like
            Input value.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        t: scalar or ndarray
            Probability of the event (X > h and 0 < Y < a * X),
            where X and Y are independent standard normal random variables.

        References
        ----------
        .. [1] M. Patefield and D. Tandy, "Fast and accurate calculation of
               Owen's T Function", Statistical Software vol. 5, pp. 1-25, 2000.

        Examples
        --------
        >>> from scipy import special
        >>> a = 3.5
        >>> h = 0.78
        >>> special.owens_t(h, a)
        0.10877216734852274

    pbdv = <ufunc 'pbdv'>
        pbdv(x1, x2[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pbdv(v, x, out=None)

        Parabolic cylinder function D

        Returns (d, dp) the parabolic cylinder function Dv(x) in d and the
        derivative, Dv'(x) in dp.

        Parameters
        ----------
        v : array_like
            Real parameter
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        d : scalar or ndarray
            Value of the function
        dp : scalar or ndarray
            Value of the derivative vs x

    pbvv = <ufunc 'pbvv'>
        pbvv(x1, x2[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pbvv(v, x, out=None)

        Parabolic cylinder function V

        Returns the parabolic cylinder function Vv(x) in v and the
        derivative, Vv'(x) in vp.

        Parameters
        ----------
        v : array_like
            Real parameter
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        v : scalar or ndarray
            Value of the function
        vp : scalar or ndarray
            Value of the derivative vs x

    pbwa = <ufunc 'pbwa'>
        pbwa(x1, x2[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pbwa(a, x, out=None)

        Parabolic cylinder function W.

        The function is a particular solution to the differential equation

        .. math::

            y'' + \left(\frac{1}{4}x^2 - a\right)y = 0,

        for a full definition see section 12.14 in [1]_.

        Parameters
        ----------
        a : array_like
            Real parameter
        x : array_like
            Real argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        w : scalar or ndarray
            Value of the function
        wp : scalar or ndarray
            Value of the derivative in x

        Notes
        -----
        The function is a wrapper for a Fortran routine by Zhang and Jin
        [2]_. The implementation is accurate only for ``|a|, |x| < 5`` and
        returns NaN outside that range.

        References
        ----------
        .. [1] Digital Library of Mathematical Functions, 14.30.
               https://dlmf.nist.gov/14.30
        .. [2] Zhang, Shanjie and Jin, Jianming. "Computation of Special
               Functions", John Wiley and Sons, 1996.
               https://people.sc.fsu.edu/~jburkardt/f_src/special_functions/special_functions.html

    pdtr = <ufunc 'pdtr'>
        pdtr(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        pdtr(k, m, out=None)

        Poisson cumulative distribution function.

        Defined as the probability that a Poisson-distributed random
        variable with event rate :math:`m` is less than or equal to
        :math:`k`. More concretely, this works out to be [1]_

        .. math::

           \exp(-m) \sum_{j = 0}^{\lfloor{k}\rfloor} \frac{m^j}{j!}.

        Parameters
        ----------
        k : array_like
            Number of occurrences (nonnegative, real)
        m : array_like
            Shape parameter (nonnegative, real)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the Poisson cumulative distribution function

        See Also
        --------
        pdtrc : Poisson survival function
        pdtrik : inverse of `pdtr` with respect to `k`
        pdtri : inverse of `pdtr` with respect to `m`

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Poisson_distribution

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is a cumulative distribution function, so it converges to 1
        monotonically as `k` goes to infinity.

        >>> sc.pdtr([1, 10, 100, np.inf], 1)
        array([0.73575888, 0.99999999, 1.        , 1.        ])

        It is discontinuous at integers and constant between integers.

        >>> sc.pdtr([1, 1.5, 1.9, 2], 1)
        array([0.73575888, 0.73575888, 0.73575888, 0.9196986 ])

    pdtrc = <ufunc 'pdtrc'>
        pdtrc(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        pdtrc(k, m, out=None)

        Poisson survival function

        Returns the sum of the terms from k+1 to infinity of the Poisson
        distribution: sum(exp(-m) * m**j / j!, j=k+1..inf) = gammainc(
        k+1, m). Arguments must both be non-negative doubles.

        Parameters
        ----------
        k : array_like
            Number of occurrences (nonnegative, real)
        m : array_like
            Shape parameter (nonnegative, real)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the Poisson survival function

        See Also
        --------
        pdtr : Poisson cumulative distribution function
        pdtrik : inverse of `pdtr` with respect to `k`
        pdtri : inverse of `pdtr` with respect to `m`

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is a survival function, so it decreases to 0
        monotonically as `k` goes to infinity.

        >>> k = np.array([1, 10, 100, np.inf])
        >>> sc.pdtrc(k, 1)
        array([2.64241118e-001, 1.00477664e-008, 3.94147589e-161, 0.00000000e+000])

        It can be expressed in terms of the lower incomplete gamma
        function `gammainc`.

        >>> sc.gammainc(k + 1, 1)
        array([2.64241118e-001, 1.00477664e-008, 3.94147589e-161, 0.00000000e+000])

    pdtri = <ufunc 'pdtri'>
        pdtri(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        pdtri(k, y, out=None)

        Inverse to `pdtr` vs m

        Returns the Poisson variable `m` such that the sum from 0 to `k` of
        the Poisson density is equal to the given probability `y`:
        calculated by ``gammaincinv(k + 1, y)``. `k` must be a nonnegative
        integer and `y` between 0 and 1.

        Parameters
        ----------
        k : array_like
            Number of occurrences (nonnegative, real)
        y : array_like
            Probability
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of the shape parameter `m` such that ``pdtr(k, m) = p``

        See Also
        --------
        pdtr : Poisson cumulative distribution function
        pdtrc : Poisson survival function
        pdtrik : inverse of `pdtr` with respect to `k`

        Examples
        --------
        >>> import scipy.special as sc

        Compute the CDF for several values of `m`:

        >>> m = [0.5, 1, 1.5]
        >>> p = sc.pdtr(1, m)
        >>> p
        array([0.90979599, 0.73575888, 0.5578254 ])

        Compute the inverse. We recover the values of `m`, as expected:

        >>> sc.pdtri(1, p)
        array([0.5, 1. , 1.5])

    pdtrik = <ufunc 'pdtrik'>
        pdtrik(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        pdtrik(p, m, out=None)

        Inverse to `pdtr` vs `k`.

        Parameters
        ----------
        p : array_like
            Probability
        m : array_like
            Shape parameter (nonnegative, real)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The number of occurrences `k` such that ``pdtr(k, m) = p``

        See Also
        --------
        pdtr : Poisson cumulative distribution function
        pdtrc : Poisson survival function
        pdtri : inverse of `pdtr` with respect to `m`

        Examples
        --------
        >>> import scipy.special as sc

        Compute the CDF for several values of `k`:

        >>> k = [1, 2, 3]
        >>> p = sc.pdtr(k, 2)
        >>> p
        array([0.40600585, 0.67667642, 0.85712346])

        Compute the inverse. We recover the values of `k`, as expected:

        >>> sc.pdtrik(p, 2)
        array([1., 2., 3.])

    poch = <ufunc 'poch'>
        poch(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        poch(z, m, out=None)

        Pochhammer symbol.

        The Pochhammer symbol (rising factorial) is defined as

        .. math::

            (z)_m = \frac{\Gamma(z + m)}{\Gamma(z)}

        For positive integer `m` it reads

        .. math::

            (z)_m = z (z + 1) ... (z + m - 1)

        See [dlmf]_ for more details.

        Parameters
        ----------
        z, m : array_like
            Real-valued arguments.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value of the function.

        References
        ----------
        .. [dlmf] Nist, Digital Library of Mathematical Functions
            https://dlmf.nist.gov/5.2#iii

        Examples
        --------
        >>> import scipy.special as sc

        It is 1 when m is 0.

        >>> sc.poch([1, 2, 3, 4], 0)
        array([1., 1., 1., 1.])

        For z equal to 1 it reduces to the factorial function.

        >>> sc.poch(1, 5)
        120.0
        >>> 1 * 2 * 3 * 4 * 5
        120

        It can be expressed in terms of the gamma function.

        >>> z, m = 3.7, 2.1
        >>> sc.poch(z, m)
        20.529581933776953
        >>> sc.gamma(z + m) / sc.gamma(z)
        20.52958193377696

    powm1 = <ufunc 'powm1'>
        powm1(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        powm1(x, y, out=None)

        Computes ``x**y - 1``.

        This function is useful when `y` is near 0, or when `x` is near 1.

        The function is implemented for real types only (unlike ``numpy.power``,
        which accepts complex inputs).

        Parameters
        ----------
        x : array_like
            The base. Must be a real type (i.e. integer or float, not complex).
        y : array_like
            The exponent. Must be a real type (i.e. integer or float, not complex).

        Returns
        -------
        array_like
            Result of the calculation

        Notes
        -----
        .. versionadded:: 1.10.0

        The underlying code is implemented for single precision and double
        precision floats only.  Unlike `numpy.power`, integer inputs to
        `powm1` are converted to floating point, and complex inputs are
        not accepted.

        Note the following edge cases:

        * ``powm1(x, 0)`` returns 0 for any ``x``, including 0, ``inf``
          and ``nan``.
        * ``powm1(1, y)`` returns 0 for any ``y``, including ``nan``
          and ``inf``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import powm1

        >>> x = np.array([1.2, 10.0, 0.9999999975])
        >>> y = np.array([1e-9, 1e-11, 0.1875])
        >>> powm1(x, y)
        array([ 1.82321557e-10,  2.30258509e-11, -4.68749998e-10])

        It can be verified that the relative errors in those results
        are less than 2.5e-16.

        Compare that to the result of ``x**y - 1``, where the
        relative errors are all larger than 8e-8:

        >>> x**y - 1
        array([ 1.82321491e-10,  2.30258035e-11, -4.68750039e-10])

    pro_ang1 = <ufunc 'pro_ang1'>
        pro_ang1(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_ang1(m, n, c, x, out=None)

        Prolate spheroidal angular function of the first kind and its derivative

        Computes the prolate spheroidal angular function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pro_ang1_cv = <ufunc 'pro_ang1_cv'>
        pro_ang1_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_ang1_cv(m, n, c, cv, x, out=None)

        Prolate spheroidal angular function pro_ang1 for precomputed characteristic value

        Computes the prolate spheroidal angular function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pro_cv = <ufunc 'obl_cv'>
        obl_cv(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_cv(m, n, c, out=None)

        Characteristic value of prolate spheroidal function

        Computes the characteristic value of prolate spheroidal wave
        functions of order `m`, `n` (n>=m) and spheroidal parameter `c`.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        cv : scalar or ndarray
            Characteristic value

    pro_rad1 = <ufunc 'pro_rad1'>
        pro_rad1(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_rad1(m, n, c, x, out=None)

        Prolate spheroidal radial function of the first kind and its derivative

        Computes the prolate spheroidal radial function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pro_rad1_cv = <ufunc 'pro_rad1_cv'>
        pro_rad1_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_rad1_cv(m, n, c, cv, x, out=None)

        Prolate spheroidal radial function pro_rad1 for precomputed characteristic value

        Computes the prolate spheroidal radial function of the first kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pro_rad2 = <ufunc 'pro_rad2'>
        pro_rad2(x1, x2, x3, x4[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_rad2(m, n, c, x, out=None)

        Prolate spheroidal radial function of the second kind and its derivative

        Computes the prolate spheroidal radial function of the second kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pro_rad2_cv = <ufunc 'pro_rad2_cv'>
        pro_rad2_cv(x1, x2, x3, x4, x5[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        pro_rad2_cv(m, n, c, cv, x, out=None)

        Prolate spheroidal radial function pro_rad2 for precomputed characteristic value

        Computes the prolate spheroidal radial function of the second kind
        and its derivative (with respect to `x`) for mode parameters m>=0
        and n>=m, spheroidal parameter `c` and ``|x| < 1.0``. Requires
        pre-computed characteristic value.

        Parameters
        ----------
        m : array_like
            Nonnegative mode parameter m
        n : array_like
            Mode parameter n (>= m)
        c : array_like
            Spheroidal parameter
        cv : array_like
            Characteristic value
        x : array_like
            Real parameter (``|x| < 1.0``)
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Value of the function
        sp : scalar or ndarray
            Value of the derivative vs x

    pseudo_huber = <ufunc 'pseudo_huber'>
        pseudo_huber(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        pseudo_huber(delta, r, out=None)

        Pseudo-Huber loss function.

        .. math:: \mathrm{pseudo\_huber}(\delta, r) =
                  \delta^2 \left( \sqrt{ 1 + \left( \frac{r}{\delta} \right)^2 } - 1 \right)

        Parameters
        ----------
        delta : array_like
            Input array, indicating the soft quadratic vs. linear loss changepoint.
        r : array_like
            Input array, possibly representing residuals.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        res : scalar or ndarray
            The computed Pseudo-Huber loss function values.

        See Also
        --------
        huber: Similar function which this function approximates

        Notes
        -----
        Like `huber`, `pseudo_huber` often serves as a robust loss function
        in statistics or machine learning to reduce the influence of outliers.
        Unlike `huber`, `pseudo_huber` is smooth.

        Typically, `r` represents residuals, the difference
        between a model prediction and data. Then, for :math:`|r|\leq\delta`,
        `pseudo_huber` resembles the squared error and for :math:`|r|>\delta` the
        absolute error. This way, the Pseudo-Huber loss often achieves
        a fast convergence in model fitting for small residuals like the squared
        error loss function and still reduces the influence of outliers
        (:math:`|r|>\delta`) like the absolute error loss. As :math:`\delta` is
        the cutoff between squared and absolute error regimes, it has
        to be tuned carefully for each problem. `pseudo_huber` is also
        convex, making it suitable for gradient based optimization. [1]_ [2]_

        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Hartley, Zisserman, "Multiple View Geometry in Computer Vision".
               2003. Cambridge University Press. p. 619
        .. [2] Charbonnier et al. "Deterministic edge-preserving regularization
               in computed imaging". 1997. IEEE Trans. Image Processing.
               6 (2): 298 - 311.

        Examples
        --------
        Import all necessary modules.

        >>> import numpy as np
        >>> from scipy.special import pseudo_huber, huber
        >>> import matplotlib.pyplot as plt

        Calculate the function for ``delta=1`` at ``r=2``.

        >>> pseudo_huber(1., 2.)
        1.2360679774997898

        Calculate the function at ``r=2`` for different `delta` by providing
        a list or NumPy array for `delta`.

        >>> pseudo_huber([1., 2., 4.], 3.)
        array([2.16227766, 3.21110255, 4.        ])

        Calculate the function for ``delta=1`` at several points by providing
        a list or NumPy array for `r`.

        >>> pseudo_huber(2., np.array([1., 1.5, 3., 4.]))
        array([0.47213595, 1.        , 3.21110255, 4.94427191])

        The function can be calculated for different `delta` and `r` by
        providing arrays for both with compatible shapes for broadcasting.

        >>> r = np.array([1., 2.5, 8., 10.])
        >>> deltas = np.array([[1.], [5.], [9.]])
        >>> print(r.shape, deltas.shape)
        (4,) (3, 1)

        >>> pseudo_huber(deltas, r)
        array([[ 0.41421356,  1.6925824 ,  7.06225775,  9.04987562],
               [ 0.49509757,  2.95084972, 22.16990566, 30.90169944],
               [ 0.49846624,  3.06693762, 27.37435121, 40.08261642]])

        Plot the function for different `delta`.

        >>> x = np.linspace(-4, 4, 500)
        >>> deltas = [1, 2, 3]
        >>> linestyles = ["dashed", "dotted", "dashdot"]
        >>> fig, ax = plt.subplots()
        >>> combined_plot_parameters = list(zip(deltas, linestyles))
        >>> for delta, style in combined_plot_parameters:
        ...     ax.plot(x, pseudo_huber(delta, x), label=rf"$\delta={delta}$",
        ...             ls=style)
        >>> ax.legend(loc="upper center")
        >>> ax.set_xlabel("$x$")
        >>> ax.set_title(r"Pseudo-Huber loss function $h_{\delta}(x)$")
        >>> ax.set_xlim(-4, 4)
        >>> ax.set_ylim(0, 8)
        >>> plt.show()

        Finally, illustrate the difference between `huber` and `pseudo_huber` by
        plotting them and their gradients with respect to `r`. The plot shows
        that `pseudo_huber` is continuously differentiable while `huber` is not
        at the points :math:`\pm\delta`.

        >>> def huber_grad(delta, x):
        ...     grad = np.copy(x)
        ...     linear_area = np.argwhere(np.abs(x) > delta)
        ...     grad[linear_area]=delta*np.sign(x[linear_area])
        ...     return grad
        >>> def pseudo_huber_grad(delta, x):
        ...     return x* (1+(x/delta)**2)**(-0.5)
        >>> x=np.linspace(-3, 3, 500)
        >>> delta = 1.
        >>> fig, ax = plt.subplots(figsize=(7, 7))
        >>> ax.plot(x, huber(delta, x), label="Huber", ls="dashed")
        >>> ax.plot(x, huber_grad(delta, x), label="Huber Gradient", ls="dashdot")
        >>> ax.plot(x, pseudo_huber(delta, x), label="Pseudo-Huber", ls="dotted")
        >>> ax.plot(x, pseudo_huber_grad(delta, x), label="Pseudo-Huber Gradient",
        ...         ls="solid")
        >>> ax.legend(loc="upper center")
        >>> plt.show()

    psi = <ufunc 'psi'>
        psi(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        psi(z, out=None)

        The digamma function.

        The logarithmic derivative of the gamma function evaluated at ``z``.

        Parameters
        ----------
        z : array_like
            Real or complex argument.
        out : ndarray, optional
            Array for the computed values of ``psi``.

        Returns
        -------
        digamma : scalar or ndarray
            Computed values of ``psi``.

        Notes
        -----
        For large values not close to the negative real axis, ``psi`` is
        computed using the asymptotic series (5.11.2) from [1]_. For small
        arguments not close to the negative real axis, the recurrence
        relation (5.5.2) from [1]_ is used until the argument is large
        enough to use the asymptotic series. For values close to the
        negative real axis, the reflection formula (5.5.4) from [1]_ is
        used first. Note that ``psi`` has a family of zeros on the
        negative real axis which occur between the poles at nonpositive
        integers. Around the zeros the reflection formula suffers from
        cancellation and the implementation loses precision. The sole
        positive zero and the first negative zero, however, are handled
        separately by precomputing series expansions using [2]_, so the
        function should maintain full accuracy around the origin.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/5
        .. [2] Fredrik Johansson and others.
               "mpmath: a Python library for arbitrary-precision floating-point arithmetic"
               (Version 0.19) http://mpmath.org/

        Examples
        --------
        >>> from scipy.special import psi
        >>> z = 3 + 4j
        >>> psi(z)
        (1.55035981733341+1.0105022091860445j)

        Verify psi(z) = psi(z + 1) - 1/z:

        >>> psi(z + 1) - 1/z
        (1.55035981733341+1.0105022091860445j)

    radian = <ufunc 'radian'>
        radian(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        radian(d, m, s, out=None)

        Convert from degrees to radians.

        Returns the angle given in (d)egrees, (m)inutes, and (s)econds in
        radians.

        Parameters
        ----------
        d : array_like
            Degrees, can be real-valued.
        m : array_like
            Minutes, can be real-valued.
        s : array_like
            Seconds, can be real-valued.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Values of the inputs in radians.

        Examples
        --------
        >>> import scipy.special as sc

        There are many ways to specify an angle.

        >>> sc.radian(90, 0, 0)
        1.5707963267948966
        >>> sc.radian(0, 60 * 90, 0)
        1.5707963267948966
        >>> sc.radian(0, 0, 60**2 * 90)
        1.5707963267948966

        The inputs can be real-valued.

        >>> sc.radian(1.5, 0, 0)
        0.02617993877991494
        >>> sc.radian(1, 30, 0)
        0.02617993877991494

    rel_entr = <ufunc 'rel_entr'>
        rel_entr(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        rel_entr(x, y, out=None)

        Elementwise function for computing relative entropy.

        .. math::

            \mathrm{rel\_entr}(x, y) =
                \begin{cases}
                    x \log(x / y) & x > 0, y > 0 \\
                    0 & x = 0, y \ge 0 \\
                    \infty & \text{otherwise}
                \end{cases}

        Parameters
        ----------
        x, y : array_like
            Input arrays
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Relative entropy of the inputs

        See Also
        --------
        entr, kl_div, scipy.stats.entropy

        Notes
        -----
        .. versionadded:: 0.15.0

        This function is jointly convex in x and y.

        The origin of this function is in convex programming; see
        [1]_. Given two discrete probability distributions :math:`p_1,
        \ldots, p_n` and :math:`q_1, \ldots, q_n`, the definition of relative
        entropy in the context of *information theory* is

        .. math::

            \sum_{i = 1}^n \mathrm{rel\_entr}(p_i, q_i).

        To compute the latter quantity, use `scipy.stats.entropy`.

        See [2]_ for details.

        References
        ----------
        .. [1] Boyd, Stephen and Lieven Vandenberghe. *Convex optimization*.
               Cambridge University Press, 2004.
               :doi:`https://doi.org/10.1017/CBO9780511804441`
        .. [2] Kullback-Leibler divergence,
               https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence

    rgamma = <ufunc 'rgamma'>
        rgamma(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        rgamma(z, out=None)

        Reciprocal of the gamma function.

        Defined as :math:`1 / \Gamma(z)`, where :math:`\Gamma` is the
        gamma function. For more on the gamma function see `gamma`.

        Parameters
        ----------
        z : array_like
            Real or complex valued input
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Function results

        See Also
        --------
        gamma, gammaln, loggamma

        Notes
        -----
        The gamma function has no zeros and has simple poles at
        nonpositive integers, so `rgamma` is an entire function with zeros
        at the nonpositive integers. See the discussion in [dlmf]_ for
        more details.

        References
        ----------
        .. [dlmf] Nist, Digital Library of Mathematical functions,
            https://dlmf.nist.gov/5.2#i

        Examples
        --------
        >>> import scipy.special as sc

        It is the reciprocal of the gamma function.

        >>> sc.rgamma([1, 2, 3, 4])
        array([1.        , 1.        , 0.5       , 0.16666667])
        >>> 1 / sc.gamma([1, 2, 3, 4])
        array([1.        , 1.        , 0.5       , 0.16666667])

        It is zero at nonpositive integers.

        >>> sc.rgamma([0, -1, -2, -3])
        array([0., 0., 0., 0.])

        It rapidly underflows to zero along the positive real axis.

        >>> sc.rgamma([10, 100, 179])
        array([2.75573192e-006, 1.07151029e-156, 0.00000000e+000])

    round = <ufunc 'round'>
        round(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        round(x, out=None)

        Round to the nearest integer.

        Returns the nearest integer to `x`.  If `x` ends in 0.5 exactly,
        the nearest even integer is chosen.

        Parameters
        ----------
        x : array_like
            Real valued input.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            The nearest integers to the elements of `x`. The result is of
            floating type, not integer type.

        Examples
        --------
        >>> import scipy.special as sc

        It rounds to even.

        >>> sc.round([0.5, 1.5])
        array([0., 2.])

    shichi = <ufunc 'shichi'>
        shichi(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        shichi(x, out=None)

        Hyperbolic sine and cosine integrals.

        The hyperbolic sine integral is

        .. math::

          \int_0^x \frac{\sinh{t}}{t}dt

        and the hyperbolic cosine integral is

        .. math::

          \gamma + \log(x) + \int_0^x \frac{\cosh{t} - 1}{t} dt

        where :math:`\gamma` is Euler's constant and :math:`\log` is the
        principal branch of the logarithm [1]_.

        Parameters
        ----------
        x : array_like
            Real or complex points at which to compute the hyperbolic sine
            and cosine integrals.
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        si : scalar or ndarray
            Hyperbolic sine integral at ``x``
        ci : scalar or ndarray
            Hyperbolic cosine integral at ``x``

        See Also
        --------
        sici : Sine and cosine integrals.
        exp1 : Exponential integral E1.
        expi : Exponential integral Ei.

        Notes
        -----
        For real arguments with ``x < 0``, ``chi`` is the real part of the
        hyperbolic cosine integral. For such points ``chi(x)`` and ``chi(x
        + 0j)`` differ by a factor of ``1j*pi``.

        For real arguments the function is computed by calling Cephes'
        [2]_ *shichi* routine. For complex arguments the algorithm is based
        on Mpmath's [3]_ *shi* and *chi* routines.

        References
        ----------
        .. [1] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
               (See Section 5.2.)
        .. [2] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [3] Fredrik Johansson and others.
               "mpmath: a Python library for arbitrary-precision floating-point
               arithmetic" (Version 0.19) http://mpmath.org/

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import shichi, sici

        `shichi` accepts real or complex input:

        >>> shichi(0.5)
        (0.5069967498196671, -0.05277684495649357)
        >>> shichi(0.5 + 2.5j)
        ((0.11772029666668238+1.831091777729851j),
         (0.29912435887648825+1.7395351121166562j))

        The hyperbolic sine and cosine integrals Shi(z) and Chi(z) are
        related to the sine and cosine integrals Si(z) and Ci(z) by

        * Shi(z) = -i*Si(i*z)
        * Chi(z) = Ci(-i*z) + i*pi/2

        >>> z = 0.25 + 5j
        >>> shi, chi = shichi(z)
        >>> shi, -1j*sici(1j*z)[0]            # Should be the same.
        ((-0.04834719325101729+1.5469354086921228j),
         (-0.04834719325101729+1.5469354086921228j))
        >>> chi, sici(-1j*z)[1] + 1j*np.pi/2  # Should be the same.
        ((-0.19568708973868087+1.556276312103824j),
         (-0.19568708973868087+1.556276312103824j))

        Plot the functions evaluated on the real axis:

        >>> xp = np.geomspace(1e-8, 4.0, 250)
        >>> x = np.concatenate((-xp[::-1], xp))
        >>> shi, chi = shichi(x)

        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, shi, label='Shi(x)')
        >>> ax.plot(x, chi, '--', label='Chi(x)')
        >>> ax.set_xlabel('x')
        >>> ax.set_title('Hyperbolic Sine and Cosine Integrals')
        >>> ax.legend(shadow=True, framealpha=1, loc='lower right')
        >>> ax.grid(True)
        >>> plt.show()

    sici = <ufunc 'sici'>
        sici(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        sici(x, out=None)

        Sine and cosine integrals.

        The sine integral is

        .. math::

          \int_0^x \frac{\sin{t}}{t}dt

        and the cosine integral is

        .. math::

          \gamma + \log(x) + \int_0^x \frac{\cos{t} - 1}{t}dt

        where :math:`\gamma` is Euler's constant and :math:`\log` is the
        principal branch of the logarithm [1]_.

        Parameters
        ----------
        x : array_like
            Real or complex points at which to compute the sine and cosine
            integrals.
        out : tuple of ndarray, optional
            Optional output arrays for the function results

        Returns
        -------
        si : scalar or ndarray
            Sine integral at ``x``
        ci : scalar or ndarray
            Cosine integral at ``x``

        See Also
        --------
        shichi : Hyperbolic sine and cosine integrals.
        exp1 : Exponential integral E1.
        expi : Exponential integral Ei.

        Notes
        -----
        For real arguments with ``x < 0``, ``ci`` is the real part of the
        cosine integral. For such points ``ci(x)`` and ``ci(x + 0j)``
        differ by a factor of ``1j*pi``.

        For real arguments the function is computed by calling Cephes'
        [2]_ *sici* routine. For complex arguments the algorithm is based
        on Mpmath's [3]_ *si* and *ci* routines.

        References
        ----------
        .. [1] Milton Abramowitz and Irene A. Stegun, eds.
               Handbook of Mathematical Functions with Formulas,
               Graphs, and Mathematical Tables. New York: Dover, 1972.
               (See Section 5.2.)
        .. [2] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/
        .. [3] Fredrik Johansson and others.
               "mpmath: a Python library for arbitrary-precision floating-point
               arithmetic" (Version 0.19) http://mpmath.org/

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import sici, exp1

        `sici` accepts real or complex input:

        >>> sici(2.5)
        (1.7785201734438267, 0.2858711963653835)
        >>> sici(2.5 + 3j)
        ((4.505735874563953+0.06863305018999577j),
        (0.0793644206906966-2.935510262937543j))

        For z in the right half plane, the sine and cosine integrals are
        related to the exponential integral E1 (implemented in SciPy as
        `scipy.special.exp1`) by

        * Si(z) = (E1(i*z) - E1(-i*z))/2i + pi/2
        * Ci(z) = -(E1(i*z) + E1(-i*z))/2

        See [1]_ (equations 5.2.21 and 5.2.23).

        We can verify these relations:

        >>> z = 2 - 3j
        >>> sici(z)
        ((4.54751388956229-1.3991965806460565j),
        (1.408292501520851+2.9836177420296055j))

        >>> (exp1(1j*z) - exp1(-1j*z))/2j + np.pi/2  # Same as sine integral
        (4.54751388956229-1.3991965806460565j)

        >>> -(exp1(1j*z) + exp1(-1j*z))/2            # Same as cosine integral
        (1.408292501520851+2.9836177420296055j)

        Plot the functions evaluated on the real axis; the dotted horizontal
        lines are at pi/2 and -pi/2:

        >>> x = np.linspace(-16, 16, 150)
        >>> si, ci = sici(x)

        >>> fig, ax = plt.subplots()
        >>> ax.plot(x, si, label='Si(x)')
        >>> ax.plot(x, ci, '--', label='Ci(x)')
        >>> ax.legend(shadow=True, framealpha=1, loc='upper left')
        >>> ax.set_xlabel('x')
        >>> ax.set_title('Sine and Cosine Integrals')
        >>> ax.axhline(np.pi/2, linestyle=':', alpha=0.5, color='k')
        >>> ax.axhline(-np.pi/2, linestyle=':', alpha=0.5, color='k')
        >>> ax.grid(True)
        >>> plt.show()

    sindg = <ufunc 'sindg'>
        sindg(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        sindg(x, out=None)

        Sine of the angle `x` given in degrees.

        Parameters
        ----------
        x : array_like
            Angle, given in degrees.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Sine at the input.

        See Also
        --------
        cosdg, tandg, cotdg

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than using sine directly.

        >>> x = 180 * np.arange(3)
        >>> sc.sindg(x)
        array([ 0., -0.,  0.])
        >>> np.sin(x * np.pi / 180)
        array([ 0.0000000e+00,  1.2246468e-16, -2.4492936e-16])

    smirnov = <ufunc 'smirnov'>
        smirnov(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        smirnov(n, d, out=None)

        Kolmogorov-Smirnov complementary cumulative distribution function

        Returns the exact Kolmogorov-Smirnov complementary cumulative
        distribution function,(aka the Survival Function) of Dn+ (or Dn-)
        for a one-sided test of equality between an empirical and a
        theoretical distribution. It is equal to the probability that the
        maximum difference between a theoretical distribution and an empirical
        one based on `n` samples is greater than d.

        Parameters
        ----------
        n : int
          Number of samples
        d : float array_like
          Deviation between the Empirical CDF (ECDF) and the target CDF.
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value(s) of smirnov(n, d), Prob(Dn+ >= d) (Also Prob(Dn- >= d))

        See Also
        --------
        smirnovi : The Inverse Survival Function for the distribution
        scipy.stats.ksone : Provides the functionality as a continuous distribution
        kolmogorov, kolmogi : Functions for the two-sided distribution

        Notes
        -----
        `smirnov` is used by `stats.kstest` in the application of the
        Kolmogorov-Smirnov Goodness of Fit test. For historical reasons this
        function is exposed in `scpy.special`, but the recommended way to achieve
        the most accurate CDF/SF/PDF/PPF/ISF computations is to use the
        `stats.ksone` distribution.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import smirnov
        >>> from scipy.stats import norm

        Show the probability of a gap at least as big as 0, 0.5 and 1.0 for a
        sample of size 5.

        >>> smirnov(5, [0, 0.5, 1.0])
        array([ 1.   ,  0.056,  0.   ])

        Compare a sample of size 5 against N(0, 1), the standard normal
        distribution with mean 0 and standard deviation 1.

        `x` is the sample.

        >>> x = np.array([-1.392, -0.135, 0.114, 0.190, 1.82])

        >>> target = norm(0, 1)
        >>> cdfs = target.cdf(x)
        >>> cdfs
        array([0.0819612 , 0.44630594, 0.5453811 , 0.57534543, 0.9656205 ])

        Construct the empirical CDF and the K-S statistics (Dn+, Dn-, Dn).

        >>> n = len(x)
        >>> ecdfs = np.arange(n+1, dtype=float)/n
        >>> cols = np.column_stack([x, ecdfs[1:], cdfs, cdfs - ecdfs[:n],
        ...                        ecdfs[1:] - cdfs])
        >>> with np.printoptions(precision=3):
        ...    print(cols)
        [[-1.392  0.2    0.082  0.082  0.118]
         [-0.135  0.4    0.446  0.246 -0.046]
         [ 0.114  0.6    0.545  0.145  0.055]
         [ 0.19   0.8    0.575 -0.025  0.225]
         [ 1.82   1.     0.966  0.166  0.034]]
        >>> gaps = cols[:, -2:]
        >>> Dnpm = np.max(gaps, axis=0)
        >>> print(f'Dn-={Dnpm[0]:f}, Dn+={Dnpm[1]:f}')
        Dn-=0.246306, Dn+=0.224655
        >>> probs = smirnov(n, Dnpm)
        >>> print(f'For a sample of size {n} drawn from N(0, 1):',
        ...       f' Smirnov n={n}: Prob(Dn- >= {Dnpm[0]:f}) = {probs[0]:.4f}',
        ...       f' Smirnov n={n}: Prob(Dn+ >= {Dnpm[1]:f}) = {probs[1]:.4f}',
        ...       sep='\n')
        For a sample of size 5 drawn from N(0, 1):
         Smirnov n=5: Prob(Dn- >= 0.246306) = 0.4711
         Smirnov n=5: Prob(Dn+ >= 0.224655) = 0.5245

        Plot the empirical CDF and the standard normal CDF.

        >>> import matplotlib.pyplot as plt
        >>> plt.step(np.concatenate(([-2.5], x, [2.5])),
        ...          np.concatenate((ecdfs, [1])),
        ...          where='post', label='Empirical CDF')
        >>> xx = np.linspace(-2.5, 2.5, 100)
        >>> plt.plot(xx, target.cdf(xx), '--', label='CDF for N(0, 1)')

        Add vertical lines marking Dn+ and Dn-.

        >>> iminus, iplus = np.argmax(gaps, axis=0)
        >>> plt.vlines([x[iminus]], ecdfs[iminus], cdfs[iminus], color='r',
        ...            alpha=0.5, lw=4)
        >>> plt.vlines([x[iplus]], cdfs[iplus], ecdfs[iplus+1], color='m',
        ...            alpha=0.5, lw=4)

        >>> plt.grid(True)
        >>> plt.legend(framealpha=1, shadow=True)
        >>> plt.show()

    smirnovi = <ufunc 'smirnovi'>
        smirnovi(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        smirnovi(n, p, out=None)

        Inverse to `smirnov`

        Returns `d` such that ``smirnov(n, d) == p``, the critical value
        corresponding to `p`.

        Parameters
        ----------
        n : int
          Number of samples
        p : float array_like
            Probability
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            The value(s) of smirnovi(n, p), the critical values.

        See Also
        --------
        smirnov : The Survival Function (SF) for the distribution
        scipy.stats.ksone : Provides the functionality as a continuous distribution
        kolmogorov, kolmogi : Functions for the two-sided distribution
        scipy.stats.kstwobign : Two-sided Kolmogorov-Smirnov distribution, large n

        Notes
        -----
        `smirnov` is used by `stats.kstest` in the application of the
        Kolmogorov-Smirnov Goodness of Fit test. For historical reasons this
        function is exposed in `scpy.special`, but the recommended way to achieve
        the most accurate CDF/SF/PDF/PPF/ISF computations is to use the
        `stats.ksone` distribution.

        Examples
        --------
        >>> from scipy.special import smirnovi, smirnov

        >>> n = 24
        >>> deviations = [0.1, 0.2, 0.3]

        Use `smirnov` to compute the complementary CDF of the Smirnov
        distribution for the given number of samples and deviations.

        >>> p = smirnov(n, deviations)
        >>> p
        array([0.58105083, 0.12826832, 0.01032231])

        The inverse function ``smirnovi(n, p)`` returns ``deviations``.

        >>> smirnovi(n, p)
        array([0.1, 0.2, 0.3])

    spence = <ufunc 'spence'>
        spence(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        spence(z, out=None)

        Spence's function, also known as the dilogarithm.

        It is defined to be

        .. math::
          \int_1^z \frac{\log(t)}{1 - t}dt

        for complex :math:`z`, where the contour of integration is taken
        to avoid the branch cut of the logarithm. Spence's function is
        analytic everywhere except the negative real axis where it has a
        branch cut.

        Parameters
        ----------
        z : array_like
            Points at which to evaluate Spence's function
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        s : scalar or ndarray
            Computed values of Spence's function

        Notes
        -----
        There is a different convention which defines Spence's function by
        the integral

        .. math::
          -\int_0^z \frac{\log(1 - t)}{t}dt;

        this is our ``spence(1 - z)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import spence
        >>> import matplotlib.pyplot as plt

        The function is defined for complex inputs:

        >>> spence([1-1j, 1.5+2j, 3j, -10-5j])
        array([-0.20561676+0.91596559j, -0.86766909-1.39560134j,
               -0.59422064-2.49129918j, -1.14044398+6.80075924j])

        For complex inputs on the branch cut, which is the negative real axis,
        the function returns the limit for ``z`` with positive imaginary part.
        For example, in the following, note the sign change of the imaginary
        part of the output for ``z = -2`` and ``z = -2 - 1e-8j``:

        >>> spence([-2 + 1e-8j, -2, -2 - 1e-8j])
        array([2.32018041-3.45139229j, 2.32018042-3.4513923j ,
               2.32018041+3.45139229j])

        The function returns ``nan`` for real inputs on the branch cut:

        >>> spence(-1.5)
        nan

        Verify some particular values: ``spence(0) = pi**2/6``,
        ``spence(1) = 0`` and ``spence(2) = -pi**2/12``.

        >>> spence([0, 1, 2])
        array([ 1.64493407,  0.        , -0.82246703])
        >>> np.pi**2/6, -np.pi**2/12
        (1.6449340668482264, -0.8224670334241132)

        Verify the identity::

            spence(z) + spence(1 - z) = pi**2/6 - log(z)*log(1 - z)

        >>> z = 3 + 4j
        >>> spence(z) + spence(1 - z)
        (-2.6523186143876067+1.8853470951513935j)
        >>> np.pi**2/6 - np.log(z)*np.log(1 - z)
        (-2.652318614387606+1.885347095151394j)

        Plot the function for positive real input.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0, 6, 400)
        >>> ax.plot(x, spence(x))
        >>> ax.grid()
        >>> ax.set_xlabel('x')
        >>> ax.set_title('spence(x)')
        >>> plt.show()

    sph_harm = <ufunc 'sph_harm'>
        sph_harm(x1, x2, x3, x4, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        sph_harm(m, n, theta, phi, out=None)

        Compute spherical harmonics.

        The spherical harmonics are defined as

        .. math::

            Y^m_n(\theta,\phi) = \sqrt{\frac{2n+1}{4\pi} \frac{(n-m)!}{(n+m)!}}
              e^{i m \theta} P^m_n(\cos(\phi))

        where :math:`P_n^m` are the associated Legendre functions; see `lpmv`.

        Parameters
        ----------
        m : array_like
            Order of the harmonic (int); must have ``|m| <= n``.
        n : array_like
           Degree of the harmonic (int); must have ``n >= 0``. This is
           often denoted by ``l`` (lower case L) in descriptions of
           spherical harmonics.
        theta : array_like
           Azimuthal (longitudinal) coordinate; must be in ``[0, 2*pi]``.
        phi : array_like
           Polar (colatitudinal) coordinate; must be in ``[0, pi]``.
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        y_mn : complex scalar or ndarray
           The harmonic :math:`Y^m_n` sampled at ``theta`` and ``phi``.

        Notes
        -----
        There are different conventions for the meanings of the input
        arguments ``theta`` and ``phi``. In SciPy ``theta`` is the
        azimuthal angle and ``phi`` is the polar angle. It is common to
        see the opposite convention, that is, ``theta`` as the polar angle
        and ``phi`` as the azimuthal angle.

        Note that SciPy's spherical harmonics include the Condon-Shortley
        phase [2]_ because it is part of `lpmv`.

        With SciPy's conventions, the first several spherical harmonics
        are

        .. math::

            Y_0^0(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{1}{\pi}} \\
            Y_1^{-1}(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{3}{2\pi}}
                                        e^{-i\theta} \sin(\phi) \\
            Y_1^0(\theta, \phi) &= \frac{1}{2} \sqrt{\frac{3}{\pi}}
                                     \cos(\phi) \\
            Y_1^1(\theta, \phi) &= -\frac{1}{2} \sqrt{\frac{3}{2\pi}}
                                     e^{i\theta} \sin(\phi).

        References
        ----------
        .. [1] Digital Library of Mathematical Functions, 14.30.
               https://dlmf.nist.gov/14.30
        .. [2] https://en.wikipedia.org/wiki/Spherical_harmonics#Condon.E2.80.93Shortley_phase

    stdtr = <ufunc 'stdtr'>
        stdtr(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        stdtr(df, t, out=None)

        Student t distribution cumulative distribution function

        Returns the integral:

        .. math::
            \frac{\Gamma((df+1)/2)}{\sqrt{\pi df} \Gamma(df/2)}
            \int_{-\infty}^t (1+x^2/df)^{-(df+1)/2}\, dx

        Parameters
        ----------
        df : array_like
            Degrees of freedom
        t : array_like
            Upper bound of the integral
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Value of the Student t CDF at t

        See Also
        --------
        stdtridf : inverse of stdtr with respect to `df`
        stdtrit : inverse of stdtr with respect to `t`
        scipy.stats.t : student t distribution

        Notes
        -----
        The student t distribution is also available as `scipy.stats.t`.
        Calling `stdtr` directly can improve performance compared to the
        ``cdf`` method of `scipy.stats.t` (see last example below).

        Examples
        --------
        Calculate the function for ``df=3`` at ``t=1``.

        >>> import numpy as np
        >>> from scipy.special import stdtr
        >>> import matplotlib.pyplot as plt
        >>> stdtr(3, 1)
        0.8044988905221148

        Plot the function for three different degrees of freedom.

        >>> x = np.linspace(-10, 10, 1000)
        >>> fig, ax = plt.subplots()
        >>> parameters = [(1, "solid"), (3, "dashed"), (10, "dotted")]
        >>> for (df, linestyle) in parameters:
        ...     ax.plot(x, stdtr(df, x), ls=linestyle, label=f"$df={df}$")
        >>> ax.legend()
        >>> ax.set_title("Student t distribution cumulative distribution function")
        >>> plt.show()

        The function can be computed for several degrees of freedom at the same
        time by providing a NumPy array or list for `df`:

        >>> stdtr([1, 2, 3], 1)
        array([0.75      , 0.78867513, 0.80449889])

        It is possible to calculate the function at several points for several
        different degrees of freedom simultaneously by providing arrays for `df`
        and `t` with shapes compatible for broadcasting. Compute `stdtr` at
        4 points for 3 degrees of freedom resulting in an array of shape 3x4.

        >>> dfs = np.array([[1], [2], [3]])
        >>> t = np.array([2, 4, 6, 8])
        >>> dfs.shape, t.shape
        ((3, 1), (4,))

        >>> stdtr(dfs, t)
        array([[0.85241638, 0.92202087, 0.94743154, 0.96041658],
               [0.90824829, 0.97140452, 0.98666426, 0.99236596],
               [0.93033702, 0.98599577, 0.99536364, 0.99796171]])

        The t distribution is also available as `scipy.stats.t`. Calling `stdtr`
        directly can be much faster than calling the ``cdf`` method of
        `scipy.stats.t`. To get the same results, one must use the following
        parametrization: ``scipy.stats.t(df).cdf(x) = stdtr(df, x)``.

        >>> from scipy.stats import t
        >>> df, x = 3, 1
        >>> stdtr_result = stdtr(df, x)  # this can be faster than below
        >>> stats_result = t(df).cdf(x)
        >>> stats_result == stdtr_result  # test that results are equal
        True

    stdtridf = <ufunc 'stdtridf'>
        stdtridf(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        stdtridf(p, t, out=None)

        Inverse of `stdtr` vs df

        Returns the argument df such that stdtr(df, t) is equal to `p`.

        Parameters
        ----------
        p : array_like
            Probability
        t : array_like
            Upper bound of the integral
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        df : scalar or ndarray
            Value of `df` such that ``stdtr(df, t) == p``

        See Also
        --------
        stdtr : Student t CDF
        stdtrit : inverse of stdtr with respect to `t`
        scipy.stats.t : Student t distribution

        Examples
        --------
        Compute the student t cumulative distribution function for one
        parameter set.

        >>> from scipy.special import stdtr, stdtridf
        >>> df, x = 5, 2
        >>> cdf_value = stdtr(df, x)
        >>> cdf_value
        0.9490302605850709

        Verify that `stdtridf` recovers the original value for `df` given
        the CDF value and `x`.

        >>> stdtridf(cdf_value, x)
        5.0

    stdtrit = <ufunc 'stdtrit'>
        stdtrit(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        stdtrit(df, p, out=None)

        The `p`-th quantile of the student t distribution.

        This function is the inverse of the student t distribution cumulative
        distribution function (CDF), returning `t` such that `stdtr(df, t) = p`.

        Returns the argument `t` such that stdtr(df, t) is equal to `p`.

        Parameters
        ----------
        df : array_like
            Degrees of freedom
        p : array_like
            Probability
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        t : scalar or ndarray
            Value of `t` such that ``stdtr(df, t) == p``

        See Also
        --------
        stdtr : Student t CDF
        stdtridf : inverse of stdtr with respect to `df`
        scipy.stats.t : Student t distribution

        Notes
        -----
        The student t distribution is also available as `scipy.stats.t`. Calling
        `stdtrit` directly can improve performance compared to the ``ppf``
        method of `scipy.stats.t` (see last example below).

        Examples
        --------
        `stdtrit` represents the inverse of the student t distribution CDF which
        is available as `stdtr`. Here, we calculate the CDF for ``df`` at
        ``x=1``. `stdtrit` then returns ``1`` up to floating point errors
        given the same value for `df` and the computed CDF value.

        >>> import numpy as np
        >>> from scipy.special import stdtr, stdtrit
        >>> import matplotlib.pyplot as plt
        >>> df = 3
        >>> x = 1
        >>> cdf_value = stdtr(df, x)
        >>> stdtrit(df, cdf_value)
        0.9999999994418539

        Plot the function for three different degrees of freedom.

        >>> x = np.linspace(0, 1, 1000)
        >>> parameters = [(1, "solid"), (2, "dashed"), (5, "dotted")]
        >>> fig, ax = plt.subplots()
        >>> for (df, linestyle) in parameters:
        ...     ax.plot(x, stdtrit(df, x), ls=linestyle, label=f"$df={df}$")
        >>> ax.legend()
        >>> ax.set_ylim(-10, 10)
        >>> ax.set_title("Student t distribution quantile function")
        >>> plt.show()

        The function can be computed for several degrees of freedom at the same
        time by providing a NumPy array or list for `df`:

        >>> stdtrit([1, 2, 3], 0.7)
        array([0.72654253, 0.6172134 , 0.58438973])

        It is possible to calculate the function at several points for several
        different degrees of freedom simultaneously by providing arrays for `df`
        and `p` with shapes compatible for broadcasting. Compute `stdtrit` at
        4 points for 3 degrees of freedom resulting in an array of shape 3x4.

        >>> dfs = np.array([[1], [2], [3]])
        >>> p = np.array([0.2, 0.4, 0.7, 0.8])
        >>> dfs.shape, p.shape
        ((3, 1), (4,))

        >>> stdtrit(dfs, p)
        array([[-1.37638192, -0.3249197 ,  0.72654253,  1.37638192],
               [-1.06066017, -0.28867513,  0.6172134 ,  1.06066017],
               [-0.97847231, -0.27667066,  0.58438973,  0.97847231]])

        The t distribution is also available as `scipy.stats.t`. Calling `stdtrit`
        directly can be much faster than calling the ``ppf`` method of
        `scipy.stats.t`. To get the same results, one must use the following
        parametrization: ``scipy.stats.t(df).ppf(x) = stdtrit(df, x)``.

        >>> from scipy.stats import t
        >>> df, x = 3, 0.5
        >>> stdtrit_result = stdtrit(df, x)  # this can be faster than below
        >>> stats_result = t(df).ppf(x)
        >>> stats_result == stdtrit_result  # test that results are equal
        True

    struve = <ufunc 'struve'>
        struve(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        struve(v, x, out=None)

        Struve function.

        Return the value of the Struve function of order `v` at `x`.  The Struve
        function is defined as,

        .. math::
            H_v(x) = (z/2)^{v + 1} \sum_{n=0}^\infty
            \frac{(-1)^n (z/2)^{2n}}{\Gamma(n + \frac{3}{2}) \Gamma(n + v + \frac{3}{2})},

        where :math:`\Gamma` is the gamma function.

        Parameters
        ----------
        v : array_like
            Order of the Struve function (float).
        x : array_like
            Argument of the Struve function (float; must be positive unless `v` is
            an integer).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        H : scalar or ndarray
            Value of the Struve function of order `v` at `x`.

        See Also
        --------
        modstruve: Modified Struve function

        Notes
        -----
        Three methods discussed in [1]_ are used to evaluate the Struve function:

        - power series
        - expansion in Bessel functions (if :math:`|z| < |v| + 20`)
        - asymptotic large-z expansion (if :math:`z \geq 0.7v + 12`)

        Rounding errors are estimated based on the largest terms in the sums, and
        the result associated with the smallest error is returned.

        References
        ----------
        .. [1] NIST Digital Library of Mathematical Functions
               https://dlmf.nist.gov/11

        Examples
        --------
        Calculate the Struve function of order 1 at 2.

        >>> import numpy as np
        >>> from scipy.special import struve
        >>> import matplotlib.pyplot as plt
        >>> struve(1, 2.)
        0.6467637282835622

        Calculate the Struve function at 2 for orders 1, 2 and 3 by providing
        a list for the order parameter `v`.

        >>> struve([1, 2, 3], 2.)
        array([0.64676373, 0.28031806, 0.08363767])

        Calculate the Struve function of order 1 for several points by providing
        an array for `x`.

        >>> points = np.array([2., 5., 8.])
        >>> struve(1, points)
        array([0.64676373, 0.80781195, 0.48811605])

        Compute the Struve function for several orders at several points by
        providing arrays for `v` and `z`. The arrays have to be broadcastable
        to the correct shapes.

        >>> orders = np.array([[1], [2], [3]])
        >>> points.shape, orders.shape
        ((3,), (3, 1))

        >>> struve(orders, points)
        array([[0.64676373, 0.80781195, 0.48811605],
               [0.28031806, 1.56937455, 1.51769363],
               [0.08363767, 1.50872065, 2.98697513]])

        Plot the Struve functions of order 0 to 3 from -10 to 10.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-10., 10., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, struve(i, x), label=f'$H_{i!r}$')
        >>> ax.legend(ncol=2)
        >>> ax.set_xlim(-10, 10)
        >>> ax.set_title(r"Struve functions $H_{\nu}$")
        >>> plt.show()

    tandg = <ufunc 'tandg'>
        tandg(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        tandg(x, out=None)

        Tangent of angle `x` given in degrees.

        Parameters
        ----------
        x : array_like
            Angle, given in degrees.
        out : ndarray, optional
            Optional output array for the function results.

        Returns
        -------
        scalar or ndarray
            Tangent at the input.

        See Also
        --------
        sindg, cosdg, cotdg

        Examples
        --------
        >>> import numpy as np
        >>> import scipy.special as sc

        It is more accurate than using tangent directly.

        >>> x = 180 * np.arange(3)
        >>> sc.tandg(x)
        array([0., 0., 0.])
        >>> np.tan(x * np.pi / 180)
        array([ 0.0000000e+00, -1.2246468e-16, -2.4492936e-16])

    tklmbda = <ufunc 'tklmbda'>
        tklmbda(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        tklmbda(x, lmbda, out=None)

        Cumulative distribution function of the Tukey lambda distribution.

        Parameters
        ----------
        x, lmbda : array_like
            Parameters
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        cdf : scalar or ndarray
            Value of the Tukey lambda CDF

        See Also
        --------
        scipy.stats.tukeylambda : Tukey lambda distribution

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.special import tklmbda, expit

        Compute the cumulative distribution function (CDF) of the Tukey lambda
        distribution at several ``x`` values for `lmbda` = -1.5.

        >>> x = np.linspace(-2, 2, 9)
        >>> x
        array([-2. , -1.5, -1. , -0.5,  0. ,  0.5,  1. ,  1.5,  2. ])
        >>> tklmbda(x, -1.5)
        array([0.34688734, 0.3786554 , 0.41528805, 0.45629737, 0.5       ,
               0.54370263, 0.58471195, 0.6213446 , 0.65311266])

        When `lmbda` is 0, the function is the logistic sigmoid function,
        which is implemented in `scipy.special` as `expit`.

        >>> tklmbda(x, 0)
        array([0.11920292, 0.18242552, 0.26894142, 0.37754067, 0.5       ,
               0.62245933, 0.73105858, 0.81757448, 0.88079708])
        >>> expit(x)
        array([0.11920292, 0.18242552, 0.26894142, 0.37754067, 0.5       ,
               0.62245933, 0.73105858, 0.81757448, 0.88079708])

        When `lmbda` is 1, the Tukey lambda distribution is uniform on the
        interval [-1, 1], so the CDF increases linearly.

        >>> t = np.linspace(-1, 1, 9)
        >>> tklmbda(t, 1)
        array([0.   , 0.125, 0.25 , 0.375, 0.5  , 0.625, 0.75 , 0.875, 1.   ])

        In the following, we generate plots for several values of `lmbda`.

        The first figure shows graphs for `lmbda` <= 0.

        >>> styles = ['-', '-.', '--', ':']
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-12, 12, 500)
        >>> for k, lmbda in enumerate([-1.0, -0.5, 0.0]):
        ...     y = tklmbda(x, lmbda)
        ...     ax.plot(x, y, styles[k], label=rf'$\lambda$ = {lmbda:-4.1f}')

        >>> ax.set_title(r'tklmbda(x, $\lambda$)')
        >>> ax.set_label('x')
        >>> ax.legend(framealpha=1, shadow=True)
        >>> ax.grid(True)

        The second figure shows graphs for `lmbda` > 0.  The dots in the
        graphs show the bounds of the support of the distribution.

        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(-4.2, 4.2, 500)
        >>> lmbdas = [0.25, 0.5, 1.0, 1.5]
        >>> for k, lmbda in enumerate(lmbdas):
        ...     y = tklmbda(x, lmbda)
        ...     ax.plot(x, y, styles[k], label=fr'$\lambda$ = {lmbda}')

        >>> ax.set_prop_cycle(None)
        >>> for lmbda in lmbdas:
        ...     ax.plot([-1/lmbda, 1/lmbda], [0, 1], '.', ms=8)

        >>> ax.set_title(r'tklmbda(x, $\lambda$)')
        >>> ax.set_xlabel('x')
        >>> ax.legend(framealpha=1, shadow=True)
        >>> ax.grid(True)

        >>> plt.tight_layout()
        >>> plt.show()

        The CDF of the Tukey lambda distribution is also implemented as the
        ``cdf`` method of `scipy.stats.tukeylambda`.  In the following,
        ``tukeylambda.cdf(x, -0.5)`` and ``tklmbda(x, -0.5)`` compute the
        same values:

        >>> from scipy.stats import tukeylambda
        >>> x = np.linspace(-2, 2, 9)

        >>> tukeylambda.cdf(x, -0.5)
        array([0.21995157, 0.27093858, 0.33541677, 0.41328161, 0.5       ,
               0.58671839, 0.66458323, 0.72906142, 0.78004843])

        >>> tklmbda(x, -0.5)
        array([0.21995157, 0.27093858, 0.33541677, 0.41328161, 0.5       ,
               0.58671839, 0.66458323, 0.72906142, 0.78004843])

        The implementation in ``tukeylambda`` also provides location and scale
        parameters, and other methods such as ``pdf()`` (the probability
        density function) and ``ppf()`` (the inverse of the CDF), so for
        working with the Tukey lambda distribution, ``tukeylambda`` is more
        generally useful.  The primary advantage of ``tklmbda`` is that it is
        significantly faster than ``tukeylambda.cdf``.

    voigt_profile = <ufunc 'voigt_profile'>
        voigt_profile(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        voigt_profile(x, sigma, gamma, out=None)

        Voigt profile.

        The Voigt profile is a convolution of a 1-D Normal distribution with
        standard deviation ``sigma`` and a 1-D Cauchy distribution with half-width at
        half-maximum ``gamma``.

        If ``sigma = 0``, PDF of Cauchy distribution is returned.
        Conversely, if ``gamma = 0``, PDF of Normal distribution is returned.
        If ``sigma = gamma = 0``, the return value is ``Inf`` for ``x = 0``,
        and ``0`` for all other ``x``.

        Parameters
        ----------
        x : array_like
            Real argument
        sigma : array_like
            The standard deviation of the Normal distribution part
        gamma : array_like
            The half-width at half-maximum of the Cauchy distribution part
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        scalar or ndarray
            The Voigt profile at the given arguments

        See Also
        --------
        wofz : Faddeeva function

        Notes
        -----
        It can be expressed in terms of Faddeeva function

        .. math:: V(x; \sigma, \gamma) = \frac{Re[w(z)]}{\sigma\sqrt{2\pi}},
        .. math:: z = \frac{x + i\gamma}{\sqrt{2}\sigma}

        where :math:`w(z)` is the Faddeeva function.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Voigt_profile

        Examples
        --------
        Calculate the function at point 2 for ``sigma=1`` and ``gamma=1``.

        >>> from scipy.special import voigt_profile
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> voigt_profile(2, 1., 1.)
        0.09071519942627544

        Calculate the function at several points by providing a NumPy array
        for `x`.

        >>> values = np.array([-2., 0., 5])
        >>> voigt_profile(values, 1., 1.)
        array([0.0907152 , 0.20870928, 0.01388492])

        Plot the function for different parameter sets.

        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> x = np.linspace(-10, 10, 500)
        >>> parameters_list = [(1.5, 0., "solid"), (1.3, 0.5, "dashed"),
        ...                    (0., 1.8, "dotted"), (1., 1., "dashdot")]
        >>> for params in parameters_list:
        ...     sigma, gamma, linestyle = params
        ...     voigt = voigt_profile(x, sigma, gamma)
        ...     ax.plot(x, voigt, label=rf"$\sigma={sigma},\, \gamma={gamma}$",
        ...             ls=linestyle)
        >>> ax.legend()
        >>> plt.show()

        Verify visually that the Voigt profile indeed arises as the convolution
        of a normal and a Cauchy distribution.

        >>> from scipy.signal import convolve
        >>> x, dx = np.linspace(-10, 10, 500, retstep=True)
        >>> def gaussian(x, sigma):
        ...     return np.exp(-0.5 * x**2/sigma**2)/(sigma * np.sqrt(2*np.pi))
        >>> def cauchy(x, gamma):
        ...     return gamma/(np.pi * (np.square(x)+gamma**2))
        >>> sigma = 2
        >>> gamma = 1
        >>> gauss_profile = gaussian(x, sigma)
        >>> cauchy_profile = cauchy(x, gamma)
        >>> convolved = dx * convolve(cauchy_profile, gauss_profile, mode="same")
        >>> voigt = voigt_profile(x, sigma, gamma)
        >>> fig, ax = plt.subplots(figsize=(8, 8))
        >>> ax.plot(x, gauss_profile, label="Gauss: $G$", c='b')
        >>> ax.plot(x, cauchy_profile, label="Cauchy: $C$", c='y', ls="dashed")
        >>> xx = 0.5*(x[1:] + x[:-1])  # midpoints
        >>> ax.plot(xx, convolved[1:], label="Convolution: $G * C$", ls='dashdot',
        ...         c='k')
        >>> ax.plot(x, voigt, label="Voigt", ls='dotted', c='r')
        >>> ax.legend()
        >>> plt.show()

    wofz = <ufunc 'wofz'>
        wofz(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        wofz(z, out=None)

        Faddeeva function

        Returns the value of the Faddeeva function for complex argument::

            exp(-z**2) * erfc(-i*z)

        Parameters
        ----------
        z : array_like
            complex argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Value of the Faddeeva function

        See Also
        --------
        dawsn, erf, erfc, erfcx, erfi

        References
        ----------
        .. [1] Steven G. Johnson, Faddeeva W function implementation.
           http://ab-initio.mit.edu/Faddeeva

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import special
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(-3, 3)
        >>> z = special.wofz(x)

        >>> plt.plot(x, z.real, label='wofz(x).real')
        >>> plt.plot(x, z.imag, label='wofz(x).imag')
        >>> plt.xlabel('$x$')
        >>> plt.legend(framealpha=1, shadow=True)
        >>> plt.grid(alpha=0.25)
        >>> plt.show()

    wright_bessel = <ufunc 'wright_bessel'>
        wright_bessel(x1, x2, x3, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        wright_bessel(a, b, x, out=None)

        Wright's generalized Bessel function.

        Wright's generalized Bessel function is an entire function and defined as

        .. math:: \Phi(a, b; x) = \sum_{k=0}^\infty \frac{x^k}{k! \Gamma(a k + b)}

        See Also [1].

        Parameters
        ----------
        a : array_like of float
            a >= 0
        b : array_like of float
            b >= 0
        x : array_like of float
            x >= 0
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Value of the Wright's generalized Bessel function

        Notes
        -----
        Due to the complexity of the function with its three parameters, only
        non-negative arguments are implemented.

        .. versionadded:: 1.7.0

        References
        ----------
        .. [1] Digital Library of Mathematical Functions, 10.46.
               https://dlmf.nist.gov/10.46.E1

        Examples
        --------
        >>> from scipy.special import wright_bessel
        >>> a, b, x = 1.5, 1.1, 2.5
        >>> wright_bessel(a, b-1, x)
        4.5314465939443025

        Now, let us verify the relation

        .. math:: \Phi(a, b-1; x) = a x \Phi(a, b+a; x) + (b-1) \Phi(a, b; x)

        >>> a * x * wright_bessel(a, b+a, x) + (b-1) * wright_bessel(a, b, x)
        4.5314465939443025

    wrightomega = <ufunc 'wrightomega'>
        wrightomega(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        wrightomega(z, out=None)

        Wright Omega function.

        Defined as the solution to

        .. math::

            \omega + \log(\omega) = z

        where :math:`\log` is the principal branch of the complex logarithm.

        Parameters
        ----------
        z : array_like
            Points at which to evaluate the Wright Omega function
        out : ndarray, optional
            Optional output array for the function values

        Returns
        -------
        omega : scalar or ndarray
            Values of the Wright Omega function

        See Also
        --------
        lambertw : The Lambert W function

        Notes
        -----
        .. versionadded:: 0.19.0

        The function can also be defined as

        .. math::

            \omega(z) = W_{K(z)}(e^z)

        where :math:`K(z) = \lceil (\Im(z) - \pi)/(2\pi) \rceil` is the
        unwinding number and :math:`W` is the Lambert W function.

        The implementation here is taken from [1]_.

        References
        ----------
        .. [1] Lawrence, Corless, and Jeffrey, "Algorithm 917: Complex
               Double-Precision Evaluation of the Wright :math:`\omega`
               Function." ACM Transactions on Mathematical Software,
               2012. :doi:`10.1145/2168773.2168779`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import wrightomega, lambertw

        >>> wrightomega([-2, -1, 0, 1, 2])
        array([0.12002824, 0.27846454, 0.56714329, 1.        , 1.5571456 ])

        Complex input:

        >>> wrightomega(3 + 5j)
        (1.5804428632097158+3.8213626783287937j)

        Verify that ``wrightomega(z)`` satisfies ``w + log(w) = z``:

        >>> w = -5 + 4j
        >>> wrightomega(w + np.log(w))
        (-5+4j)

        Verify the connection to ``lambertw``:

        >>> z = 0.5 + 3j
        >>> wrightomega(z)
        (0.0966015889280649+1.4937828458191993j)
        >>> lambertw(np.exp(z))
        (0.09660158892806493+1.4937828458191993j)

        >>> z = 0.5 + 4j
        >>> wrightomega(z)
        (-0.3362123489037213+2.282986001579032j)
        >>> lambertw(np.exp(z), k=1)
        (-0.33621234890372115+2.282986001579032j)

    xlog1py = <ufunc 'xlog1py'>
        xlog1py(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        xlog1py(x, y, out=None)

        Compute ``x*log1p(y)`` so that the result is 0 if ``x = 0``.

        Parameters
        ----------
        x : array_like
            Multiplier
        y : array_like
            Argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        z : scalar or ndarray
            Computed x*log1p(y)

        Notes
        -----

        .. versionadded:: 0.13.0

        Examples
        --------
        This example shows how the function can be used to calculate the log of
        the probability mass function for a geometric discrete random variable.
        The probability mass function of the geometric distribution is defined
        as follows:

        .. math:: f(k) = (1-p)^{k-1} p

        where :math:`p` is the probability of a single success
        and :math:`1-p` is the probability of a single failure
        and :math:`k` is the number of trials to get the first success.

        >>> import numpy as np
        >>> from scipy.special import xlog1py
        >>> p = 0.5
        >>> k = 100
        >>> _pmf = np.power(1 - p, k - 1) * p
        >>> _pmf
        7.888609052210118e-31

        If we take k as a relatively large number the value of the probability
        mass function can become very low. In such cases taking the log of the
        pmf would be more suitable as the log function can change the values
        to a scale that is more appropriate to work with.

        >>> _log_pmf = xlog1py(k - 1, -p) + np.log(p)
        >>> _log_pmf
        -69.31471805599453

        We can confirm that we get a value close to the original pmf value by
        taking the exponential of the log pmf.

        >>> _orig_pmf = np.exp(_log_pmf)
        >>> np.isclose(_pmf, _orig_pmf)
        True

    xlogy = <ufunc 'xlogy'>
        xlogy(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        xlogy(x, y, out=None)

        Compute ``x*log(y)`` so that the result is 0 if ``x = 0``.

        Parameters
        ----------
        x : array_like
            Multiplier
        y : array_like
            Argument
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        z : scalar or ndarray
            Computed x*log(y)

        Notes
        -----
        The log function used in the computation is the natural log.

        .. versionadded:: 0.13.0

        Examples
        --------
        We can use this function to calculate the binary logistic loss also
        known as the binary cross entropy. This loss function is used for
        binary classification problems and is defined as:

        .. math::
            L = 1/n * \sum_{i=0}^n -(y_i*log(y\_pred_i) + (1-y_i)*log(1-y\_pred_i))

        We can define the parameters `x` and `y` as y and y_pred respectively.
        y is the array of the actual labels which over here can be either 0 or 1.
        y_pred is the array of the predicted probabilities with respect to
        the positive class (1).

        >>> import numpy as np
        >>> from scipy.special import xlogy
        >>> y = np.array([0, 1, 0, 1, 1, 0])
        >>> y_pred = np.array([0.3, 0.8, 0.4, 0.7, 0.9, 0.2])
        >>> n = len(y)
        >>> loss = -(xlogy(y, y_pred) + xlogy(1 - y, 1 - y_pred)).sum()
        >>> loss /= n
        >>> loss
        0.29597052165495025

        A lower loss is usually better as it indicates that the predictions are
        similar to the actual labels. In this example since our predicted
        probabilities are close to the actual labels, we get an overall loss
        that is reasonably low and appropriate.

    y0 = <ufunc 'y0'>
        y0(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        y0(x, out=None)

        Bessel function of the second kind of order 0.

        Parameters
        ----------
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        Y : scalar or ndarray
            Value of the Bessel function of the second kind of order 0 at `x`.

        See Also
        --------
        j0: Bessel function of the first kind of order 0
        yv: Bessel function of the first kind

        Notes
        -----
        The domain is divided into the intervals [0, 5] and (5, infinity). In the
        first interval a rational approximation :math:`R(x)` is employed to
        compute,

        .. math::

            Y_0(x) = R(x) + \frac{2 \log(x) J_0(x)}{\pi},

        where :math:`J_0` is the Bessel function of the first kind of order 0.

        In the second interval, the Hankel asymptotic expansion is employed with
        two rational functions of degree 6/6 and 7/7.

        This function is a wrapper for the Cephes [1]_ routine `y0`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import y0
        >>> y0(1.)
        0.08825696421567697

        Calculate at several points:

        >>> import numpy as np
        >>> y0(np.array([0.5, 2., 3.]))
        array([-0.44451873,  0.51037567,  0.37685001])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = y0(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    y1 = <ufunc 'y1'>
        y1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        y1(x, out=None)

        Bessel function of the second kind of order 1.

        Parameters
        ----------
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        Y : scalar or ndarray
            Value of the Bessel function of the second kind of order 1 at `x`.

        See Also
        --------
        j1: Bessel function of the first kind of order 1
        yn: Bessel function of the second kind
        yv: Bessel function of the second kind

        Notes
        -----
        The domain is divided into the intervals [0, 8] and (8, infinity). In the
        first interval a 25 term Chebyshev expansion is used, and computing
        :math:`J_1` (the Bessel function of the first kind) is required. In the
        second, the asymptotic trigonometric representation is employed using two
        rational functions of degree 5/5.

        This function is a wrapper for the Cephes [1]_ routine `y1`.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Calculate the function at one point:

        >>> from scipy.special import y1
        >>> y1(1.)
        -0.7812128213002888

        Calculate at several points:

        >>> import numpy as np
        >>> y1(np.array([0.5, 2., 3.]))
        array([-1.47147239, -0.10703243,  0.32467442])

        Plot the function from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> y = y1(x)
        >>> ax.plot(x, y)
        >>> plt.show()

    yn = <ufunc 'yn'>
        yn(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        yn(n, x, out=None)

        Bessel function of the second kind of integer order and real argument.

        Parameters
        ----------
        n : array_like
            Order (integer).
        x : array_like
            Argument (float).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        Y : scalar or ndarray
            Value of the Bessel function, :math:`Y_n(x)`.

        See Also
        --------
        yv : For real order and real or complex argument.
        y0: faster implementation of this function for order 0
        y1: faster implementation of this function for order 1

        Notes
        -----
        Wrapper for the Cephes [1]_ routine `yn`.

        The function is evaluated by forward recurrence on `n`, starting with
        values computed by the Cephes routines `y0` and `y1`. If `n = 0` or 1,
        the routine for `y0` or `y1` is called directly.

        References
        ----------
        .. [1] Cephes Mathematical Functions Library,
               http://www.netlib.org/cephes/

        Examples
        --------
        Evaluate the function of order 0 at one point.

        >>> from scipy.special import yn
        >>> yn(0, 1.)
        0.08825696421567697

        Evaluate the function at one point for different orders.

        >>> yn(0, 1.), yn(1, 1.), yn(2, 1.)
        (0.08825696421567697, -0.7812128213002888, -1.6506826068162546)

        The evaluation for different orders can be carried out in one call by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> yn([0, 1, 2], 1.)
        array([ 0.08825696, -0.78121282, -1.65068261])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 3., 8.])
        >>> yn(0, points)
        array([-0.44451873,  0.37685001,  0.22352149])

        If `z` is an array, the order parameter `v` must be broadcastable to
        the correct shape if different orders shall be computed in one call.
        To calculate the orders 0 and 1 for an 1D array:

        >>> orders = np.array([[0], [1]])
        >>> orders.shape
        (2, 1)

        >>> yn(orders, points)
        array([[-0.44451873,  0.37685001,  0.22352149],
               [-1.47147239,  0.32467442, -0.15806046]])

        Plot the functions of order 0 to 3 from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, yn(i, x), label=f'$Y_{i!r}$')
        >>> ax.set_ylim(-3, 1)
        >>> ax.legend()
        >>> plt.show()

    yv = <ufunc 'yv'>
        yv(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        yv(v, z, out=None)

        Bessel function of the second kind of real order and complex argument.

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        Y : scalar or ndarray
            Value of the Bessel function of the second kind, :math:`Y_v(x)`.

        See Also
        --------
        yve : :math:`Y_v` with leading exponential behavior stripped off.
        y0: faster implementation of this function for order 0
        y1: faster implementation of this function for order 1

        Notes
        -----
        For positive `v` values, the computation is carried out using the
        AMOS [1]_ `zbesy` routine, which exploits the connection to the Hankel
        Bessel functions :math:`H_v^{(1)}` and :math:`H_v^{(2)}`,

        .. math:: Y_v(z) = \frac{1}{2\imath} (H_v^{(1)} - H_v^{(2)}).

        For negative `v` values the formula,

        .. math:: Y_{-v}(z) = Y_v(z) \cos(\pi v) + J_v(z) \sin(\pi v)

        is used, where :math:`J_v(z)` is the Bessel function of the first kind,
        computed using the AMOS routine `zbesj`.  Note that the second term is
        exactly zero for integer `v`; to improve accuracy the second term is
        explicitly omitted for `v` values such that `v = floor(v)`.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Evaluate the function of order 0 at one point.

        >>> from scipy.special import yv
        >>> yv(0, 1.)
        0.088256964215677

        Evaluate the function at one point for different orders.

        >>> yv(0, 1.), yv(1, 1.), yv(1.5, 1.)
        (0.088256964215677, -0.7812128213002889, -1.102495575160179)

        The evaluation for different orders can be carried out in one call by
        providing a list or NumPy array as argument for the `v` parameter:

        >>> yv([0, 1, 1.5], 1.)
        array([ 0.08825696, -0.78121282, -1.10249558])

        Evaluate the function at several points for order 0 by providing an
        array for `z`.

        >>> import numpy as np
        >>> points = np.array([0.5, 3., 8.])
        >>> yv(0, points)
        array([-0.44451873,  0.37685001,  0.22352149])

        If `z` is an array, the order parameter `v` must be broadcastable to
        the correct shape if different orders shall be computed in one call.
        To calculate the orders 0 and 1 for an 1D array:

        >>> orders = np.array([[0], [1]])
        >>> orders.shape
        (2, 1)

        >>> yv(orders, points)
        array([[-0.44451873,  0.37685001,  0.22352149],
               [-1.47147239,  0.32467442, -0.15806046]])

        Plot the functions of order 0 to 3 from 0 to 10.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> x = np.linspace(0., 10., 1000)
        >>> for i in range(4):
        ...     ax.plot(x, yv(i, x), label=f'$Y_{i!r}$')
        >>> ax.set_ylim(-3, 1)
        >>> ax.legend()
        >>> plt.show()

    yve = <ufunc 'yve'>
        yve(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])


        yve(v, z, out=None)

        Exponentially scaled Bessel function of the second kind of real order.

        Returns the exponentially scaled Bessel function of the second
        kind of real order `v` at complex `z`::

            yve(v, z) = yv(v, z) * exp(-abs(z.imag))

        Parameters
        ----------
        v : array_like
            Order (float).
        z : array_like
            Argument (float or complex).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        Y : scalar or ndarray
            Value of the exponentially scaled Bessel function.

        See Also
        --------
        yv: Unscaled Bessel function of the second kind of real order.

        Notes
        -----
        For positive `v` values, the computation is carried out using the
        AMOS [1]_ `zbesy` routine, which exploits the connection to the Hankel
        Bessel functions :math:`H_v^{(1)}` and :math:`H_v^{(2)}`,

        .. math:: Y_v(z) = \frac{1}{2\imath} (H_v^{(1)} - H_v^{(2)}).

        For negative `v` values the formula,

        .. math:: Y_{-v}(z) = Y_v(z) \cos(\pi v) + J_v(z) \sin(\pi v)

        is used, where :math:`J_v(z)` is the Bessel function of the first kind,
        computed using the AMOS routine `zbesj`.  Note that the second term is
        exactly zero for integer `v`; to improve accuracy the second term is
        explicitly omitted for `v` values such that `v = floor(v)`.

        Exponentially scaled Bessel functions are useful for large `z`:
        for these, the unscaled Bessel functions can easily under-or overflow.

        References
        ----------
        .. [1] Donald E. Amos, "AMOS, A Portable Package for Bessel Functions
               of a Complex Argument and Nonnegative Order",
               http://netlib.org/amos/

        Examples
        --------
        Compare the output of `yv` and `yve` for large complex arguments for `z`
        by computing their values for order ``v=1`` at ``z=1000j``. We see that
        `yv` returns nan but `yve` returns a finite number:

        >>> import numpy as np
        >>> from scipy.special import yv, yve
        >>> v = 1
        >>> z = 1000j
        >>> yv(v, z), yve(v, z)
        ((nan+nanj), (-0.012610930256928629+7.721967686709076e-19j))

        For real arguments for `z`, `yve` returns the same as `yv` up to
        floating point errors.

        >>> v, z = 1, 1000
        >>> yv(v, z), yve(v, z)
        (-0.02478433129235178, -0.02478433129235179)

        The function can be evaluated for several orders at the same time by
        providing a list or NumPy array for `v`:

        >>> yve([1, 2, 3], 1j)
        array([-0.20791042+0.14096627j,  0.38053618-0.04993878j,
               0.00815531-1.66311097j])

        In the same way, the function can be evaluated at several points in one
        call by providing a list or NumPy array for `z`:

        >>> yve(1, np.array([1j, 2j, 3j]))
        array([-0.20791042+0.14096627j, -0.21526929+0.01205044j,
               -0.19682671+0.00127278j])

        It is also possible to evaluate several orders at several points
        at the same time by providing arrays for `v` and `z` with
        broadcasting compatible shapes. Compute `yve` for two different orders
        `v` and three points `z` resulting in a 2x3 array.

        >>> v = np.array([[1], [2]])
        >>> z = np.array([3j, 4j, 5j])
        >>> v.shape, z.shape
        ((2, 1), (3,))

        >>> yve(v, z)
        array([[-1.96826713e-01+1.27277544e-03j, -1.78750840e-01+1.45558819e-04j,
                -1.63972267e-01+1.73494110e-05j],
               [1.94960056e-03-1.11782545e-01j,  2.02902325e-04-1.17626501e-01j,
                2.27727687e-05-1.17951906e-01j]])

    zetac = <ufunc 'zetac'>
        zetac(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature])

        zetac(x, out=None)

        Riemann zeta function minus 1.

        This function is defined as

        .. math:: \zeta(x) = \sum_{k=2}^{\infty} 1 / k^x,

        where ``x > 1``.  For ``x < 1`` the analytic continuation is
        computed. For more information on the Riemann zeta function, see
        [dlmf]_.

        Parameters
        ----------
        x : array_like of float
            Values at which to compute zeta(x) - 1 (must be real).
        out : ndarray, optional
            Optional output array for the function results

        Returns
        -------
        scalar or ndarray
            Values of zeta(x) - 1.

        See Also
        --------
        zeta

        References
        ----------
        .. [dlmf] NIST Digital Library of Mathematical Functions
                  https://dlmf.nist.gov/25

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.special import zetac, zeta

        Some special values:

        >>> zetac(2), np.pi**2/6 - 1
        (0.64493406684822641, 0.6449340668482264)

        >>> zetac(-1), -1.0/12 - 1
        (-1.0833333333333333, -1.0833333333333333)

        Compare ``zetac(x)`` to ``zeta(x) - 1`` for large `x`:

        >>> zetac(60), zeta(60) - 1
        (8.673617380119933e-19, 0.0)

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\special\__init__.py

scipy.stats
Python Library Documentation: package scipy.stats in scipy

NAME
    scipy.stats - .. _statsrefmanual:

DESCRIPTION
    ==========================================
    Statistical functions (:mod:`scipy.stats`)
    ==========================================

    .. currentmodule:: scipy.stats

    This module contains a large number of probability distributions,
    summary and frequency statistics, correlation functions and statistical
    tests, masked statistics, kernel density estimation, quasi-Monte Carlo
    functionality, and more.

    Statistics is a very large area, and there are topics that are out of scope
    for SciPy and are covered by other packages. Some of the most important ones
    are:

    - `statsmodels <https://www.statsmodels.org/stable/index.html>`__:
      regression, linear models, time series analysis, extensions to topics
      also covered by ``scipy.stats``.
    - `Pandas <https://pandas.pydata.org/>`__: tabular data, time series
      functionality, interfaces to other statistical languages.
    - `PyMC <https://docs.pymc.io/>`__: Bayesian statistical
      modeling, probabilistic machine learning.
    - `scikit-learn <https://scikit-learn.org/>`__: classification, regression,
      model selection.
    - `Seaborn <https://seaborn.pydata.org/>`__: statistical data visualization.
    - `rpy2 <https://rpy2.github.io/>`__: Python to R bridge.


    Probability distributions
    =========================

    Each univariate distribution is an instance of a subclass of `rv_continuous`
    (`rv_discrete` for discrete distributions):

    .. autosummary::
       :toctree: generated/

       rv_continuous
       rv_discrete
       rv_histogram

    Continuous distributions
    ------------------------

    .. autosummary::
       :toctree: generated/

       alpha             -- Alpha
       anglit            -- Anglit
       arcsine           -- Arcsine
       argus             -- Argus
       beta              -- Beta
       betaprime         -- Beta Prime
       bradford          -- Bradford
       burr              -- Burr (Type III)
       burr12            -- Burr (Type XII)
       cauchy            -- Cauchy
       chi               -- Chi
       chi2              -- Chi-squared
       cosine            -- Cosine
       crystalball       -- Crystalball
       dgamma            -- Double Gamma
       dweibull          -- Double Weibull
       erlang            -- Erlang
       expon             -- Exponential
       exponnorm         -- Exponentially Modified Normal
       exponweib         -- Exponentiated Weibull
       exponpow          -- Exponential Power
       f                 -- F (Snecdor F)
       fatiguelife       -- Fatigue Life (Birnbaum-Saunders)
       fisk              -- Fisk
       foldcauchy        -- Folded Cauchy
       foldnorm          -- Folded Normal
       genlogistic       -- Generalized Logistic
       gennorm           -- Generalized normal
       genpareto         -- Generalized Pareto
       genexpon          -- Generalized Exponential
       genextreme        -- Generalized Extreme Value
       gausshyper        -- Gauss Hypergeometric
       gamma             -- Gamma
       gengamma          -- Generalized gamma
       genhalflogistic   -- Generalized Half Logistic
       genhyperbolic     -- Generalized Hyperbolic
       geninvgauss       -- Generalized Inverse Gaussian
       gibrat            -- Gibrat
       gompertz          -- Gompertz (Truncated Gumbel)
       gumbel_r          -- Right Sided Gumbel, Log-Weibull, Fisher-Tippett, Extreme Value Type I
       gumbel_l          -- Left Sided Gumbel, etc.
       halfcauchy        -- Half Cauchy
       halflogistic      -- Half Logistic
       halfnorm          -- Half Normal
       halfgennorm       -- Generalized Half Normal
       hypsecant         -- Hyperbolic Secant
       invgamma          -- Inverse Gamma
       invgauss          -- Inverse Gaussian
       invweibull        -- Inverse Weibull
       irwinhall         -- Irwin-Hall
       jf_skew_t         -- Jones and Faddy Skew-T
       johnsonsb         -- Johnson SB
       johnsonsu         -- Johnson SU
       kappa4            -- Kappa 4 parameter
       kappa3            -- Kappa 3 parameter
       ksone             -- Distribution of Kolmogorov-Smirnov one-sided test statistic
       kstwo             -- Distribution of Kolmogorov-Smirnov two-sided test statistic
       kstwobign         -- Limiting Distribution of scaled Kolmogorov-Smirnov two-sided test statistic.
       laplace           -- Laplace
       laplace_asymmetric    -- Asymmetric Laplace
       levy              -- Levy
       levy_l
       levy_stable
       logistic          -- Logistic
       loggamma          -- Log-Gamma
       loglaplace        -- Log-Laplace (Log Double Exponential)
       lognorm           -- Log-Normal
       loguniform        -- Log-Uniform
       lomax             -- Lomax (Pareto of the second kind)
       maxwell           -- Maxwell
       mielke            -- Mielke's Beta-Kappa
       moyal             -- Moyal
       nakagami          -- Nakagami
       ncx2              -- Non-central chi-squared
       ncf               -- Non-central F
       nct               -- Non-central Student's T
       norm              -- Normal (Gaussian)
       norminvgauss      -- Normal Inverse Gaussian
       pareto            -- Pareto
       pearson3          -- Pearson type III
       powerlaw          -- Power-function
       powerlognorm      -- Power log normal
       powernorm         -- Power normal
       rdist             -- R-distribution
       rayleigh          -- Rayleigh
       rel_breitwigner   -- Relativistic Breit-Wigner
       rice              -- Rice
       recipinvgauss     -- Reciprocal Inverse Gaussian
       semicircular      -- Semicircular
       skewcauchy        -- Skew Cauchy
       skewnorm          -- Skew normal
       studentized_range    -- Studentized Range
       t                 -- Student's T
       trapezoid         -- Trapezoidal
       triang            -- Triangular
       truncexpon        -- Truncated Exponential
       truncnorm         -- Truncated Normal
       truncpareto       -- Truncated Pareto
       truncweibull_min  -- Truncated minimum Weibull distribution
       tukeylambda       -- Tukey-Lambda
       uniform           -- Uniform
       vonmises          -- Von-Mises (Circular)
       vonmises_line     -- Von-Mises (Line)
       wald              -- Wald
       weibull_min       -- Minimum Weibull (see Frechet)
       weibull_max       -- Maximum Weibull (see Frechet)
       wrapcauchy        -- Wrapped Cauchy

    The ``fit`` method of the univariate continuous distributions uses
    maximum likelihood estimation to fit the distribution to a data set.
    The ``fit`` method can accept regular data or *censored data*.
    Censored data is represented with instances of the `CensoredData`
    class.

    .. autosummary::
       :toctree: generated/

       CensoredData


    Multivariate distributions
    --------------------------

    .. autosummary::
       :toctree: generated/

       multivariate_normal    -- Multivariate normal distribution
       matrix_normal          -- Matrix normal distribution
       dirichlet              -- Dirichlet
       dirichlet_multinomial  -- Dirichlet multinomial distribution
       wishart                -- Wishart
       invwishart             -- Inverse Wishart
       multinomial            -- Multinomial distribution
       special_ortho_group    -- SO(N) group
       ortho_group            -- O(N) group
       unitary_group          -- U(N) group
       random_correlation     -- random correlation matrices
       multivariate_t         -- Multivariate t-distribution
       multivariate_hypergeom -- Multivariate hypergeometric distribution
       random_table           -- Distribution of random tables with given marginals
       uniform_direction      -- Uniform distribution on S(N-1)
       vonmises_fisher        -- Von Mises-Fisher distribution

    `scipy.stats.multivariate_normal` methods accept instances
    of the following class to represent the covariance.

    .. autosummary::
       :toctree: generated/

       Covariance             -- Representation of a covariance matrix


    Discrete distributions
    ----------------------

    .. autosummary::
       :toctree: generated/

       bernoulli                -- Bernoulli
       betabinom                -- Beta-Binomial
       betanbinom               -- Beta-Negative Binomial
       binom                    -- Binomial
       boltzmann                -- Boltzmann (Truncated Discrete Exponential)
       dlaplace                 -- Discrete Laplacian
       geom                     -- Geometric
       hypergeom                -- Hypergeometric
       logser                   -- Logarithmic (Log-Series, Series)
       nbinom                   -- Negative Binomial
       nchypergeom_fisher       -- Fisher's Noncentral Hypergeometric
       nchypergeom_wallenius    -- Wallenius's Noncentral Hypergeometric
       nhypergeom               -- Negative Hypergeometric
       planck                   -- Planck (Discrete Exponential)
       poisson                  -- Poisson
       randint                  -- Discrete Uniform
       skellam                  -- Skellam
       yulesimon                -- Yule-Simon
       zipf                     -- Zipf (Zeta)
       zipfian                  -- Zipfian


    An overview of statistical functions is given below.  Many of these functions
    have a similar version in `scipy.stats.mstats` which work for masked arrays.

    Summary statistics
    ==================

    .. autosummary::
       :toctree: generated/

       describe          -- Descriptive statistics
       gmean             -- Geometric mean
       hmean             -- Harmonic mean
       pmean             -- Power mean
       kurtosis          -- Fisher or Pearson kurtosis
       mode              -- Modal value
       moment            -- Central moment
       expectile         -- Expectile
       skew              -- Skewness
       kstat             --
       kstatvar          --
       tmean             -- Truncated arithmetic mean
       tvar              -- Truncated variance
       tmin              --
       tmax              --
       tstd              --
       tsem              --
       variation         -- Coefficient of variation
       find_repeats
       rankdata
       tiecorrect
       trim_mean
       gstd              -- Geometric Standard Deviation
       iqr
       sem
       bayes_mvs
       mvsdist
       entropy
       differential_entropy
       median_abs_deviation

    Frequency statistics
    ====================

    .. autosummary::
       :toctree: generated/

       cumfreq
       percentileofscore
       scoreatpercentile
       relfreq

    .. autosummary::
       :toctree: generated/

       binned_statistic     -- Compute a binned statistic for a set of data.
       binned_statistic_2d  -- Compute a 2-D binned statistic for a set of data.
       binned_statistic_dd  -- Compute a d-D binned statistic for a set of data.

    .. _hypotests:

    Hypothesis Tests and related functions
    ======================================
    SciPy has many functions for performing hypothesis tests that return a
    test statistic and a p-value, and several of them return confidence intervals
    and/or other related information.

    The headings below are based on common uses of the functions within, but due to
    the wide variety of statistical procedures, any attempt at coarse-grained
    categorization will be imperfect. Also, note that tests within the same heading
    are not interchangeable in general (e.g. many have different distributional
    assumptions).

    One Sample Tests / Paired Sample Tests
    --------------------------------------
    One sample tests are typically used to assess whether a single sample was
    drawn from a specified distribution or a distribution with specified properties
    (e.g. zero mean).

    .. autosummary::
       :toctree: generated/

       ttest_1samp
       binomtest
       quantile_test
       skewtest
       kurtosistest
       normaltest
       jarque_bera
       shapiro
       anderson
       cramervonmises
       ks_1samp
       goodness_of_fit
       chisquare
       power_divergence

    Paired sample tests are often used to assess whether two samples were drawn
    from the same distribution; they differ from the independent sample tests below
    in that each observation in one sample is treated as paired with a
    closely-related observation in the other sample (e.g. when environmental
    factors are controlled between observations within a pair but not among pairs).
    They can also be interpreted or used as one-sample tests (e.g. tests on the
    mean or median of *differences* between paired observations).

    .. autosummary::
       :toctree: generated/

       ttest_rel
       wilcoxon

    Association/Correlation Tests
    -----------------------------

    These tests are often used to assess whether there is a relationship (e.g.
    linear) between paired observations in multiple samples or among the
    coordinates of multivariate observations.

    .. autosummary::
       :toctree: generated/

       linregress
       pearsonr
       spearmanr
       pointbiserialr
       kendalltau
       weightedtau
       somersd
       siegelslopes
       theilslopes
       page_trend_test
       multiscale_graphcorr

    These association tests and are to work with samples in the form of contingency
    tables. Supporting functions are available in `scipy.stats.contingency`.

    .. autosummary::
       :toctree: generated/

       chi2_contingency
       fisher_exact
       barnard_exact
       boschloo_exact

    Independent Sample Tests
    ------------------------
    Independent sample tests are typically used to assess whether multiple samples
    were independently drawn from the same distribution or different distributions
    with a shared property (e.g. equal means).

    Some tests are specifically for comparing two samples.

    .. autosummary::
       :toctree: generated/

       ttest_ind_from_stats
       poisson_means_test
       ttest_ind
       mannwhitneyu
       bws_test
       ranksums
       brunnermunzel
       mood
       ansari
       cramervonmises_2samp
       epps_singleton_2samp
       ks_2samp
       kstest

    Others are generalized to multiple samples.

    .. autosummary::
       :toctree: generated/

       f_oneway
       tukey_hsd
       dunnett
       kruskal
       alexandergovern
       fligner
       levene
       bartlett
       median_test
       friedmanchisquare
       anderson_ksamp

    Resampling and Monte Carlo Methods
    ----------------------------------
    The following functions can reproduce the p-value and confidence interval
    results of most of the functions above, and often produce accurate results in a
    wider variety of conditions. They can also be used to perform hypothesis tests
    and generate confidence intervals for custom statistics. This flexibility comes
    at the cost of greater computational requirements and stochastic results.

    .. autosummary::
       :toctree: generated/

       monte_carlo_test
       permutation_test
       bootstrap
       power

    Instances of the following object can be passed into some hypothesis test
    functions to perform a resampling or Monte Carlo version of the hypothesis
    test.

    .. autosummary::
       :toctree: generated/

       MonteCarloMethod
       PermutationMethod
       BootstrapMethod

    Multiple Hypothesis Testing and Meta-Analysis
    ---------------------------------------------
    These functions are for assessing the results of individual tests as a whole.
    Functions for performing specific multiple hypothesis tests (e.g. post hoc
    tests) are listed above.

    .. autosummary::
       :toctree: generated/

       combine_pvalues
       false_discovery_control


    The following functions are related to the tests above but do not belong in the
    above categories.

    Quasi-Monte Carlo
    =================

    .. toctree::
       :maxdepth: 4

       stats.qmc

    Contingency Tables
    ==================

    .. toctree::
       :maxdepth: 4

       stats.contingency

    Masked statistics functions
    ===========================

    .. toctree::

       stats.mstats


    Other statistical functionality
    ===============================

    Transformations
    ---------------

    .. autosummary::
       :toctree: generated/

       boxcox
       boxcox_normmax
       boxcox_llf
       yeojohnson
       yeojohnson_normmax
       yeojohnson_llf
       obrientransform
       sigmaclip
       trimboth
       trim1
       zmap
       zscore
       gzscore

    Statistical distances
    ---------------------

    .. autosummary::
       :toctree: generated/

       wasserstein_distance
       wasserstein_distance_nd
       energy_distance

    Sampling
    --------

    .. toctree::
       :maxdepth: 4

       stats.sampling

    Random variate generation / CDF Inversion
    -----------------------------------------

    .. autosummary::
       :toctree: generated/

       rvs_ratio_uniforms

    Fitting / Survival Analysis
    ---------------------------

    .. autosummary::
       :toctree: generated/

       fit
       ecdf
       logrank

    Directional statistical functions
    ---------------------------------

    .. autosummary::
       :toctree: generated/

       directional_stats
       circmean
       circvar
       circstd

    Sensitivity Analysis
    --------------------

    .. autosummary::
       :toctree: generated/

       sobol_indices

    Plot-tests
    ----------

    .. autosummary::
       :toctree: generated/

       ppcc_max
       ppcc_plot
       probplot
       boxcox_normplot
       yeojohnson_normplot

    Univariate and multivariate kernel density estimation
    -----------------------------------------------------

    .. autosummary::
       :toctree: generated/

       gaussian_kde

    Warnings / Errors used in :mod:`scipy.stats`
    --------------------------------------------

    .. autosummary::
       :toctree: generated/

       DegenerateDataWarning
       ConstantInputWarning
       NearConstantInputWarning
       FitError

    Result classes used in :mod:`scipy.stats`
    -----------------------------------------

    .. warning::

        These classes are private, but they are included here because instances
        of them are returned by other statistical functions. User import and
        instantiation is not supported.

    .. toctree::
       :maxdepth: 2

       stats._result_classes

PACKAGE CONTENTS
    _ansari_swilk_statistics
    _axis_nan_policy
    _biasedurn
    _binned_statistic
    _binomtest
    _bws_test
    _censored_data
    _common
    _constants
    _continuous_distns
    _covariance
    _crosstab
    _discrete_distns
    _distn_infrastructure
    _distr_params
    _entropy
    _fit
    _hypotests
    _kde
    _ksstats
    _levy_stable (package)
    _mannwhitneyu
    _mgc
    _morestats
    _mstats_basic
    _mstats_extras
    _multicomp
    _multivariate
    _mvn
    _odds_ratio
    _page_trend_test
    _qmc
    _qmc_cy
    _qmvnt
    _rcont (package)
    _relative_risk
    _resampling
    _result_classes
    _rvs_sampling
    _sampling
    _sensitivity_analysis
    _sobol
    _stats
    _stats_mstats_common
    _stats_py
    _stats_pythran
    _survival
    _tukeylambda_stats
    _unuran (package)
    _variation
    _warnings_errors
    _wilcoxon
    biasedurn
    contingency
    distributions
    kde
    morestats
    mstats
    mstats_basic
    mstats_extras
    mvn
    qmc
    sampling
    stats
    tests (package)

CLASSES
    builtins.RuntimeError(builtins.Exception)
        scipy.stats._warnings_errors.FitError
    builtins.RuntimeWarning(builtins.Warning)
        scipy.stats._warnings_errors.DegenerateDataWarning
            scipy.stats._warnings_errors.ConstantInputWarning
            scipy.stats._warnings_errors.NearConstantInputWarning
    builtins.object
        scipy.stats._censored_data.CensoredData
        scipy.stats._covariance.Covariance
        scipy.stats._kde.gaussian_kde
    scipy.stats._distn_infrastructure.rv_generic(builtins.object)
        scipy.stats._distn_infrastructure.rv_continuous
            scipy.stats._continuous_distns.rv_histogram
        scipy.stats._distn_infrastructure.rv_discrete
    scipy.stats._resampling.ResamplingMethod(builtins.object)
        scipy.stats._resampling.BootstrapMethod
        scipy.stats._resampling.MonteCarloMethod
        scipy.stats._resampling.PermutationMethod

    class BootstrapMethod(ResamplingMethod)
     |  BootstrapMethod(n_resamples: 'int' = 9999, batch: 'int' = None, random_state: 'object' = None, method: 'str' = 'BCa') -> None
     |
     |  Configuration information for a bootstrap confidence interval.
     |
     |  Instances of this class can be passed into the `method` parameter of some
     |  confidence interval methods to generate a bootstrap confidence interval.
     |
     |  Attributes
     |  ----------
     |  n_resamples : int, optional
     |      The number of resamples to perform. Default is 9999.
     |  batch : int, optional
     |      The number of resamples to process in each vectorized call to
     |      the statistic. Batch sizes >>1 tend to be faster when the statistic
     |      is vectorized, but memory usage scales linearly with the batch size.
     |      Default is ``None``, which processes all resamples in a single batch.
     |  random_state : {None, int, `numpy.random.Generator`,
     |                  `numpy.random.RandomState`}, optional
     |
     |      Pseudorandom number generator state used to generate resamples.
     |
     |      If `random_state` is already a ``Generator`` or ``RandomState``
     |      instance, then that instance is used.
     |      If `random_state` is an int, a new ``RandomState`` instance is used,
     |      seeded with `random_state`.
     |      If `random_state` is ``None`` (default), the
     |      `numpy.random.RandomState` singleton is used.
     |
     |  method : {'bca', 'percentile', 'basic'}
     |      Whether to use the 'percentile' bootstrap ('percentile'), the 'basic'
     |      (AKA 'reverse') bootstrap ('basic'), or the bias-corrected and
     |      accelerated bootstrap ('BCa', default).
     |
     |  Method resolution order:
     |      BootstrapMethod
     |      ResamplingMethod
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __init__(self, n_resamples: 'int' = 9999, batch: 'int' = None, random_state: 'object' = None, method: 'str' = 'BCa') -> None
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {'method': 'str', 'random_state': 'object'}
     |
     |  __dataclass_fields__ = {'batch': Field(name='batch',type='int',default...
     |
     |  __dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,or...
     |
     |  __hash__ = None
     |
     |  __match_args__ = ('n_resamples', 'batch', 'random_state', 'method')
     |
     |  method = 'BCa'
     |
     |  random_state = None
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from ResamplingMethod:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from ResamplingMethod:
     |
     |  batch = None
     |
     |  n_resamples = 9999

    class CensoredData(builtins.object)
     |  CensoredData(uncensored=None, *, left=None, right=None, interval=None)
     |
     |  Instances of this class represent censored data.
     |
     |  Instances may be passed to the ``fit`` method of continuous
     |  univariate SciPy distributions for maximum likelihood estimation.
     |  The *only* method of the univariate continuous distributions that
     |  understands `CensoredData` is the ``fit`` method.  An instance of
     |  `CensoredData` can not be passed to methods such as ``pdf`` and
     |  ``cdf``.
     |
     |  An observation is said to be *censored* when the precise value is unknown,
     |  but it has a known upper and/or lower bound.  The conventional terminology
     |  is:
     |
     |  * left-censored: an observation is below a certain value but it is
     |    unknown by how much.
     |  * right-censored: an observation is above a certain value but it is
     |    unknown by how much.
     |  * interval-censored: an observation lies somewhere on an interval between
     |    two values.
     |
     |  Left-, right-, and interval-censored data can be represented by
     |  `CensoredData`.
     |
     |  For convenience, the class methods ``left_censored`` and
     |  ``right_censored`` are provided to create a `CensoredData`
     |  instance from a single one-dimensional array of measurements
     |  and a corresponding boolean array to indicate which measurements
     |  are censored.  The class method ``interval_censored`` accepts two
     |  one-dimensional arrays that hold the lower and upper bounds of the
     |  intervals.
     |
     |  Parameters
     |  ----------
     |  uncensored : array_like, 1D
     |      Uncensored observations.
     |  left : array_like, 1D
     |      Left-censored observations.
     |  right : array_like, 1D
     |      Right-censored observations.
     |  interval : array_like, 2D, with shape (m, 2)
     |      Interval-censored observations.  Each row ``interval[k, :]``
     |      represents the interval for the kth interval-censored observation.
     |
     |  Notes
     |  -----
     |  In the input array `interval`, the lower bound of the interval may
     |  be ``-inf``, and the upper bound may be ``inf``, but at least one must be
     |  finite. When the lower bound is ``-inf``, the row represents a left-
     |  censored observation, and when the upper bound is ``inf``, the row
     |  represents a right-censored observation.  If the length of an interval
     |  is 0 (i.e. ``interval[k, 0] == interval[k, 1]``, the observation is
     |  treated as uncensored.  So one can represent all the types of censored
     |  and uncensored data in ``interval``, but it is generally more convenient
     |  to use `uncensored`, `left` and `right` for uncensored, left-censored and
     |  right-censored observations, respectively.
     |
     |  Examples
     |  --------
     |  In the most general case, a censored data set may contain values that
     |  are left-censored, right-censored, interval-censored, and uncensored.
     |  For example, here we create a data set with five observations.  Two
     |  are uncensored (values 1 and 1.5), one is a left-censored observation
     |  of 0, one is a right-censored observation of 10 and one is
     |  interval-censored in the interval [2, 3].
     |
     |  >>> import numpy as np
     |  >>> from scipy.stats import CensoredData
     |  >>> data = CensoredData(uncensored=[1, 1.5], left=[0], right=[10],
     |  ...                     interval=[[2, 3]])
     |  >>> print(data)
     |  CensoredData(5 values: 2 not censored, 1 left-censored,
     |  1 right-censored, 1 interval-censored)
     |
     |  Equivalently,
     |
     |  >>> data = CensoredData(interval=[[1, 1],
     |  ...                               [1.5, 1.5],
     |  ...                               [-np.inf, 0],
     |  ...                               [10, np.inf],
     |  ...                               [2, 3]])
     |  >>> print(data)
     |  CensoredData(5 values: 2 not censored, 1 left-censored,
     |  1 right-censored, 1 interval-censored)
     |
     |  A common case is to have a mix of uncensored observations and censored
     |  observations that are all right-censored (or all left-censored). For
     |  example, consider an experiment in which six devices are started at
     |  various times and left running until they fail.  Assume that time is
     |  measured in hours, and the experiment is stopped after 30 hours, even
     |  if all the devices have not failed by that time.  We might end up with
     |  data such as this::
     |
     |      Device  Start-time  Fail-time  Time-to-failure
     |         1         0         13           13
     |         2         2         24           22
     |         3         5         22           17
     |         4         8         23           15
     |         5        10        ***          >20
     |         6        12        ***          >18
     |
     |  Two of the devices had not failed when the experiment was stopped;
     |  the observations of the time-to-failure for these two devices are
     |  right-censored.  We can represent this data with
     |
     |  >>> data = CensoredData(uncensored=[13, 22, 17, 15], right=[20, 18])
     |  >>> print(data)
     |  CensoredData(6 values: 4 not censored, 2 right-censored)
     |
     |  Alternatively, we can use the method `CensoredData.right_censored` to
     |  create a representation of this data.  The time-to-failure observations
     |  are put the list ``ttf``.  The ``censored`` list indicates which values
     |  in ``ttf`` are censored.
     |
     |  >>> ttf = [13, 22, 17, 15, 20, 18]
     |  >>> censored = [False, False, False, False, True, True]
     |
     |  Pass these lists to `CensoredData.right_censored` to create an
     |  instance of `CensoredData`.
     |
     |  >>> data = CensoredData.right_censored(ttf, censored)
     |  >>> print(data)
     |  CensoredData(6 values: 4 not censored, 2 right-censored)
     |
     |  If the input data is interval censored and already stored in two
     |  arrays, one holding the low end of the intervals and another
     |  holding the high ends, the class method ``interval_censored`` can
     |  be used to create the `CensoredData` instance.
     |
     |  This example creates an instance with four interval-censored values.
     |  The intervals are [10, 11], [0.5, 1], [2, 3], and [12.5, 13.5].
     |
     |  >>> a = [10, 0.5, 2, 12.5]  # Low ends of the intervals
     |  >>> b = [11, 1.0, 3, 13.5]  # High ends of the intervals
     |  >>> data = CensoredData.interval_censored(low=a, high=b)
     |  >>> print(data)
     |  CensoredData(4 values: 0 not censored, 4 interval-censored)
     |
     |  Finally, we create and censor some data from the `weibull_min`
     |  distribution, and then fit `weibull_min` to that data. We'll assume
     |  that the location parameter is known to be 0.
     |
     |  >>> from scipy.stats import weibull_min
     |  >>> rng = np.random.default_rng()
     |
     |  Create the random data set.
     |
     |  >>> x = weibull_min.rvs(2.5, loc=0, scale=30, size=250, random_state=rng)
     |  >>> x[x > 40] = 40  # Right-censor values greater or equal to 40.
     |
     |  Create the `CensoredData` instance with the `right_censored` method.
     |  The censored values are those where the value is 40.
     |
     |  >>> data = CensoredData.right_censored(x, x == 40)
     |  >>> print(data)
     |  CensoredData(250 values: 215 not censored, 35 right-censored)
     |
     |  35 values have been right-censored.
     |
     |  Fit `weibull_min` to the censored data.  We expect to shape and scale
     |  to be approximately 2.5 and 30, respectively.
     |
     |  >>> weibull_min.fit(data, floc=0)
     |  (2.3575922823897315, 0, 30.40650074451254)
     |
     |  Methods defined here:
     |
     |  __init__(self, uncensored=None, *, left=None, right=None, interval=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __len__(self)
     |      The number of values (censored and not censored).
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  __str__(self)
     |      Return str(self).
     |
     |  __sub__(self, other)
     |
     |  __truediv__(self, other)
     |
     |  num_censored(self)
     |      Number of censored values.
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  interval_censored(low, high)
     |      Create a `CensoredData` instance of interval-censored data.
     |
     |      This method is useful when all the data is interval-censored, and
     |      the low and high ends of the intervals are already stored in
     |      separate one-dimensional arrays.
     |
     |      Parameters
     |      ----------
     |      low : array_like
     |          The one-dimensional array containing the low ends of the
     |          intervals.
     |      high : array_like
     |          The one-dimensional array containing the high ends of the
     |          intervals.
     |
     |      Returns
     |      -------
     |      data : `CensoredData`
     |          An instance of `CensoredData` that represents the
     |          collection of censored values.
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy.stats import CensoredData
     |
     |      ``a`` and ``b`` are the low and high ends of a collection of
     |      interval-censored values.
     |
     |      >>> a = [0.5, 2.0, 3.0, 5.5]
     |      >>> b = [1.0, 2.5, 3.5, 7.0]
     |      >>> data = CensoredData.interval_censored(low=a, high=b)
     |      >>> print(data)
     |      CensoredData(4 values: 0 not censored, 4 interval-censored)
     |
     |  left_censored(x, censored)
     |      Create a `CensoredData` instance of left-censored data.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          `x` is the array of observed data or measurements.
     |          `x` must be a one-dimensional sequence of finite numbers.
     |      censored : array_like of bool
     |          `censored` must be a one-dimensional sequence of boolean
     |          values.  If ``censored[k]`` is True, the corresponding value
     |          in `x` is left-censored.  That is, the value ``x[k]``
     |          is the upper bound of the true (but unknown) value.
     |
     |      Returns
     |      -------
     |      data : `CensoredData`
     |          An instance of `CensoredData` that represents the
     |          collection of uncensored and left-censored values.
     |
     |      Examples
     |      --------
     |      >>> from scipy.stats import CensoredData
     |
     |      Two uncensored values (0.12 and 0.033) and two left-censored values
     |      (both 1e-3).
     |
     |      >>> data = CensoredData.left_censored([0.12, 0.033, 1e-3, 1e-3],
     |      ...                                   [False, False, True, True])
     |      >>> data
     |      CensoredData(uncensored=array([0.12 , 0.033]),
     |      left=array([0.001, 0.001]), right=array([], dtype=float64),
     |      interval=array([], shape=(0, 2), dtype=float64))
     |      >>> print(data)
     |      CensoredData(4 values: 2 not censored, 2 left-censored)
     |
     |  right_censored(x, censored)
     |      Create a `CensoredData` instance of right-censored data.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          `x` is the array of observed data or measurements.
     |          `x` must be a one-dimensional sequence of finite numbers.
     |      censored : array_like of bool
     |          `censored` must be a one-dimensional sequence of boolean
     |          values.  If ``censored[k]`` is True, the corresponding value
     |          in `x` is right-censored.  That is, the value ``x[k]``
     |          is the lower bound of the true (but unknown) value.
     |
     |      Returns
     |      -------
     |      data : `CensoredData`
     |          An instance of `CensoredData` that represents the
     |          collection of uncensored and right-censored values.
     |
     |      Examples
     |      --------
     |      >>> from scipy.stats import CensoredData
     |
     |      Two uncensored values (4 and 10) and two right-censored values
     |      (24 and 25).
     |
     |      >>> data = CensoredData.right_censored([4, 10, 24, 25],
     |      ...                                    [False, False, True, True])
     |      >>> data
     |      CensoredData(uncensored=array([ 4., 10.]),
     |      left=array([], dtype=float64), right=array([24., 25.]),
     |      interval=array([], shape=(0, 2), dtype=float64))
     |      >>> print(data)
     |      CensoredData(4 values: 2 not censored, 2 right-censored)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class ConstantInputWarning(DegenerateDataWarning)
     |  ConstantInputWarning(msg=None)
     |
     |  Warns when all values in data are exactly equal.
     |
     |  Method resolution order:
     |      ConstantInputWarning
     |      DegenerateDataWarning
     |      builtins.RuntimeWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, msg=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from DegenerateDataWarning:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class Covariance(builtins.object)
     |  Representation of a covariance matrix
     |
     |  Calculations involving covariance matrices (e.g. data whitening,
     |  multivariate normal function evaluation) are often performed more
     |  efficiently using a decomposition of the covariance matrix instead of the
     |  covariance matrix itself. This class allows the user to construct an
     |  object representing a covariance matrix using any of several
     |  decompositions and perform calculations using a common interface.
     |
     |  .. note::
     |
     |      The `Covariance` class cannot be instantiated directly. Instead, use
     |      one of the factory methods (e.g. `Covariance.from_diagonal`).
     |
     |  Examples
     |  --------
     |  The `Covariance` class is used by calling one of its
     |  factory methods to create a `Covariance` object, then pass that
     |  representation of the `Covariance` matrix as a shape parameter of a
     |  multivariate distribution.
     |
     |  For instance, the multivariate normal distribution can accept an array
     |  representing a covariance matrix:
     |
     |  >>> from scipy import stats
     |  >>> import numpy as np
     |  >>> d = [1, 2, 3]
     |  >>> A = np.diag(d)  # a diagonal covariance matrix
     |  >>> x = [4, -2, 5]  # a point of interest
     |  >>> dist = stats.multivariate_normal(mean=[0, 0, 0], cov=A)
     |  >>> dist.pdf(x)
     |  4.9595685102808205e-08
     |
     |  but the calculations are performed in a very generic way that does not
     |  take advantage of any special properties of the covariance matrix. Because
     |  our covariance matrix is diagonal, we can use ``Covariance.from_diagonal``
     |  to create an object representing the covariance matrix, and
     |  `multivariate_normal` can use this to compute the probability density
     |  function more efficiently.
     |
     |  >>> cov = stats.Covariance.from_diagonal(d)
     |  >>> dist = stats.multivariate_normal(mean=[0, 0, 0], cov=cov)
     |  >>> dist.pdf(x)
     |  4.9595685102808205e-08
     |
     |  Methods defined here:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  colorize(self, x)
     |      Perform a colorizing transformation on data.
     |
     |      "Colorizing" ("color" as in "colored noise", in which different
     |      frequencies may have different magnitudes) transforms a set of
     |      uncorrelated random variables into a new set of random variables with
     |      the desired covariance. When a coloring transform is applied to a
     |      sample of points distributed according to a multivariate normal
     |      distribution with identity covariance and zero mean, the covariance of
     |      the transformed sample is approximately the covariance matrix used
     |      in the coloring transform.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          An array of points. The last dimension must correspond with the
     |          dimensionality of the space, i.e., the number of columns in the
     |          covariance matrix.
     |
     |      Returns
     |      -------
     |      x_ : array_like
     |          The transformed array of points.
     |
     |      References
     |      ----------
     |      .. [1] "Whitening Transformation". Wikipedia.
     |             https://en.wikipedia.org/wiki/Whitening_transformation
     |      .. [2] Novak, Lukas, and Miroslav Vorechovsky. "Generalization of
     |             coloring linear transformation". Transactions of VSB 18.2
     |             (2018): 31-35. :doi:`10.31490/tces-2018-0013`
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng(1638083107694713882823079058616272161)
     |      >>> n = 3
     |      >>> A = rng.random(size=(n, n))
     |      >>> cov_array = A @ A.T  # make matrix symmetric positive definite
     |      >>> cholesky = np.linalg.cholesky(cov_array)
     |      >>> cov_object = stats.Covariance.from_cholesky(cholesky)
     |      >>> x = rng.multivariate_normal(np.zeros(n), np.eye(n), size=(10000))
     |      >>> x_ = cov_object.colorize(x)
     |      >>> cov_data = np.cov(x_, rowvar=False)
     |      >>> np.allclose(cov_data, cov_array, rtol=3e-2)
     |      True
     |
     |  whiten(self, x)
     |      Perform a whitening transformation on data.
     |
     |      "Whitening" ("white" as in "white noise", in which each frequency has
     |      equal magnitude) transforms a set of random variables into a new set of
     |      random variables with unit-diagonal covariance. When a whitening
     |      transform is applied to a sample of points distributed according to
     |      a multivariate normal distribution with zero mean, the covariance of
     |      the transformed sample is approximately the identity matrix.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          An array of points. The last dimension must correspond with the
     |          dimensionality of the space, i.e., the number of columns in the
     |          covariance matrix.
     |
     |      Returns
     |      -------
     |      x_ : array_like
     |          The transformed array of points.
     |
     |      References
     |      ----------
     |      .. [1] "Whitening Transformation". Wikipedia.
     |             https://en.wikipedia.org/wiki/Whitening_transformation
     |      .. [2] Novak, Lukas, and Miroslav Vorechovsky. "Generalization of
     |             coloring linear transformation". Transactions of VSB 18.2
     |             (2018): 31-35. :doi:`10.31490/tces-2018-0013`
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng()
     |      >>> n = 3
     |      >>> A = rng.random(size=(n, n))
     |      >>> cov_array = A @ A.T  # make matrix symmetric positive definite
     |      >>> precision = np.linalg.inv(cov_array)
     |      >>> cov_object = stats.Covariance.from_precision(precision)
     |      >>> x = rng.multivariate_normal(np.zeros(n), cov_array, size=(10000))
     |      >>> x_ = cov_object.whiten(x)
     |      >>> np.cov(x_, rowvar=False)  # near-identity covariance
     |      array([[0.97862122, 0.00893147, 0.02430451],
     |             [0.00893147, 0.96719062, 0.02201312],
     |             [0.02430451, 0.02201312, 0.99206881]])
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  from_cholesky(cholesky)
     |      Representation of a covariance provided via the (lower) Cholesky factor
     |
     |      Parameters
     |      ----------
     |      cholesky : array_like
     |          The lower triangular Cholesky factor of the covariance matrix.
     |
     |      Notes
     |      -----
     |      Let the covariance matrix be :math:`A` and :math:`L` be the lower
     |      Cholesky factor such that :math:`L L^T = A`.
     |      Whitening of a data point :math:`x` is performed by computing
     |      :math:`L^{-1} x`. :math:`\log\det{A}` is calculated as
     |      :math:`2tr(\log{L})`, where the :math:`\log` operation is performed
     |      element-wise.
     |
     |      This `Covariance` class does not support singular covariance matrices
     |      because the Cholesky decomposition does not exist for a singular
     |      covariance matrix.
     |
     |      Examples
     |      --------
     |      Prepare a symmetric positive definite covariance matrix ``A`` and a
     |      data point ``x``.
     |
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng()
     |      >>> n = 5
     |      >>> A = rng.random(size=(n, n))
     |      >>> A = A @ A.T  # make the covariance symmetric positive definite
     |      >>> x = rng.random(size=n)
     |
     |      Perform the Cholesky decomposition of ``A`` and create the
     |      `Covariance` object.
     |
     |      >>> L = np.linalg.cholesky(A)
     |      >>> cov = stats.Covariance.from_cholesky(L)
     |
     |      Compare the functionality of the `Covariance` object against
     |      reference implementation.
     |
     |      >>> from scipy.linalg import solve_triangular
     |      >>> res = cov.whiten(x)
     |      >>> ref = solve_triangular(L, x, lower=True)
     |      >>> np.allclose(res, ref)
     |      True
     |      >>> res = cov.log_pdet
     |      >>> ref = np.linalg.slogdet(A)[-1]
     |      >>> np.allclose(res, ref)
     |      True
     |
     |  from_diagonal(diagonal)
     |      Return a representation of a covariance matrix from its diagonal.
     |
     |      Parameters
     |      ----------
     |      diagonal : array_like
     |          The diagonal elements of a diagonal matrix.
     |
     |      Notes
     |      -----
     |      Let the diagonal elements of a diagonal covariance matrix :math:`D` be
     |      stored in the vector :math:`d`.
     |
     |      When all elements of :math:`d` are strictly positive, whitening of a
     |      data point :math:`x` is performed by computing
     |      :math:`x \cdot d^{-1/2}`, where the inverse square root can be taken
     |      element-wise.
     |      :math:`\log\det{D}` is calculated as :math:`-2 \sum(\log{d})`,
     |      where the :math:`\log` operation is performed element-wise.
     |
     |      This `Covariance` class supports singular covariance matrices. When
     |      computing ``_log_pdet``, non-positive elements of :math:`d` are
     |      ignored. Whitening is not well defined when the point to be whitened
     |      does not lie in the span of the columns of the covariance matrix. The
     |      convention taken here is to treat the inverse square root of
     |      non-positive elements of :math:`d` as zeros.
     |
     |      Examples
     |      --------
     |      Prepare a symmetric positive definite covariance matrix ``A`` and a
     |      data point ``x``.
     |
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng()
     |      >>> n = 5
     |      >>> A = np.diag(rng.random(n))
     |      >>> x = rng.random(size=n)
     |
     |      Extract the diagonal from ``A`` and create the `Covariance` object.
     |
     |      >>> d = np.diag(A)
     |      >>> cov = stats.Covariance.from_diagonal(d)
     |
     |      Compare the functionality of the `Covariance` object against a
     |      reference implementations.
     |
     |      >>> res = cov.whiten(x)
     |      >>> ref = np.diag(d**-0.5) @ x
     |      >>> np.allclose(res, ref)
     |      True
     |      >>> res = cov.log_pdet
     |      >>> ref = np.linalg.slogdet(A)[-1]
     |      >>> np.allclose(res, ref)
     |      True
     |
     |  from_eigendecomposition(eigendecomposition)
     |      Representation of a covariance provided via eigendecomposition
     |
     |      Parameters
     |      ----------
     |      eigendecomposition : sequence
     |          A sequence (nominally a tuple) containing the eigenvalue and
     |          eigenvector arrays as computed by `scipy.linalg.eigh` or
     |          `numpy.linalg.eigh`.
     |
     |      Notes
     |      -----
     |      Let the covariance matrix be :math:`A`, let :math:`V` be matrix of
     |      eigenvectors, and let :math:`W` be the diagonal matrix of eigenvalues
     |      such that `V W V^T = A`.
     |
     |      When all of the eigenvalues are strictly positive, whitening of a
     |      data point :math:`x` is performed by computing
     |      :math:`x^T (V W^{-1/2})`, where the inverse square root can be taken
     |      element-wise.
     |      :math:`\log\det{A}` is calculated as  :math:`tr(\log{W})`,
     |      where the :math:`\log` operation is performed element-wise.
     |
     |      This `Covariance` class supports singular covariance matrices. When
     |      computing ``_log_pdet``, non-positive eigenvalues are ignored.
     |      Whitening is not well defined when the point to be whitened
     |      does not lie in the span of the columns of the covariance matrix. The
     |      convention taken here is to treat the inverse square root of
     |      non-positive eigenvalues as zeros.
     |
     |      Examples
     |      --------
     |      Prepare a symmetric positive definite covariance matrix ``A`` and a
     |      data point ``x``.
     |
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng()
     |      >>> n = 5
     |      >>> A = rng.random(size=(n, n))
     |      >>> A = A @ A.T  # make the covariance symmetric positive definite
     |      >>> x = rng.random(size=n)
     |
     |      Perform the eigendecomposition of ``A`` and create the `Covariance`
     |      object.
     |
     |      >>> w, v = np.linalg.eigh(A)
     |      >>> cov = stats.Covariance.from_eigendecomposition((w, v))
     |
     |      Compare the functionality of the `Covariance` object against
     |      reference implementations.
     |
     |      >>> res = cov.whiten(x)
     |      >>> ref = x @ (v @ np.diag(w**-0.5))
     |      >>> np.allclose(res, ref)
     |      True
     |      >>> res = cov.log_pdet
     |      >>> ref = np.linalg.slogdet(A)[-1]
     |      >>> np.allclose(res, ref)
     |      True
     |
     |  from_precision(precision, covariance=None)
     |      Return a representation of a covariance from its precision matrix.
     |
     |      Parameters
     |      ----------
     |      precision : array_like
     |          The precision matrix; that is, the inverse of a square, symmetric,
     |          positive definite covariance matrix.
     |      covariance : array_like, optional
     |          The square, symmetric, positive definite covariance matrix. If not
     |          provided, this may need to be calculated (e.g. to evaluate the
     |          cumulative distribution function of
     |          `scipy.stats.multivariate_normal`) by inverting `precision`.
     |
     |      Notes
     |      -----
     |      Let the covariance matrix be :math:`A`, its precision matrix be
     |      :math:`P = A^{-1}`, and :math:`L` be the lower Cholesky factor such
     |      that :math:`L L^T = P`.
     |      Whitening of a data point :math:`x` is performed by computing
     |      :math:`x^T L`. :math:`\log\det{A}` is calculated as
     |      :math:`-2tr(\log{L})`, where the :math:`\log` operation is performed
     |      element-wise.
     |
     |      This `Covariance` class does not support singular covariance matrices
     |      because the precision matrix does not exist for a singular covariance
     |      matrix.
     |
     |      Examples
     |      --------
     |      Prepare a symmetric positive definite precision matrix ``P`` and a
     |      data point ``x``. (If the precision matrix is not already available,
     |      consider the other factory methods of the `Covariance` class.)
     |
     |      >>> import numpy as np
     |      >>> from scipy import stats
     |      >>> rng = np.random.default_rng()
     |      >>> n = 5
     |      >>> P = rng.random(size=(n, n))
     |      >>> P = P @ P.T  # a precision matrix must be positive definite
     |      >>> x = rng.random(size=n)
     |
     |      Create the `Covariance` object.
     |
     |      >>> cov = stats.Covariance.from_precision(P)
     |
     |      Compare the functionality of the `Covariance` object against
     |      reference implementations.
     |
     |      >>> res = cov.whiten(x)
     |      >>> ref = x @ np.linalg.cholesky(P)
     |      >>> np.allclose(res, ref)
     |      True
     |      >>> res = cov.log_pdet
     |      >>> ref = -np.linalg.slogdet(P)[-1]
     |      >>> np.allclose(res, ref)
     |      True
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  covariance
     |      Explicit representation of the covariance matrix
     |
     |  log_pdet
     |      Log of the pseudo-determinant of the covariance matrix
     |
     |  rank
     |      Rank of the covariance matrix
     |
     |  shape
     |      Shape of the covariance array
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class DegenerateDataWarning(builtins.RuntimeWarning)
     |  DegenerateDataWarning(msg=None)
     |
     |  Warns when data is degenerate and results may not be reliable.
     |
     |  Method resolution order:
     |      DegenerateDataWarning
     |      builtins.RuntimeWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, msg=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class FitError(builtins.RuntimeError)
     |  FitError(msg=None)
     |
     |  Represents an error condition when fitting a distribution to data.
     |
     |  Method resolution order:
     |      FitError
     |      builtins.RuntimeError
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, msg=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeError:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeError
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class MonteCarloMethod(ResamplingMethod)
     |  MonteCarloMethod(n_resamples: 'int' = 9999, batch: 'int' = None, rvs: 'object' = None) -> None
     |
     |  Configuration information for a Monte Carlo hypothesis test.
     |
     |  Instances of this class can be passed into the `method` parameter of some
     |  hypothesis test functions to perform a Monte Carlo version of the
     |  hypothesis tests.
     |
     |  Attributes
     |  ----------
     |  n_resamples : int, optional
     |      The number of Monte Carlo samples to draw. Default is 9999.
     |  batch : int, optional
     |      The number of Monte Carlo samples to process in each vectorized call to
     |      the statistic. Batch sizes >>1 tend to be faster when the statistic
     |      is vectorized, but memory usage scales linearly with the batch size.
     |      Default is ``None``, which processes all samples in a single batch.
     |  rvs : callable or tuple of callables, optional
     |      A callable or sequence of callables that generates random variates
     |      under the null hypothesis. Each element of `rvs` must be a callable
     |      that accepts keyword argument ``size`` (e.g. ``rvs(size=(m, n))``) and
     |      returns an N-d array sample of that shape. If `rvs` is a sequence, the
     |      number of callables in `rvs` must match the number of samples passed
     |      to the hypothesis test in which the `MonteCarloMethod` is used. Default
     |      is ``None``, in which case the hypothesis test function chooses values
     |      to match the standard version of the hypothesis test. For example,
     |      the null hypothesis of `scipy.stats.pearsonr` is typically that the
     |      samples are drawn from the standard normal distribution, so
     |      ``rvs = (rng.normal, rng.normal)`` where
     |      ``rng = np.random.default_rng()``.
     |
     |  Method resolution order:
     |      MonteCarloMethod
     |      ResamplingMethod
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __init__(self, n_resamples: 'int' = 9999, batch: 'int' = None, rvs: 'object' = None) -> None
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {'rvs': 'object'}
     |
     |  __dataclass_fields__ = {'batch': Field(name='batch',type='int',default...
     |
     |  __dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,or...
     |
     |  __hash__ = None
     |
     |  __match_args__ = ('n_resamples', 'batch', 'rvs')
     |
     |  rvs = None
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from ResamplingMethod:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from ResamplingMethod:
     |
     |  batch = None
     |
     |  n_resamples = 9999

    class NearConstantInputWarning(DegenerateDataWarning)
     |  NearConstantInputWarning(msg=None)
     |
     |  Warns when all values in data are nearly equal.
     |
     |  Method resolution order:
     |      NearConstantInputWarning
     |      DegenerateDataWarning
     |      builtins.RuntimeWarning
     |      builtins.Warning
     |      builtins.Exception
     |      builtins.BaseException
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, msg=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from DegenerateDataWarning:
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from builtins.RuntimeWarning:
     |
     |  __new__(*args, **kwargs) class method of builtins.RuntimeWarning
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.BaseException:
     |
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |
     |  __reduce__(...)
     |      Helper for pickle.
     |
     |  __repr__(self, /)
     |      Return repr(self).
     |
     |  __setstate__(...)
     |
     |  __str__(self, /)
     |      Return str(self).
     |
     |  add_note(...)
     |      Exception.add_note(note) --
     |      add a note to the exception
     |
     |  with_traceback(...)
     |      Exception.with_traceback(tb) --
     |      set self.__traceback__ to tb and return self.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from builtins.BaseException:
     |
     |  __cause__
     |      exception cause
     |
     |  __context__
     |      exception context
     |
     |  __dict__
     |
     |  __suppress_context__
     |
     |  __traceback__
     |
     |  args

    class PermutationMethod(ResamplingMethod)
     |  PermutationMethod(n_resamples: 'int' = 9999, batch: 'int' = None, random_state: 'object' = None) -> None
     |
     |  Configuration information for a permutation hypothesis test.
     |
     |  Instances of this class can be passed into the `method` parameter of some
     |  hypothesis test functions to perform a permutation version of the
     |  hypothesis tests.
     |
     |  Attributes
     |  ----------
     |  n_resamples : int, optional
     |      The number of resamples to perform. Default is 9999.
     |  batch : int, optional
     |      The number of resamples to process in each vectorized call to
     |      the statistic. Batch sizes >>1 tend to be faster when the statistic
     |      is vectorized, but memory usage scales linearly with the batch size.
     |      Default is ``None``, which processes all resamples in a single batch.
     |  random_state : {None, int, `numpy.random.Generator`,
     |                  `numpy.random.RandomState`}, optional
     |
     |      Pseudorandom number generator state used to generate resamples.
     |
     |      If `random_state` is already a ``Generator`` or ``RandomState``
     |      instance, then that instance is used.
     |      If `random_state` is an int, a new ``RandomState`` instance is used,
     |      seeded with `random_state`.
     |      If `random_state` is ``None`` (default), the
     |      `numpy.random.RandomState` singleton is used.
     |
     |  Method resolution order:
     |      PermutationMethod
     |      ResamplingMethod
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __eq__(self, other)
     |      Return self==value.
     |
     |  __init__(self, n_resamples: 'int' = 9999, batch: 'int' = None, random_state: 'object' = None) -> None
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  __repr__(self)
     |      Return repr(self).
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __annotations__ = {'random_state': 'object'}
     |
     |  __dataclass_fields__ = {'batch': Field(name='batch',type='int',default...
     |
     |  __dataclass_params__ = _DataclassParams(init=True,repr=True,eq=True,or...
     |
     |  __hash__ = None
     |
     |  __match_args__ = ('n_resamples', 'batch', 'random_state')
     |
     |  random_state = None
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from ResamplingMethod:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from ResamplingMethod:
     |
     |  batch = None
     |
     |  n_resamples = 9999

    class gaussian_kde(builtins.object)
     |  gaussian_kde(dataset, bw_method=None, weights=None)
     |
     |  Representation of a kernel-density estimate using Gaussian kernels.
     |
     |  Kernel density estimation is a way to estimate the probability density
     |  function (PDF) of a random variable in a non-parametric way.
     |  `gaussian_kde` works for both uni-variate and multi-variate data.   It
     |  includes automatic bandwidth determination.  The estimation works best for
     |  a unimodal distribution; bimodal or multi-modal distributions tend to be
     |  oversmoothed.
     |
     |  Parameters
     |  ----------
     |  dataset : array_like
     |      Datapoints to estimate from. In case of univariate data this is a 1-D
     |      array, otherwise a 2-D array with shape (# of dims, # of data).
     |  bw_method : str, scalar or callable, optional
     |      The method used to calculate the estimator bandwidth.  This can be
     |      'scott', 'silverman', a scalar constant or a callable.  If a scalar,
     |      this will be used directly as `kde.factor`.  If a callable, it should
     |      take a `gaussian_kde` instance as only parameter and return a scalar.
     |      If None (default), 'scott' is used.  See Notes for more details.
     |  weights : array_like, optional
     |      weights of datapoints. This must be the same shape as dataset.
     |      If None (default), the samples are assumed to be equally weighted
     |
     |  Attributes
     |  ----------
     |  dataset : ndarray
     |      The dataset with which `gaussian_kde` was initialized.
     |  d : int
     |      Number of dimensions.
     |  n : int
     |      Number of datapoints.
     |  neff : int
     |      Effective number of datapoints.
     |
     |      .. versionadded:: 1.2.0
     |  factor : float
     |      The bandwidth factor, obtained from `kde.covariance_factor`. The square
     |      of `kde.factor` multiplies the covariance matrix of the data in the kde
     |      estimation.
     |  covariance : ndarray
     |      The covariance matrix of `dataset`, scaled by the calculated bandwidth
     |      (`kde.factor`).
     |  inv_cov : ndarray
     |      The inverse of `covariance`.
     |
     |  Methods
     |  -------
     |  evaluate
     |  __call__
     |  integrate_gaussian
     |  integrate_box_1d
     |  integrate_box
     |  integrate_kde
     |  pdf
     |  logpdf
     |  resample
     |  set_bandwidth
     |  covariance_factor
     |
     |  Notes
     |  -----
     |  Bandwidth selection strongly influences the estimate obtained from the KDE
     |  (much more so than the actual shape of the kernel).  Bandwidth selection
     |  can be done by a "rule of thumb", by cross-validation, by "plug-in
     |  methods" or by other means; see [3]_, [4]_ for reviews.  `gaussian_kde`
     |  uses a rule of thumb, the default is Scott's Rule.
     |
     |  Scott's Rule [1]_, implemented as `scotts_factor`, is::
     |
     |      n**(-1./(d+4)),
     |
     |  with ``n`` the number of data points and ``d`` the number of dimensions.
     |  In the case of unequally weighted points, `scotts_factor` becomes::
     |
     |      neff**(-1./(d+4)),
     |
     |  with ``neff`` the effective number of datapoints.
     |  Silverman's Rule [2]_, implemented as `silverman_factor`, is::
     |
     |      (n * (d + 2) / 4.)**(-1. / (d + 4)).
     |
     |  or in the case of unequally weighted points::
     |
     |      (neff * (d + 2) / 4.)**(-1. / (d + 4)).
     |
     |  Good general descriptions of kernel density estimation can be found in [1]_
     |  and [2]_, the mathematics for this multi-dimensional implementation can be
     |  found in [1]_.
     |
     |  With a set of weighted samples, the effective number of datapoints ``neff``
     |  is defined by::
     |
     |      neff = sum(weights)^2 / sum(weights^2)
     |
     |  as detailed in [5]_.
     |
     |  `gaussian_kde` does not currently support data that lies in a
     |  lower-dimensional subspace of the space in which it is expressed. For such
     |  data, consider performing principle component analysis / dimensionality
     |  reduction and using `gaussian_kde` with the transformed data.
     |
     |  References
     |  ----------
     |  .. [1] D.W. Scott, "Multivariate Density Estimation: Theory, Practice, and
     |         Visualization", John Wiley & Sons, New York, Chicester, 1992.
     |  .. [2] B.W. Silverman, "Density Estimation for Statistics and Data
     |         Analysis", Vol. 26, Monographs on Statistics and Applied Probability,
     |         Chapman and Hall, London, 1986.
     |  .. [3] B.A. Turlach, "Bandwidth Selection in Kernel Density Estimation: A
     |         Review", CORE and Institut de Statistique, Vol. 19, pp. 1-33, 1993.
     |  .. [4] D.M. Bashtannyk and R.J. Hyndman, "Bandwidth selection for kernel
     |         conditional density estimation", Computational Statistics & Data
     |         Analysis, Vol. 36, pp. 279-298, 2001.
     |  .. [5] Gray P. G., 1969, Journal of the Royal Statistical Society.
     |         Series A (General), 132, 272
     |
     |  Examples
     |  --------
     |  Generate some random two-dimensional data:
     |
     |  >>> import numpy as np
     |  >>> from scipy import stats
     |  >>> def measure(n):
     |  ...     "Measurement model, return two coupled measurements."
     |  ...     m1 = np.random.normal(size=n)
     |  ...     m2 = np.random.normal(scale=0.5, size=n)
     |  ...     return m1+m2, m1-m2
     |
     |  >>> m1, m2 = measure(2000)
     |  >>> xmin = m1.min()
     |  >>> xmax = m1.max()
     |  >>> ymin = m2.min()
     |  >>> ymax = m2.max()
     |
     |  Perform a kernel density estimate on the data:
     |
     |  >>> X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
     |  >>> positions = np.vstack([X.ravel(), Y.ravel()])
     |  >>> values = np.vstack([m1, m2])
     |  >>> kernel = stats.gaussian_kde(values)
     |  >>> Z = np.reshape(kernel(positions).T, X.shape)
     |
     |  Plot the results:
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig, ax = plt.subplots()
     |  >>> ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r,
     |  ...           extent=[xmin, xmax, ymin, ymax])
     |  >>> ax.plot(m1, m2, 'k.', markersize=2)
     |  >>> ax.set_xlim([xmin, xmax])
     |  >>> ax.set_ylim([ymin, ymax])
     |  >>> plt.show()
     |
     |  Methods defined here:
     |
     |  __call__ = evaluate(self, points)
     |
     |  __init__(self, dataset, bw_method=None, weights=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  covariance_factor = scotts_factor(self)
     |
     |  evaluate(self, points)
     |      Evaluate the estimated pdf on a set of points.
     |
     |      Parameters
     |      ----------
     |      points : (# of dimensions, # of points)-array
     |          Alternatively, a (# of dimensions,) vector can be passed in and
     |          treated as a single point.
     |
     |      Returns
     |      -------
     |      values : (# of points,)-array
     |          The values at each point.
     |
     |      Raises
     |      ------
     |      ValueError : if the dimensionality of the input points is different than
     |                   the dimensionality of the KDE.
     |
     |  integrate_box(self, low_bounds, high_bounds, maxpts=None)
     |      Computes the integral of a pdf over a rectangular interval.
     |
     |      Parameters
     |      ----------
     |      low_bounds : array_like
     |          A 1-D array containing the lower bounds of integration.
     |      high_bounds : array_like
     |          A 1-D array containing the upper bounds of integration.
     |      maxpts : int, optional
     |          The maximum number of points to use for integration.
     |
     |      Returns
     |      -------
     |      value : scalar
     |          The result of the integral.
     |
     |  integrate_box_1d(self, low, high)
     |      Computes the integral of a 1D pdf between two bounds.
     |
     |      Parameters
     |      ----------
     |      low : scalar
     |          Lower bound of integration.
     |      high : scalar
     |          Upper bound of integration.
     |
     |      Returns
     |      -------
     |      value : scalar
     |          The result of the integral.
     |
     |      Raises
     |      ------
     |      ValueError
     |          If the KDE is over more than one dimension.
     |
     |  integrate_gaussian(self, mean, cov)
     |      Multiply estimated density by a multivariate Gaussian and integrate
     |      over the whole space.
     |
     |      Parameters
     |      ----------
     |      mean : aray_like
     |          A 1-D array, specifying the mean of the Gaussian.
     |      cov : array_like
     |          A 2-D array, specifying the covariance matrix of the Gaussian.
     |
     |      Returns
     |      -------
     |      result : scalar
     |          The value of the integral.
     |
     |      Raises
     |      ------
     |      ValueError
     |          If the mean or covariance of the input Gaussian differs from
     |          the KDE's dimensionality.
     |
     |  integrate_kde(self, other)
     |      Computes the integral of the product of this  kernel density estimate
     |      with another.
     |
     |      Parameters
     |      ----------
     |      other : gaussian_kde instance
     |          The other kde.
     |
     |      Returns
     |      -------
     |      value : scalar
     |          The result of the integral.
     |
     |      Raises
     |      ------
     |      ValueError
     |          If the KDEs have different dimensionality.
     |
     |  logpdf(self, x)
     |      Evaluate the log of the estimated pdf on a provided set of points.
     |
     |  marginal(self, dimensions)
     |      Return a marginal KDE distribution
     |
     |      Parameters
     |      ----------
     |      dimensions : int or 1-d array_like
     |          The dimensions of the multivariate distribution corresponding
     |          with the marginal variables, that is, the indices of the dimensions
     |          that are being retained. The other dimensions are marginalized out.
     |
     |      Returns
     |      -------
     |      marginal_kde : gaussian_kde
     |          An object representing the marginal distribution.
     |
     |      Notes
     |      -----
     |      .. versionadded:: 1.10.0
     |
     |  pdf(self, x)
     |      Evaluate the estimated pdf on a provided set of points.
     |
     |      Notes
     |      -----
     |      This is an alias for `gaussian_kde.evaluate`.  See the ``evaluate``
     |      docstring for more details.
     |
     |  resample(self, size=None, seed=None)
     |      Randomly sample a dataset from the estimated pdf.
     |
     |      Parameters
     |      ----------
     |      size : int, optional
     |          The number of samples to draw.  If not provided, then the size is
     |          the same as the effective number of samples in the underlying
     |          dataset.
     |      seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
     |          If `seed` is None (or `np.random`), the `numpy.random.RandomState`
     |          singleton is used.
     |          If `seed` is an int, a new ``RandomState`` instance is used,
     |          seeded with `seed`.
     |          If `seed` is already a ``Generator`` or ``RandomState`` instance then
     |          that instance is used.
     |
     |      Returns
     |      -------
     |      resample : (self.d, `size`) ndarray
     |          The sampled dataset.
     |
     |  scotts_factor(self)
     |      Computes the coefficient (`kde.factor`) that
     |      multiplies the data covariance matrix to obtain the kernel covariance
     |      matrix. The default is `scotts_factor`.  A subclass can overwrite this
     |      method to provide a different method, or set it through a call to
     |      `kde.set_bandwidth`.
     |
     |  set_bandwidth(self, bw_method=None)
     |      Compute the estimator bandwidth with given method.
     |
     |      The new bandwidth calculated after a call to `set_bandwidth` is used
     |      for subsequent evaluations of the estimated density.
     |
     |      Parameters
     |      ----------
     |      bw_method : str, scalar or callable, optional
     |          The method used to calculate the estimator bandwidth.  This can be
     |          'scott', 'silverman', a scalar constant or a callable.  If a
     |          scalar, this will be used directly as `kde.factor`.  If a callable,
     |          it should take a `gaussian_kde` instance as only parameter and
     |          return a scalar.  If None (default), nothing happens; the current
     |          `kde.covariance_factor` method is kept.
     |
     |      Notes
     |      -----
     |      .. versionadded:: 0.11
     |
     |      Examples
     |      --------
     |      >>> import numpy as np
     |      >>> import scipy.stats as stats
     |      >>> x1 = np.array([-7, -5, 1, 4, 5.])
     |      >>> kde = stats.gaussian_kde(x1)
     |      >>> xs = np.linspace(-10, 10, num=50)
     |      >>> y1 = kde(xs)
     |      >>> kde.set_bandwidth(bw_method='silverman')
     |      >>> y2 = kde(xs)
     |      >>> kde.set_bandwidth(bw_method=kde.factor / 3.)
     |      >>> y3 = kde(xs)
     |
     |      >>> import matplotlib.pyplot as plt
     |      >>> fig, ax = plt.subplots()
     |      >>> ax.plot(x1, np.full(x1.shape, 1 / (4. * x1.size)), 'bo',
     |      ...         label='Data points (rescaled)')
     |      >>> ax.plot(xs, y1, label='Scott (default)')
     |      >>> ax.plot(xs, y2, label='Silverman')
     |      >>> ax.plot(xs, y3, label='Const (1/3 * Silverman)')
     |      >>> ax.legend()
     |      >>> plt.show()
     |
     |  silverman_factor(self)
     |      Compute the Silverman factor.
     |
     |      Returns
     |      -------
     |      s : float
     |          The silverman factor.
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  inv_cov
     |
     |  neff
     |
     |  weights
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object

    class rv_continuous(rv_generic)
     |  rv_continuous(momtype=1, a=None, b=None, xtol=1e-14, badvalue=None, name=None, longname=None, shapes=None, seed=None)
     |
     |  A generic continuous random variable class meant for subclassing.
     |
     |  `rv_continuous` is a base class to construct specific distribution classes
     |  and instances for continuous random variables. It cannot be used
     |  directly as a distribution.
     |
     |  Parameters
     |  ----------
     |  momtype : int, optional
     |      The type of generic moment calculation to use: 0 for pdf, 1 (default)
     |      for ppf.
     |  a : float, optional
     |      Lower bound of the support of the distribution, default is minus
     |      infinity.
     |  b : float, optional
     |      Upper bound of the support of the distribution, default is plus
     |      infinity.
     |  xtol : float, optional
     |      The tolerance for fixed point calculation for generic ppf.
     |  badvalue : float, optional
     |      The value in a result arrays that indicates a value that for which
     |      some argument restriction is violated, default is np.nan.
     |  name : str, optional
     |      The name of the instance. This string is used to construct the default
     |      example for distributions.
     |  longname : str, optional
     |      This string is used as part of the first line of the docstring returned
     |      when a subclass has no docstring of its own. Note: `longname` exists
     |      for backwards compatibility, do not use for new subclasses.
     |  shapes : str, optional
     |      The shape of the distribution. For example ``"m, n"`` for a
     |      distribution that takes two integers as the two shape arguments for all
     |      its methods. If not provided, shape parameters will be inferred from
     |      the signature of the private methods, ``_pdf`` and ``_cdf`` of the
     |      instance.
     |  seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
     |      If `seed` is None (or `np.random`), the `numpy.random.RandomState`
     |      singleton is used.
     |      If `seed` is an int, a new ``RandomState`` instance is used,
     |      seeded with `seed`.
     |      If `seed` is already a ``Generator`` or ``RandomState`` instance then
     |      that instance is used.
     |
     |  Methods
     |  -------
     |  rvs
     |  pdf
     |  logpdf
     |  cdf
     |  logcdf
     |  sf
     |  logsf
     |  ppf
     |  isf
     |  moment
     |  stats
     |  entropy
     |  expect
     |  median
     |  mean
     |  std
     |  var
     |  interval
     |  __call__
     |  fit
     |  fit_loc_scale
     |  nnlf
     |  support
     |
     |  Notes
     |  -----
     |  Public methods of an instance of a distribution class (e.g., ``pdf``,
     |  ``cdf``) check their arguments and pass valid arguments to private,
     |  computational methods (``_pdf``, ``_cdf``). For ``pdf(x)``, ``x`` is valid
     |  if it is within the support of the distribution.
     |  Whether a shape parameter is valid is decided by an ``_argcheck`` method
     |  (which defaults to checking that its arguments are strictly positive.)
     |
     |  **Subclassing**
     |
     |  New random variables can be defined by subclassing the `rv_continuous` class
     |  and re-defining at least the ``_pdf`` or the ``_cdf`` method (normalized
     |  to location 0 and scale 1).
     |
     |  If positive argument checking is not correct for your RV
     |  then you will also need to re-define the ``_argcheck`` method.
     |
     |  For most of the scipy.stats distributions, the support interval doesn't
     |  depend on the shape parameters. ``x`` being in the support interval is
     |  equivalent to ``self.a <= x <= self.b``.  If either of the endpoints of
     |  the support do depend on the shape parameters, then
     |  i) the distribution must implement the ``_get_support`` method; and
     |  ii) those dependent endpoints must be omitted from the distribution's
     |  call to the ``rv_continuous`` initializer.
     |
     |  Correct, but potentially slow defaults exist for the remaining
     |  methods but for speed and/or accuracy you can over-ride::
     |
     |    _logpdf, _cdf, _logcdf, _ppf, _rvs, _isf, _sf, _logsf
     |
     |  The default method ``_rvs`` relies on the inverse of the cdf, ``_ppf``,
     |  applied to a uniform random variate. In order to generate random variates
     |  efficiently, either the default ``_ppf`` needs to be overwritten (e.g.
     |  if the inverse cdf can expressed in an explicit form) or a sampling
     |  method needs to be implemented in a custom ``_rvs`` method.
     |
     |  If possible, you should override ``_isf``, ``_sf`` or ``_logsf``.
     |  The main reason would be to improve numerical accuracy: for example,
     |  the survival function ``_sf`` is computed as ``1 - _cdf`` which can
     |  result in loss of precision if ``_cdf(x)`` is close to one.
     |
     |  **Methods that can be overwritten by subclasses**
     |  ::
     |
     |    _rvs
     |    _pdf
     |    _cdf
     |    _sf
     |    _ppf
     |    _isf
     |    _stats
     |    _munp
     |    _entropy
     |    _argcheck
     |    _get_support
     |
     |  There are additional (internal and private) generic methods that can
     |  be useful for cross-checking and for debugging, but might work in all
     |  cases when directly called.
     |
     |  A note on ``shapes``: subclasses need not specify them explicitly. In this
     |  case, `shapes` will be automatically deduced from the signatures of the
     |  overridden methods (`pdf`, `cdf` etc).
     |  If, for some reason, you prefer to avoid relying on introspection, you can
     |  specify ``shapes`` explicitly as an argument to the instance constructor.
     |
     |
     |  **Frozen Distributions**
     |
     |  Normally, you must provide shape parameters (and, optionally, location and
     |  scale parameters to each call of a method of a distribution.
     |
     |  Alternatively, the object may be called (as a function) to fix the shape,
     |  location, and scale parameters returning a "frozen" continuous RV object:
     |
     |  rv = generic(<shape(s)>, loc=0, scale=1)
     |      `rv_frozen` object with the same methods but holding the given shape,
     |      location, and scale fixed
     |
     |  **Statistics**
     |
     |  Statistics are computed using numerical integration by default.
     |  For speed you can redefine this using ``_stats``:
     |
     |   - take shape parameters and return mu, mu2, g1, g2
     |   - If you can't compute one of these, return it as None
     |   - Can also be defined with a keyword argument ``moments``, which is a
     |     string composed of "m", "v", "s", and/or "k".
     |     Only the components appearing in string should be computed and
     |     returned in the order "m", "v", "s", or "k"  with missing values
     |     returned as None.
     |
     |  Alternatively, you can override ``_munp``, which takes ``n`` and shape
     |  parameters and returns the n-th non-central moment of the distribution.
     |
     |  **Deepcopying / Pickling**
     |
     |  If a distribution or frozen distribution is deepcopied (pickled/unpickled,
     |  etc.), any underlying random number generator is deepcopied with it. An
     |  implication is that if a distribution relies on the singleton RandomState
     |  before copying, it will rely on a copy of that random state after copying,
     |  and ``np.random.seed`` will no longer control the state.
     |
     |  Examples
     |  --------
     |  To create a new Gaussian distribution, we would do the following:
     |
     |  >>> from scipy.stats import rv_continuous
     |  >>> class gaussian_gen(rv_continuous):
     |  ...     "Gaussian distribution"
     |  ...     def _pdf(self, x):
     |  ...         return np.exp(-x**2 / 2.) / np.sqrt(2.0 * np.pi)
     |  >>> gaussian = gaussian_gen(name='gaussian')
     |
     |  ``scipy.stats`` distributions are *instances*, so here we subclass
     |  `rv_continuous` and create an instance. With this, we now have
     |  a fully functional distribution with all relevant methods automagically
     |  generated by the framework.
     |
     |  Note that above we defined a standard normal distribution, with zero mean
     |  and unit variance. Shifting and scaling of the distribution can be done
     |  by using ``loc`` and ``scale`` parameters: ``gaussian.pdf(x, loc, scale)``
     |  essentially computes ``y = (x - loc) / scale`` and
     |  ``gaussian._pdf(y) / scale``.
     |
     |  Method resolution order:
     |      rv_continuous
     |      rv_generic
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __getstate__(self)
     |      Helper for pickle.
     |
     |  __init__(self, momtype=1, a=None, b=None, xtol=1e-14, badvalue=None, name=None, longname=None, shapes=None, seed=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  cdf(self, x, *args, **kwds)
     |      Cumulative distribution function of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      cdf : ndarray
     |          Cumulative distribution function evaluated at `x`
     |
     |  expect(self, func=None, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
     |      Calculate expected value of a function with respect to the
     |      distribution by numerical integration.
     |
     |      The expected value of a function ``f(x)`` with respect to a
     |      distribution ``dist`` is defined as::
     |
     |                  ub
     |          E[f(x)] = Integral(f(x) * dist.pdf(x)),
     |                  lb
     |
     |      where ``ub`` and ``lb`` are arguments and ``x`` has the ``dist.pdf(x)``
     |      distribution. If the bounds ``lb`` and ``ub`` correspond to the
     |      support of the distribution, e.g. ``[-inf, inf]`` in the default
     |      case, then the integral is the unrestricted expectation of ``f(x)``.
     |      Also, the function ``f(x)`` may be defined such that ``f(x)`` is ``0``
     |      outside a finite interval in which case the expectation is
     |      calculated within the finite range ``[lb, ub]``.
     |
     |      Parameters
     |      ----------
     |      func : callable, optional
     |          Function for which integral is calculated. Takes only one argument.
     |          The default is the identity mapping f(x) = x.
     |      args : tuple, optional
     |          Shape parameters of the distribution.
     |      loc : float, optional
     |          Location parameter (default=0).
     |      scale : float, optional
     |          Scale parameter (default=1).
     |      lb, ub : scalar, optional
     |          Lower and upper bound for integration. Default is set to the
     |          support of the distribution.
     |      conditional : bool, optional
     |          If True, the integral is corrected by the conditional probability
     |          of the integration interval.  The return value is the expectation
     |          of the function, conditional on being in the given interval.
     |          Default is False.
     |
     |      Additional keyword arguments are passed to the integration routine.
     |
     |      Returns
     |      -------
     |      expect : float
     |          The calculated expected value.
     |
     |      Notes
     |      -----
     |      The integration behavior of this function is inherited from
     |      `scipy.integrate.quad`. Neither this function nor
     |      `scipy.integrate.quad` can verify whether the integral exists or is
     |      finite. For example ``cauchy(0).mean()`` returns ``np.nan`` and
     |      ``cauchy(0).expect()`` returns ``0.0``.
     |
     |      Likewise, the accuracy of results is not verified by the function.
     |      `scipy.integrate.quad` is typically reliable for integrals that are
     |      numerically favorable, but it is not guaranteed to converge
     |      to a correct value for all possible intervals and integrands. This
     |      function is provided for convenience; for critical applications,
     |      check results against other integration methods.
     |
     |      The function is not vectorized.
     |
     |      Examples
     |      --------
     |
     |      To understand the effect of the bounds of integration consider
     |
     |      >>> from scipy.stats import expon
     |      >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0)
     |      0.6321205588285578
     |
     |      This is close to
     |
     |      >>> expon(1).cdf(2.0) - expon(1).cdf(0.0)
     |      0.6321205588285577
     |
     |      If ``conditional=True``
     |
     |      >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0, conditional=True)
     |      1.0000000000000002
     |
     |      The slight deviation from 1 is due to numerical integration.
     |
     |      The integrand can be treated as a complex-valued function
     |      by passing ``complex_func=True`` to `scipy.integrate.quad` .
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats import vonmises
     |      >>> res = vonmises(loc=2, kappa=1).expect(lambda x: np.exp(1j*x),
     |      ...                                       complex_func=True)
     |      >>> res
     |      (-0.18576377217422957+0.40590124735052263j)
     |
     |      >>> np.angle(res)  # location of the (circular) distribution
     |      2.0
     |
     |  fit(self, data, *args, **kwds)
     |      Return estimates of shape (if applicable), location, and scale
     |      parameters from data. The default estimation method is Maximum
     |      Likelihood Estimation (MLE), but Method of Moments (MM)
     |      is also available.
     |
     |      Starting estimates for the fit are given by input arguments;
     |      for any arguments not provided with starting estimates,
     |      ``self._fitstart(data)`` is called to generate such.
     |
     |      One can hold some parameters fixed to specific values by passing in
     |      keyword arguments ``f0``, ``f1``, ..., ``fn`` (for shape parameters)
     |      and ``floc`` and ``fscale`` (for location and scale parameters,
     |      respectively).
     |
     |      Parameters
     |      ----------
     |      data : array_like or `CensoredData` instance
     |          Data to use in estimating the distribution parameters.
     |      arg1, arg2, arg3,... : floats, optional
     |          Starting value(s) for any shape-characterizing arguments (those not
     |          provided will be determined by a call to ``_fitstart(data)``).
     |          No default value.
     |      **kwds : floats, optional
     |          - `loc`: initial guess of the distribution's location parameter.
     |          - `scale`: initial guess of the distribution's scale parameter.
     |
     |          Special keyword arguments are recognized as holding certain
     |          parameters fixed:
     |
     |          - f0...fn : hold respective shape parameters fixed.
     |            Alternatively, shape parameters to fix can be specified by name.
     |            For example, if ``self.shapes == "a, b"``, ``fa`` and ``fix_a``
     |            are equivalent to ``f0``, and ``fb`` and ``fix_b`` are
     |            equivalent to ``f1``.
     |
     |          - floc : hold location parameter fixed to specified value.
     |
     |          - fscale : hold scale parameter fixed to specified value.
     |
     |          - optimizer : The optimizer to use.  The optimizer must take
     |            ``func`` and starting position as the first two arguments,
     |            plus ``args`` (for extra arguments to pass to the
     |            function to be optimized) and ``disp``.
     |            The ``fit`` method calls the optimizer with ``disp=0`` to suppress output.
     |            The optimizer must return the estimated parameters.
     |
     |          - method : The method to use. The default is "MLE" (Maximum
     |            Likelihood Estimate); "MM" (Method of Moments)
     |            is also available.
     |
     |      Raises
     |      ------
     |      TypeError, ValueError
     |          If an input is invalid
     |      `~scipy.stats.FitError`
     |          If fitting fails or the fit produced would be invalid
     |
     |      Returns
     |      -------
     |      parameter_tuple : tuple of floats
     |          Estimates for any shape parameters (if applicable), followed by
     |          those for location and scale. For most random variables, shape
     |          statistics will be returned, but there are exceptions (e.g.
     |          ``norm``).
     |
     |      Notes
     |      -----
     |      With ``method="MLE"`` (default), the fit is computed by minimizing
     |      the negative log-likelihood function. A large, finite penalty
     |      (rather than infinite negative log-likelihood) is applied for
     |      observations beyond the support of the distribution.
     |
     |      With ``method="MM"``, the fit is computed by minimizing the L2 norm
     |      of the relative errors between the first *k* raw (about zero) data
     |      moments and the corresponding distribution moments, where *k* is the
     |      number of non-fixed parameters.
     |      More precisely, the objective function is::
     |
     |          (((data_moments - dist_moments)
     |            / np.maximum(np.abs(data_moments), 1e-8))**2).sum()
     |
     |      where the constant ``1e-8`` avoids division by zero in case of
     |      vanishing data moments. Typically, this error norm can be reduced to
     |      zero.
     |      Note that the standard method of moments can produce parameters for
     |      which some data are outside the support of the fitted distribution;
     |      this implementation does nothing to prevent this.
     |
     |      For either method,
     |      the returned answer is not guaranteed to be globally optimal; it
     |      may only be locally optimal, or the optimization may fail altogether.
     |      If the data contain any of ``np.nan``, ``np.inf``, or ``-np.inf``,
     |      the `fit` method will raise a ``RuntimeError``.
     |
     |      When passing a ``CensoredData`` instance to ``data``, the log-likelihood
     |      function is defined as:
     |
     |      .. math::
     |
     |          l(\pmb{\theta}; k) & = \sum
     |                                  \log(f(k_u; \pmb{\theta}))
     |                              + \sum
     |                                  \log(F(k_l; \pmb{\theta})) \\
     |                              & + \sum
     |                                  \log(1 - F(k_r; \pmb{\theta})) \\
     |                              & + \sum
     |                                  \log(F(k_{\text{high}, i}; \pmb{\theta})
     |                                  - F(k_{\text{low}, i}; \pmb{\theta}))
     |
     |      where :math:`f` and :math:`F` are the pdf and cdf, respectively, of the
     |      function being fitted, :math:`\pmb{\theta}` is the parameter vector,
     |      :math:`u` are the indices of uncensored observations,
     |      :math:`l` are the indices of left-censored observations,
     |      :math:`r` are the indices of right-censored observations,
     |      subscripts "low"/"high" denote endpoints of interval-censored observations, and
     |      :math:`i` are the indices of interval-censored observations.
     |
     |      Examples
     |      --------
     |
     |      Generate some data to fit: draw random variates from the `beta`
     |      distribution
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats import beta
     |      >>> a, b = 1., 2.
     |      >>> rng = np.random.default_rng(172786373191770012695001057628748821561)
     |      >>> x = beta.rvs(a, b, size=1000, random_state=rng)
     |
     |      Now we can fit all four parameters (``a``, ``b``, ``loc`` and
     |      ``scale``):
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x)
     |      >>> a1, b1, loc1, scale1
     |      (1.0198945204435628, 1.9484708982737828, 4.372241314917588e-05, 0.9979078845964814)
     |
     |      The fit can be done also using a custom optimizer:
     |
     |      >>> from scipy.optimize import minimize
     |      >>> def custom_optimizer(func, x0, args=(), disp=0):
     |      ...     res = minimize(func, x0, args, method="slsqp", options={"disp": disp})
     |      ...     if res.success:
     |      ...         return res.x
     |      ...     raise RuntimeError('optimization routine failed')
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, method="MLE", optimizer=custom_optimizer)
     |      >>> a1, b1, loc1, scale1
     |      (1.0198821087258905, 1.948484145914738, 4.3705304486881485e-05, 0.9979104663953395)
     |
     |      We can also use some prior knowledge about the dataset: let's keep
     |      ``loc`` and ``scale`` fixed:
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, floc=0, fscale=1)
     |      >>> loc1, scale1
     |      (0, 1)
     |
     |      We can also keep shape parameters fixed by using ``f``-keywords. To
     |      keep the zero-th shape parameter ``a`` equal 1, use ``f0=1`` or,
     |      equivalently, ``fa=1``:
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, fa=1, floc=0, fscale=1)
     |      >>> a1
     |      1
     |
     |      Not all distributions return estimates for the shape parameters.
     |      ``norm`` for example just returns estimates for location and scale:
     |
     |      >>> from scipy.stats import norm
     |      >>> x = norm.rvs(a, b, size=1000, random_state=123)
     |      >>> loc1, scale1 = norm.fit(x)
     |      >>> loc1, scale1
     |      (0.92087172783841631, 2.0015750750324668)
     |
     |  fit_loc_scale(self, data, *args)
     |      Estimate loc and scale parameters from data using 1st and 2nd moments.
     |
     |      Parameters
     |      ----------
     |      data : array_like
     |          Data to fit.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |
     |      Returns
     |      -------
     |      Lhat : float
     |          Estimated location parameter for the data.
     |      Shat : float
     |          Estimated scale parameter for the data.
     |
     |  isf(self, q, *args, **kwds)
     |      Inverse survival function (inverse of `sf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          upper tail probability
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      x : ndarray or scalar
     |          Quantile corresponding to the upper tail probability q.
     |
     |  logcdf(self, x, *args, **kwds)
     |      Log of the cumulative distribution function at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logcdf : array_like
     |          Log of the cumulative distribution function evaluated at x
     |
     |  logpdf(self, x, *args, **kwds)
     |      Log of the probability density function at x of the given RV.
     |
     |      This uses a more numerically accurate calculation if available.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logpdf : array_like
     |          Log of the probability density function evaluated at x
     |
     |  logsf(self, x, *args, **kwds)
     |      Log of the survival function of the given RV.
     |
     |      Returns the log of the "survival function," defined as (1 - `cdf`),
     |      evaluated at `x`.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logsf : ndarray
     |          Log of the survival function evaluated at `x`.
     |
     |  pdf(self, x, *args, **kwds)
     |      Probability density function at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      pdf : ndarray
     |          Probability density function evaluated at x
     |
     |  ppf(self, q, *args, **kwds)
     |      Percent point function (inverse of `cdf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          lower tail probability
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      x : array_like
     |          quantile corresponding to the lower tail probability q.
     |
     |  sf(self, x, *args, **kwds)
     |      Survival function (1 - `cdf`) at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      sf : array_like
     |          Survival function evaluated at x
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from rv_generic:
     |
     |  __call__(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  __setstate__(self, state)
     |
     |  entropy(self, *args, **kwds)
     |      Differential entropy of the RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      scale : array_like, optional  (continuous distributions only).
     |          Scale parameter (default=1).
     |
     |      Notes
     |      -----
     |      Entropy is defined base `e`:
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats._distn_infrastructure import rv_discrete
     |      >>> drv = rv_discrete(values=((0, 1), (0.5, 0.5)))
     |      >>> np.allclose(drv.entropy(), np.log(2.0))
     |      True
     |
     |  freeze(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  interval(self, confidence, *args, **kwds)
     |      Confidence interval with equal areas around the median.
     |
     |      Parameters
     |      ----------
     |      confidence : array_like of float
     |          Probability that an rv will be drawn from the returned range.
     |          Each value should be in the range [0, 1].
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : ndarray of float
     |          end-points of range that contain ``100 * alpha %`` of the rv's
     |          possible values.
     |
     |      Notes
     |      -----
     |      This is implemented as ``ppf([p_tail, 1-p_tail])``, where
     |      ``ppf`` is the inverse cumulative distribution function and
     |      ``p_tail = (1-confidence)/2``. Suppose ``[c, d]`` is the support of a
     |      discrete distribution; then ``ppf([0, 1]) == (c-1, d)``. Therefore,
     |      when ``confidence=1`` and the distribution is discrete, the left end
     |      of the interval will be beyond the support of the distribution.
     |      For discrete distributions, the interval will limit the probability
     |      in each tail to be less than or equal to ``p_tail`` (usually
     |      strictly less).
     |
     |  mean(self, *args, **kwds)
     |      Mean of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      mean : float
     |          the mean of the distribution
     |
     |  median(self, *args, **kwds)
     |      Median of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          Location parameter, Default is 0.
     |      scale : array_like, optional
     |          Scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      median : float
     |          The median of the distribution.
     |
     |      See Also
     |      --------
     |      rv_discrete.ppf
     |          Inverse of the CDF
     |
     |  moment(self, order, *args, **kwds)
     |      non-central moment of distribution of specified order.
     |
     |      Parameters
     |      ----------
     |      order : int, order >= 1
     |          Order of moment.
     |      arg1, arg2, arg3,... : float
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |  nnlf(self, theta, x)
     |      Negative loglikelihood function.
     |      Notes
     |      -----
     |      This is ``-sum(log pdf(x, theta), axis=0)`` where `theta` are the
     |      parameters (including loc and scale).
     |
     |  rvs(self, *args, **kwds)
     |      Random variates of given type.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      scale : array_like, optional
     |          Scale parameter (default=1).
     |      size : int or tuple of ints, optional
     |          Defining number of random variates (default is 1).
     |      random_state : {None, int, `numpy.random.Generator`,
     |                      `numpy.random.RandomState`}, optional
     |
     |          If `random_state` is None (or `np.random`), the
     |          `numpy.random.RandomState` singleton is used.
     |          If `random_state` is an int, a new ``RandomState`` instance is
     |          used, seeded with `random_state`.
     |          If `random_state` is already a ``Generator`` or ``RandomState``
     |          instance, that instance is used.
     |
     |      Returns
     |      -------
     |      rvs : ndarray or scalar
     |          Random variates of given `size`.
     |
     |  stats(self, *args, **kwds)
     |      Some statistics of the given RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional (continuous RVs only)
     |          scale parameter (default=1)
     |      moments : str, optional
     |          composed of letters ['mvsk'] defining which moments to compute:
     |          'm' = mean,
     |          'v' = variance,
     |          's' = (Fisher's) skew,
     |          'k' = (Fisher's) kurtosis.
     |          (default is 'mv')
     |
     |      Returns
     |      -------
     |      stats : sequence
     |          of requested moments.
     |
     |  std(self, *args, **kwds)
     |      Standard deviation of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      std : float
     |          standard deviation of the distribution
     |
     |  support(self, *args, **kwargs)
     |      Support of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : array_like
     |          end-points of the distribution's support.
     |
     |  var(self, *args, **kwds)
     |      Variance of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      var : float
     |          the variance of the distribution
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from rv_generic:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  random_state
     |      Get or set the generator object for generating random variates.
     |
     |      If `random_state` is None (or `np.random`), the
     |      `numpy.random.RandomState` singleton is used.
     |      If `random_state` is an int, a new ``RandomState`` instance is used,
     |      seeded with `random_state`.
     |      If `random_state` is already a ``Generator`` or ``RandomState``
     |      instance, that instance is used.

    class rv_discrete(rv_generic)
     |  rv_discrete(a=0, b=inf, name=None, badvalue=None, moment_tol=1e-08, values=None, inc=1, longname=None, shapes=None, seed=None)
     |
     |  A generic discrete random variable class meant for subclassing.
     |
     |  `rv_discrete` is a base class to construct specific distribution classes
     |  and instances for discrete random variables. It can also be used
     |  to construct an arbitrary distribution defined by a list of support
     |  points and corresponding probabilities.
     |
     |  Parameters
     |  ----------
     |  a : float, optional
     |      Lower bound of the support of the distribution, default: 0
     |  b : float, optional
     |      Upper bound of the support of the distribution, default: plus infinity
     |  moment_tol : float, optional
     |      The tolerance for the generic calculation of moments.
     |  values : tuple of two array_like, optional
     |      ``(xk, pk)`` where ``xk`` are integers and ``pk`` are the non-zero
     |      probabilities between 0 and 1 with ``sum(pk) = 1``. ``xk``
     |      and ``pk`` must have the same shape, and ``xk`` must be unique.
     |  inc : integer, optional
     |      Increment for the support of the distribution.
     |      Default is 1. (other values have not been tested)
     |  badvalue : float, optional
     |      The value in a result arrays that indicates a value that for which
     |      some argument restriction is violated, default is np.nan.
     |  name : str, optional
     |      The name of the instance. This string is used to construct the default
     |      example for distributions.
     |  longname : str, optional
     |      This string is used as part of the first line of the docstring returned
     |      when a subclass has no docstring of its own. Note: `longname` exists
     |      for backwards compatibility, do not use for new subclasses.
     |  shapes : str, optional
     |      The shape of the distribution. For example "m, n" for a distribution
     |      that takes two integers as the two shape arguments for all its methods
     |      If not provided, shape parameters will be inferred from
     |      the signatures of the private methods, ``_pmf`` and ``_cdf`` of
     |      the instance.
     |  seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional
     |      If `seed` is None (or `np.random`), the `numpy.random.RandomState`
     |      singleton is used.
     |      If `seed` is an int, a new ``RandomState`` instance is used,
     |      seeded with `seed`.
     |      If `seed` is already a ``Generator`` or ``RandomState`` instance then
     |      that instance is used.
     |
     |  Methods
     |  -------
     |  rvs
     |  pmf
     |  logpmf
     |  cdf
     |  logcdf
     |  sf
     |  logsf
     |  ppf
     |  isf
     |  moment
     |  stats
     |  entropy
     |  expect
     |  median
     |  mean
     |  std
     |  var
     |  interval
     |  __call__
     |  support
     |
     |  Notes
     |  -----
     |  This class is similar to `rv_continuous`. Whether a shape parameter is
     |  valid is decided by an ``_argcheck`` method (which defaults to checking
     |  that its arguments are strictly positive.)
     |  The main differences are as follows.
     |
     |  - The support of the distribution is a set of integers.
     |  - Instead of the probability density function, ``pdf`` (and the
     |    corresponding private ``_pdf``), this class defines the
     |    *probability mass function*, `pmf` (and the corresponding
     |    private ``_pmf``.)
     |  - There is no ``scale`` parameter.
     |  - The default implementations of methods (e.g. ``_cdf``) are not designed
     |    for distributions with support that is unbounded below (i.e.
     |    ``a=-np.inf``), so they must be overridden.
     |
     |  To create a new discrete distribution, we would do the following:
     |
     |  >>> from scipy.stats import rv_discrete
     |  >>> class poisson_gen(rv_discrete):
     |  ...     "Poisson distribution"
     |  ...     def _pmf(self, k, mu):
     |  ...         return exp(-mu) * mu**k / factorial(k)
     |
     |  and create an instance::
     |
     |  >>> poisson = poisson_gen(name="poisson")
     |
     |  Note that above we defined the Poisson distribution in the standard form.
     |  Shifting the distribution can be done by providing the ``loc`` parameter
     |  to the methods of the instance. For example, ``poisson.pmf(x, mu, loc)``
     |  delegates the work to ``poisson._pmf(x-loc, mu)``.
     |
     |  **Discrete distributions from a list of probabilities**
     |
     |  Alternatively, you can construct an arbitrary discrete rv defined
     |  on a finite set of values ``xk`` with ``Prob{X=xk} = pk`` by using the
     |  ``values`` keyword argument to the `rv_discrete` constructor.
     |
     |  **Deepcopying / Pickling**
     |
     |  If a distribution or frozen distribution is deepcopied (pickled/unpickled,
     |  etc.), any underlying random number generator is deepcopied with it. An
     |  implication is that if a distribution relies on the singleton RandomState
     |  before copying, it will rely on a copy of that random state after copying,
     |  and ``np.random.seed`` will no longer control the state.
     |
     |  Examples
     |  --------
     |  Custom made discrete distribution:
     |
     |  >>> import numpy as np
     |  >>> from scipy import stats
     |  >>> xk = np.arange(7)
     |  >>> pk = (0.1, 0.2, 0.3, 0.1, 0.1, 0.0, 0.2)
     |  >>> custm = stats.rv_discrete(name='custm', values=(xk, pk))
     |  >>>
     |  >>> import matplotlib.pyplot as plt
     |  >>> fig, ax = plt.subplots(1, 1)
     |  >>> ax.plot(xk, custm.pmf(xk), 'ro', ms=12, mec='r')
     |  >>> ax.vlines(xk, 0, custm.pmf(xk), colors='r', lw=4)
     |  >>> plt.show()
     |
     |  Random number generation:
     |
     |  >>> R = custm.rvs(size=100)
     |
     |  Method resolution order:
     |      rv_discrete
     |      rv_generic
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __getstate__(self)
     |      Helper for pickle.
     |
     |  __init__(self, a=0, b=inf, name=None, badvalue=None, moment_tol=1e-08, values=None, inc=1, longname=None, shapes=None, seed=None)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  cdf(self, k, *args, **kwds)
     |      Cumulative distribution function of the given RV.
     |
     |      Parameters
     |      ----------
     |      k : array_like, int
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      cdf : ndarray
     |          Cumulative distribution function evaluated at `k`.
     |
     |  expect(self, func=None, args=(), loc=0, lb=None, ub=None, conditional=False, maxcount=1000, tolerance=1e-10, chunksize=32)
     |      Calculate expected value of a function with respect to the distribution
     |      for discrete distribution by numerical summation.
     |
     |      Parameters
     |      ----------
     |      func : callable, optional
     |          Function for which the expectation value is calculated.
     |          Takes only one argument.
     |          The default is the identity mapping f(k) = k.
     |      args : tuple, optional
     |          Shape parameters of the distribution.
     |      loc : float, optional
     |          Location parameter.
     |          Default is 0.
     |      lb, ub : int, optional
     |          Lower and upper bound for the summation, default is set to the
     |          support of the distribution, inclusive (``lb <= k <= ub``).
     |      conditional : bool, optional
     |          If true then the expectation is corrected by the conditional
     |          probability of the summation interval. The return value is the
     |          expectation of the function, `func`, conditional on being in
     |          the given interval (k such that ``lb <= k <= ub``).
     |          Default is False.
     |      maxcount : int, optional
     |          Maximal number of terms to evaluate (to avoid an endless loop for
     |          an infinite sum). Default is 1000.
     |      tolerance : float, optional
     |          Absolute tolerance for the summation. Default is 1e-10.
     |      chunksize : int, optional
     |          Iterate over the support of a distributions in chunks of this size.
     |          Default is 32.
     |
     |      Returns
     |      -------
     |      expect : float
     |          Expected value.
     |
     |      Notes
     |      -----
     |      For heavy-tailed distributions, the expected value may or
     |      may not exist,
     |      depending on the function, `func`. If it does exist, but the
     |      sum converges
     |      slowly, the accuracy of the result may be rather low. For instance, for
     |      ``zipf(4)``, accuracy for mean, variance in example is only 1e-5.
     |      increasing `maxcount` and/or `chunksize` may improve the result,
     |      but may also make zipf very slow.
     |
     |      The function is not vectorized.
     |
     |  isf(self, q, *args, **kwds)
     |      Inverse survival function (inverse of `sf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          Upper tail probability.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      k : ndarray or scalar
     |          Quantile corresponding to the upper tail probability, q.
     |
     |  logcdf(self, k, *args, **kwds)
     |      Log of the cumulative distribution function at k of the given RV.
     |
     |      Parameters
     |      ----------
     |      k : array_like, int
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      logcdf : array_like
     |          Log of the cumulative distribution function evaluated at k.
     |
     |  logpmf(self, k, *args, **kwds)
     |      Log of the probability mass function at k of the given RV.
     |
     |      Parameters
     |      ----------
     |      k : array_like
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter. Default is 0.
     |
     |      Returns
     |      -------
     |      logpmf : array_like
     |          Log of the probability mass function evaluated at k.
     |
     |  logsf(self, k, *args, **kwds)
     |      Log of the survival function of the given RV.
     |
     |      Returns the log of the "survival function," defined as 1 - `cdf`,
     |      evaluated at `k`.
     |
     |      Parameters
     |      ----------
     |      k : array_like
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      logsf : ndarray
     |          Log of the survival function evaluated at `k`.
     |
     |  pmf(self, k, *args, **kwds)
     |      Probability mass function at k of the given RV.
     |
     |      Parameters
     |      ----------
     |      k : array_like
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      pmf : array_like
     |          Probability mass function evaluated at k
     |
     |  ppf(self, q, *args, **kwds)
     |      Percent point function (inverse of `cdf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          Lower tail probability.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      k : array_like
     |          Quantile corresponding to the lower tail probability, q.
     |
     |  rvs(self, *args, **kwargs)
     |      Random variates of given type.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      size : int or tuple of ints, optional
     |          Defining number of random variates (Default is 1). Note that `size`
     |          has to be given as keyword, not as positional argument.
     |      random_state : {None, int, `numpy.random.Generator`,
     |                      `numpy.random.RandomState`}, optional
     |
     |          If `random_state` is None (or `np.random`), the
     |          `numpy.random.RandomState` singleton is used.
     |          If `random_state` is an int, a new ``RandomState`` instance is
     |          used, seeded with `random_state`.
     |          If `random_state` is already a ``Generator`` or ``RandomState``
     |          instance, that instance is used.
     |
     |      Returns
     |      -------
     |      rvs : ndarray or scalar
     |          Random variates of given `size`.
     |
     |  sf(self, k, *args, **kwds)
     |      Survival function (1 - `cdf`) at k of the given RV.
     |
     |      Parameters
     |      ----------
     |      k : array_like
     |          Quantiles.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |
     |      Returns
     |      -------
     |      sf : array_like
     |          Survival function evaluated at k.
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(cls, a=0, b=inf, name=None, badvalue=None, moment_tol=1e-08, values=None, inc=1, longname=None, shapes=None, seed=None)
     |      Create and return a new object.  See help(type) for accurate signature.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from rv_generic:
     |
     |  __call__(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  __setstate__(self, state)
     |
     |  entropy(self, *args, **kwds)
     |      Differential entropy of the RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      scale : array_like, optional  (continuous distributions only).
     |          Scale parameter (default=1).
     |
     |      Notes
     |      -----
     |      Entropy is defined base `e`:
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats._distn_infrastructure import rv_discrete
     |      >>> drv = rv_discrete(values=((0, 1), (0.5, 0.5)))
     |      >>> np.allclose(drv.entropy(), np.log(2.0))
     |      True
     |
     |  freeze(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  interval(self, confidence, *args, **kwds)
     |      Confidence interval with equal areas around the median.
     |
     |      Parameters
     |      ----------
     |      confidence : array_like of float
     |          Probability that an rv will be drawn from the returned range.
     |          Each value should be in the range [0, 1].
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : ndarray of float
     |          end-points of range that contain ``100 * alpha %`` of the rv's
     |          possible values.
     |
     |      Notes
     |      -----
     |      This is implemented as ``ppf([p_tail, 1-p_tail])``, where
     |      ``ppf`` is the inverse cumulative distribution function and
     |      ``p_tail = (1-confidence)/2``. Suppose ``[c, d]`` is the support of a
     |      discrete distribution; then ``ppf([0, 1]) == (c-1, d)``. Therefore,
     |      when ``confidence=1`` and the distribution is discrete, the left end
     |      of the interval will be beyond the support of the distribution.
     |      For discrete distributions, the interval will limit the probability
     |      in each tail to be less than or equal to ``p_tail`` (usually
     |      strictly less).
     |
     |  mean(self, *args, **kwds)
     |      Mean of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      mean : float
     |          the mean of the distribution
     |
     |  median(self, *args, **kwds)
     |      Median of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          Location parameter, Default is 0.
     |      scale : array_like, optional
     |          Scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      median : float
     |          The median of the distribution.
     |
     |      See Also
     |      --------
     |      rv_discrete.ppf
     |          Inverse of the CDF
     |
     |  moment(self, order, *args, **kwds)
     |      non-central moment of distribution of specified order.
     |
     |      Parameters
     |      ----------
     |      order : int, order >= 1
     |          Order of moment.
     |      arg1, arg2, arg3,... : float
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |  nnlf(self, theta, x)
     |      Negative loglikelihood function.
     |      Notes
     |      -----
     |      This is ``-sum(log pdf(x, theta), axis=0)`` where `theta` are the
     |      parameters (including loc and scale).
     |
     |  stats(self, *args, **kwds)
     |      Some statistics of the given RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional (continuous RVs only)
     |          scale parameter (default=1)
     |      moments : str, optional
     |          composed of letters ['mvsk'] defining which moments to compute:
     |          'm' = mean,
     |          'v' = variance,
     |          's' = (Fisher's) skew,
     |          'k' = (Fisher's) kurtosis.
     |          (default is 'mv')
     |
     |      Returns
     |      -------
     |      stats : sequence
     |          of requested moments.
     |
     |  std(self, *args, **kwds)
     |      Standard deviation of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      std : float
     |          standard deviation of the distribution
     |
     |  support(self, *args, **kwargs)
     |      Support of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : array_like
     |          end-points of the distribution's support.
     |
     |  var(self, *args, **kwds)
     |      Variance of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      var : float
     |          the variance of the distribution
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from rv_generic:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  random_state
     |      Get or set the generator object for generating random variates.
     |
     |      If `random_state` is None (or `np.random`), the
     |      `numpy.random.RandomState` singleton is used.
     |      If `random_state` is an int, a new ``RandomState`` instance is used,
     |      seeded with `random_state`.
     |      If `random_state` is already a ``Generator`` or ``RandomState``
     |      instance, that instance is used.

    class rv_histogram(scipy.stats._distn_infrastructure.rv_continuous)
     |  rv_histogram(histogram, *args, density=None, **kwargs)
     |
     |  Generates a distribution given by a histogram.
     |  This is useful to generate a template distribution from a binned
     |  datasample.
     |
     |  As a subclass of the `rv_continuous` class, `rv_histogram` inherits from it
     |  a collection of generic methods (see `rv_continuous` for the full list),
     |  and implements them based on the properties of the provided binned
     |  datasample.
     |
     |  Parameters
     |  ----------
     |  histogram : tuple of array_like
     |      Tuple containing two array_like objects.
     |      The first containing the content of n bins,
     |      the second containing the (n+1) bin boundaries.
     |      In particular, the return value of `numpy.histogram` is accepted.
     |
     |  density : bool, optional
     |      If False, assumes the histogram is proportional to counts per bin;
     |      otherwise, assumes it is proportional to a density.
     |      For constant bin widths, these are equivalent, but the distinction
     |      is important when bin widths vary (see Notes).
     |      If None (default), sets ``density=True`` for backwards compatibility,
     |      but warns if the bin widths are variable. Set `density` explicitly
     |      to silence the warning.
     |
     |      .. versionadded:: 1.10.0
     |
     |  Notes
     |  -----
     |  When a histogram has unequal bin widths, there is a distinction between
     |  histograms that are proportional to counts per bin and histograms that are
     |  proportional to probability density over a bin. If `numpy.histogram` is
     |  called with its default ``density=False``, the resulting histogram is the
     |  number of counts per bin, so ``density=False`` should be passed to
     |  `rv_histogram`. If `numpy.histogram` is called with ``density=True``, the
     |  resulting histogram is in terms of probability density, so ``density=True``
     |  should be passed to `rv_histogram`. To avoid warnings, always pass
     |  ``density`` explicitly when the input histogram has unequal bin widths.
     |
     |  There are no additional shape parameters except for the loc and scale.
     |  The pdf is defined as a stepwise function from the provided histogram.
     |  The cdf is a linear interpolation of the pdf.
     |
     |  .. versionadded:: 0.19.0
     |
     |  Examples
     |  --------
     |
     |  Create a scipy.stats distribution from a numpy histogram
     |
     |  >>> import scipy.stats
     |  >>> import numpy as np
     |  >>> data = scipy.stats.norm.rvs(size=100000, loc=0, scale=1.5,
     |  ...                             random_state=123)
     |  >>> hist = np.histogram(data, bins=100)
     |  >>> hist_dist = scipy.stats.rv_histogram(hist, density=False)
     |
     |  Behaves like an ordinary scipy rv_continuous distribution
     |
     |  >>> hist_dist.pdf(1.0)
     |  0.20538577847618705
     |  >>> hist_dist.cdf(2.0)
     |  0.90818568543056499
     |
     |  PDF is zero above (below) the highest (lowest) bin of the histogram,
     |  defined by the max (min) of the original dataset
     |
     |  >>> hist_dist.pdf(np.max(data))
     |  0.0
     |  >>> hist_dist.cdf(np.max(data))
     |  1.0
     |  >>> hist_dist.pdf(np.min(data))
     |  7.7591907244498314e-05
     |  >>> hist_dist.cdf(np.min(data))
     |  0.0
     |
     |  PDF and CDF follow the histogram
     |
     |  >>> import matplotlib.pyplot as plt
     |  >>> X = np.linspace(-5.0, 5.0, 100)
     |  >>> fig, ax = plt.subplots()
     |  >>> ax.set_title("PDF from Template")
     |  >>> ax.hist(data, density=True, bins=100)
     |  >>> ax.plot(X, hist_dist.pdf(X), label='PDF')
     |  >>> ax.plot(X, hist_dist.cdf(X), label='CDF')
     |  >>> ax.legend()
     |  >>> fig.show()
     |
     |  Method resolution order:
     |      rv_histogram
     |      scipy.stats._distn_infrastructure.rv_continuous
     |      scipy.stats._distn_infrastructure.rv_generic
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self, histogram, *args, density=None, **kwargs)
     |      Create a new distribution using the given histogram
     |
     |      Parameters
     |      ----------
     |      histogram : tuple of array_like
     |          Tuple containing two array_like objects.
     |          The first containing the content of n bins,
     |          the second containing the (n+1) bin boundaries.
     |          In particular, the return value of np.histogram is accepted.
     |      density : bool, optional
     |          If False, assumes the histogram is proportional to counts per bin;
     |          otherwise, assumes it is proportional to a density.
     |          For constant bin widths, these are equivalent.
     |          If None (default), sets ``density=True`` for backward
     |          compatibility, but warns if the bin widths are variable. Set
     |          `density` explicitly to silence the warning.
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.stats._distn_infrastructure.rv_continuous:
     |
     |  __getstate__(self)
     |      Helper for pickle.
     |
     |  cdf(self, x, *args, **kwds)
     |      Cumulative distribution function of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      cdf : ndarray
     |          Cumulative distribution function evaluated at `x`
     |
     |  expect(self, func=None, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
     |      Calculate expected value of a function with respect to the
     |      distribution by numerical integration.
     |
     |      The expected value of a function ``f(x)`` with respect to a
     |      distribution ``dist`` is defined as::
     |
     |                  ub
     |          E[f(x)] = Integral(f(x) * dist.pdf(x)),
     |                  lb
     |
     |      where ``ub`` and ``lb`` are arguments and ``x`` has the ``dist.pdf(x)``
     |      distribution. If the bounds ``lb`` and ``ub`` correspond to the
     |      support of the distribution, e.g. ``[-inf, inf]`` in the default
     |      case, then the integral is the unrestricted expectation of ``f(x)``.
     |      Also, the function ``f(x)`` may be defined such that ``f(x)`` is ``0``
     |      outside a finite interval in which case the expectation is
     |      calculated within the finite range ``[lb, ub]``.
     |
     |      Parameters
     |      ----------
     |      func : callable, optional
     |          Function for which integral is calculated. Takes only one argument.
     |          The default is the identity mapping f(x) = x.
     |      args : tuple, optional
     |          Shape parameters of the distribution.
     |      loc : float, optional
     |          Location parameter (default=0).
     |      scale : float, optional
     |          Scale parameter (default=1).
     |      lb, ub : scalar, optional
     |          Lower and upper bound for integration. Default is set to the
     |          support of the distribution.
     |      conditional : bool, optional
     |          If True, the integral is corrected by the conditional probability
     |          of the integration interval.  The return value is the expectation
     |          of the function, conditional on being in the given interval.
     |          Default is False.
     |
     |      Additional keyword arguments are passed to the integration routine.
     |
     |      Returns
     |      -------
     |      expect : float
     |          The calculated expected value.
     |
     |      Notes
     |      -----
     |      The integration behavior of this function is inherited from
     |      `scipy.integrate.quad`. Neither this function nor
     |      `scipy.integrate.quad` can verify whether the integral exists or is
     |      finite. For example ``cauchy(0).mean()`` returns ``np.nan`` and
     |      ``cauchy(0).expect()`` returns ``0.0``.
     |
     |      Likewise, the accuracy of results is not verified by the function.
     |      `scipy.integrate.quad` is typically reliable for integrals that are
     |      numerically favorable, but it is not guaranteed to converge
     |      to a correct value for all possible intervals and integrands. This
     |      function is provided for convenience; for critical applications,
     |      check results against other integration methods.
     |
     |      The function is not vectorized.
     |
     |      Examples
     |      --------
     |
     |      To understand the effect of the bounds of integration consider
     |
     |      >>> from scipy.stats import expon
     |      >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0)
     |      0.6321205588285578
     |
     |      This is close to
     |
     |      >>> expon(1).cdf(2.0) - expon(1).cdf(0.0)
     |      0.6321205588285577
     |
     |      If ``conditional=True``
     |
     |      >>> expon(1).expect(lambda x: 1, lb=0.0, ub=2.0, conditional=True)
     |      1.0000000000000002
     |
     |      The slight deviation from 1 is due to numerical integration.
     |
     |      The integrand can be treated as a complex-valued function
     |      by passing ``complex_func=True`` to `scipy.integrate.quad` .
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats import vonmises
     |      >>> res = vonmises(loc=2, kappa=1).expect(lambda x: np.exp(1j*x),
     |      ...                                       complex_func=True)
     |      >>> res
     |      (-0.18576377217422957+0.40590124735052263j)
     |
     |      >>> np.angle(res)  # location of the (circular) distribution
     |      2.0
     |
     |  fit(self, data, *args, **kwds)
     |      Return estimates of shape (if applicable), location, and scale
     |      parameters from data. The default estimation method is Maximum
     |      Likelihood Estimation (MLE), but Method of Moments (MM)
     |      is also available.
     |
     |      Starting estimates for the fit are given by input arguments;
     |      for any arguments not provided with starting estimates,
     |      ``self._fitstart(data)`` is called to generate such.
     |
     |      One can hold some parameters fixed to specific values by passing in
     |      keyword arguments ``f0``, ``f1``, ..., ``fn`` (for shape parameters)
     |      and ``floc`` and ``fscale`` (for location and scale parameters,
     |      respectively).
     |
     |      Parameters
     |      ----------
     |      data : array_like or `CensoredData` instance
     |          Data to use in estimating the distribution parameters.
     |      arg1, arg2, arg3,... : floats, optional
     |          Starting value(s) for any shape-characterizing arguments (those not
     |          provided will be determined by a call to ``_fitstart(data)``).
     |          No default value.
     |      **kwds : floats, optional
     |          - `loc`: initial guess of the distribution's location parameter.
     |          - `scale`: initial guess of the distribution's scale parameter.
     |
     |          Special keyword arguments are recognized as holding certain
     |          parameters fixed:
     |
     |          - f0...fn : hold respective shape parameters fixed.
     |            Alternatively, shape parameters to fix can be specified by name.
     |            For example, if ``self.shapes == "a, b"``, ``fa`` and ``fix_a``
     |            are equivalent to ``f0``, and ``fb`` and ``fix_b`` are
     |            equivalent to ``f1``.
     |
     |          - floc : hold location parameter fixed to specified value.
     |
     |          - fscale : hold scale parameter fixed to specified value.
     |
     |          - optimizer : The optimizer to use.  The optimizer must take
     |            ``func`` and starting position as the first two arguments,
     |            plus ``args`` (for extra arguments to pass to the
     |            function to be optimized) and ``disp``.
     |            The ``fit`` method calls the optimizer with ``disp=0`` to suppress output.
     |            The optimizer must return the estimated parameters.
     |
     |          - method : The method to use. The default is "MLE" (Maximum
     |            Likelihood Estimate); "MM" (Method of Moments)
     |            is also available.
     |
     |      Raises
     |      ------
     |      TypeError, ValueError
     |          If an input is invalid
     |      `~scipy.stats.FitError`
     |          If fitting fails or the fit produced would be invalid
     |
     |      Returns
     |      -------
     |      parameter_tuple : tuple of floats
     |          Estimates for any shape parameters (if applicable), followed by
     |          those for location and scale. For most random variables, shape
     |          statistics will be returned, but there are exceptions (e.g.
     |          ``norm``).
     |
     |      Notes
     |      -----
     |      With ``method="MLE"`` (default), the fit is computed by minimizing
     |      the negative log-likelihood function. A large, finite penalty
     |      (rather than infinite negative log-likelihood) is applied for
     |      observations beyond the support of the distribution.
     |
     |      With ``method="MM"``, the fit is computed by minimizing the L2 norm
     |      of the relative errors between the first *k* raw (about zero) data
     |      moments and the corresponding distribution moments, where *k* is the
     |      number of non-fixed parameters.
     |      More precisely, the objective function is::
     |
     |          (((data_moments - dist_moments)
     |            / np.maximum(np.abs(data_moments), 1e-8))**2).sum()
     |
     |      where the constant ``1e-8`` avoids division by zero in case of
     |      vanishing data moments. Typically, this error norm can be reduced to
     |      zero.
     |      Note that the standard method of moments can produce parameters for
     |      which some data are outside the support of the fitted distribution;
     |      this implementation does nothing to prevent this.
     |
     |      For either method,
     |      the returned answer is not guaranteed to be globally optimal; it
     |      may only be locally optimal, or the optimization may fail altogether.
     |      If the data contain any of ``np.nan``, ``np.inf``, or ``-np.inf``,
     |      the `fit` method will raise a ``RuntimeError``.
     |
     |      When passing a ``CensoredData`` instance to ``data``, the log-likelihood
     |      function is defined as:
     |
     |      .. math::
     |
     |          l(\pmb{\theta}; k) & = \sum
     |                                  \log(f(k_u; \pmb{\theta}))
     |                              + \sum
     |                                  \log(F(k_l; \pmb{\theta})) \\
     |                              & + \sum
     |                                  \log(1 - F(k_r; \pmb{\theta})) \\
     |                              & + \sum
     |                                  \log(F(k_{\text{high}, i}; \pmb{\theta})
     |                                  - F(k_{\text{low}, i}; \pmb{\theta}))
     |
     |      where :math:`f` and :math:`F` are the pdf and cdf, respectively, of the
     |      function being fitted, :math:`\pmb{\theta}` is the parameter vector,
     |      :math:`u` are the indices of uncensored observations,
     |      :math:`l` are the indices of left-censored observations,
     |      :math:`r` are the indices of right-censored observations,
     |      subscripts "low"/"high" denote endpoints of interval-censored observations, and
     |      :math:`i` are the indices of interval-censored observations.
     |
     |      Examples
     |      --------
     |
     |      Generate some data to fit: draw random variates from the `beta`
     |      distribution
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats import beta
     |      >>> a, b = 1., 2.
     |      >>> rng = np.random.default_rng(172786373191770012695001057628748821561)
     |      >>> x = beta.rvs(a, b, size=1000, random_state=rng)
     |
     |      Now we can fit all four parameters (``a``, ``b``, ``loc`` and
     |      ``scale``):
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x)
     |      >>> a1, b1, loc1, scale1
     |      (1.0198945204435628, 1.9484708982737828, 4.372241314917588e-05, 0.9979078845964814)
     |
     |      The fit can be done also using a custom optimizer:
     |
     |      >>> from scipy.optimize import minimize
     |      >>> def custom_optimizer(func, x0, args=(), disp=0):
     |      ...     res = minimize(func, x0, args, method="slsqp", options={"disp": disp})
     |      ...     if res.success:
     |      ...         return res.x
     |      ...     raise RuntimeError('optimization routine failed')
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, method="MLE", optimizer=custom_optimizer)
     |      >>> a1, b1, loc1, scale1
     |      (1.0198821087258905, 1.948484145914738, 4.3705304486881485e-05, 0.9979104663953395)
     |
     |      We can also use some prior knowledge about the dataset: let's keep
     |      ``loc`` and ``scale`` fixed:
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, floc=0, fscale=1)
     |      >>> loc1, scale1
     |      (0, 1)
     |
     |      We can also keep shape parameters fixed by using ``f``-keywords. To
     |      keep the zero-th shape parameter ``a`` equal 1, use ``f0=1`` or,
     |      equivalently, ``fa=1``:
     |
     |      >>> a1, b1, loc1, scale1 = beta.fit(x, fa=1, floc=0, fscale=1)
     |      >>> a1
     |      1
     |
     |      Not all distributions return estimates for the shape parameters.
     |      ``norm`` for example just returns estimates for location and scale:
     |
     |      >>> from scipy.stats import norm
     |      >>> x = norm.rvs(a, b, size=1000, random_state=123)
     |      >>> loc1, scale1 = norm.fit(x)
     |      >>> loc1, scale1
     |      (0.92087172783841631, 2.0015750750324668)
     |
     |  fit_loc_scale(self, data, *args)
     |      Estimate loc and scale parameters from data using 1st and 2nd moments.
     |
     |      Parameters
     |      ----------
     |      data : array_like
     |          Data to fit.
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |
     |      Returns
     |      -------
     |      Lhat : float
     |          Estimated location parameter for the data.
     |      Shat : float
     |          Estimated scale parameter for the data.
     |
     |  isf(self, q, *args, **kwds)
     |      Inverse survival function (inverse of `sf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          upper tail probability
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      x : ndarray or scalar
     |          Quantile corresponding to the upper tail probability q.
     |
     |  logcdf(self, x, *args, **kwds)
     |      Log of the cumulative distribution function at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logcdf : array_like
     |          Log of the cumulative distribution function evaluated at x
     |
     |  logpdf(self, x, *args, **kwds)
     |      Log of the probability density function at x of the given RV.
     |
     |      This uses a more numerically accurate calculation if available.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logpdf : array_like
     |          Log of the probability density function evaluated at x
     |
     |  logsf(self, x, *args, **kwds)
     |      Log of the survival function of the given RV.
     |
     |      Returns the log of the "survival function," defined as (1 - `cdf`),
     |      evaluated at `x`.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      logsf : ndarray
     |          Log of the survival function evaluated at `x`.
     |
     |  pdf(self, x, *args, **kwds)
     |      Probability density function at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      pdf : ndarray
     |          Probability density function evaluated at x
     |
     |  ppf(self, q, *args, **kwds)
     |      Percent point function (inverse of `cdf`) at q of the given RV.
     |
     |      Parameters
     |      ----------
     |      q : array_like
     |          lower tail probability
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      x : array_like
     |          quantile corresponding to the lower tail probability q.
     |
     |  sf(self, x, *args, **kwds)
     |      Survival function (1 - `cdf`) at x of the given RV.
     |
     |      Parameters
     |      ----------
     |      x : array_like
     |          quantiles
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      sf : array_like
     |          Survival function evaluated at x
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from scipy.stats._distn_infrastructure.rv_generic:
     |
     |  __call__(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  __setstate__(self, state)
     |
     |  entropy(self, *args, **kwds)
     |      Differential entropy of the RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      scale : array_like, optional  (continuous distributions only).
     |          Scale parameter (default=1).
     |
     |      Notes
     |      -----
     |      Entropy is defined base `e`:
     |
     |      >>> import numpy as np
     |      >>> from scipy.stats._distn_infrastructure import rv_discrete
     |      >>> drv = rv_discrete(values=((0, 1), (0.5, 0.5)))
     |      >>> np.allclose(drv.entropy(), np.log(2.0))
     |      True
     |
     |  freeze(self, *args, **kwds)
     |      Freeze the distribution for the given arguments.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution.  Should include all
     |          the non-optional arguments, may include ``loc`` and ``scale``.
     |
     |      Returns
     |      -------
     |      rv_frozen : rv_frozen instance
     |          The frozen distribution.
     |
     |  interval(self, confidence, *args, **kwds)
     |      Confidence interval with equal areas around the median.
     |
     |      Parameters
     |      ----------
     |      confidence : array_like of float
     |          Probability that an rv will be drawn from the returned range.
     |          Each value should be in the range [0, 1].
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : ndarray of float
     |          end-points of range that contain ``100 * alpha %`` of the rv's
     |          possible values.
     |
     |      Notes
     |      -----
     |      This is implemented as ``ppf([p_tail, 1-p_tail])``, where
     |      ``ppf`` is the inverse cumulative distribution function and
     |      ``p_tail = (1-confidence)/2``. Suppose ``[c, d]`` is the support of a
     |      discrete distribution; then ``ppf([0, 1]) == (c-1, d)``. Therefore,
     |      when ``confidence=1`` and the distribution is discrete, the left end
     |      of the interval will be beyond the support of the distribution.
     |      For discrete distributions, the interval will limit the probability
     |      in each tail to be less than or equal to ``p_tail`` (usually
     |      strictly less).
     |
     |  mean(self, *args, **kwds)
     |      Mean of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      mean : float
     |          the mean of the distribution
     |
     |  median(self, *args, **kwds)
     |      Median of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          Location parameter, Default is 0.
     |      scale : array_like, optional
     |          Scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      median : float
     |          The median of the distribution.
     |
     |      See Also
     |      --------
     |      rv_discrete.ppf
     |          Inverse of the CDF
     |
     |  moment(self, order, *args, **kwds)
     |      non-central moment of distribution of specified order.
     |
     |      Parameters
     |      ----------
     |      order : int, order >= 1
     |          Order of moment.
     |      arg1, arg2, arg3,... : float
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |  nnlf(self, theta, x)
     |      Negative loglikelihood function.
     |      Notes
     |      -----
     |      This is ``-sum(log pdf(x, theta), axis=0)`` where `theta` are the
     |      parameters (including loc and scale).
     |
     |  rvs(self, *args, **kwds)
     |      Random variates of given type.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          Location parameter (default=0).
     |      scale : array_like, optional
     |          Scale parameter (default=1).
     |      size : int or tuple of ints, optional
     |          Defining number of random variates (default is 1).
     |      random_state : {None, int, `numpy.random.Generator`,
     |                      `numpy.random.RandomState`}, optional
     |
     |          If `random_state` is None (or `np.random`), the
     |          `numpy.random.RandomState` singleton is used.
     |          If `random_state` is an int, a new ``RandomState`` instance is
     |          used, seeded with `random_state`.
     |          If `random_state` is already a ``Generator`` or ``RandomState``
     |          instance, that instance is used.
     |
     |      Returns
     |      -------
     |      rvs : ndarray or scalar
     |          Random variates of given `size`.
     |
     |  stats(self, *args, **kwds)
     |      Some statistics of the given RV.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional (continuous RVs only)
     |          scale parameter (default=1)
     |      moments : str, optional
     |          composed of letters ['mvsk'] defining which moments to compute:
     |          'm' = mean,
     |          'v' = variance,
     |          's' = (Fisher's) skew,
     |          'k' = (Fisher's) kurtosis.
     |          (default is 'mv')
     |
     |      Returns
     |      -------
     |      stats : sequence
     |          of requested moments.
     |
     |  std(self, *args, **kwds)
     |      Standard deviation of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      std : float
     |          standard deviation of the distribution
     |
     |  support(self, *args, **kwargs)
     |      Support of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, ... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information).
     |      loc : array_like, optional
     |          location parameter, Default is 0.
     |      scale : array_like, optional
     |          scale parameter, Default is 1.
     |
     |      Returns
     |      -------
     |      a, b : array_like
     |          end-points of the distribution's support.
     |
     |  var(self, *args, **kwds)
     |      Variance of the distribution.
     |
     |      Parameters
     |      ----------
     |      arg1, arg2, arg3,... : array_like
     |          The shape parameter(s) for the distribution (see docstring of the
     |          instance object for more information)
     |      loc : array_like, optional
     |          location parameter (default=0)
     |      scale : array_like, optional
     |          scale parameter (default=1)
     |
     |      Returns
     |      -------
     |      var : float
     |          the variance of the distribution
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from scipy.stats._distn_infrastructure.rv_generic:
     |
     |  __dict__
     |      dictionary for instance variables
     |
     |  __weakref__
     |      list of weak references to the object
     |
     |  random_state
     |      Get or set the generator object for generating random variates.
     |
     |      If `random_state` is None (or `np.random`), the
     |      `numpy.random.RandomState` singleton is used.
     |      If `random_state` is an int, a new ``RandomState`` instance is used,
     |      seeded with `random_state`.
     |      If `random_state` is already a ``Generator`` or ``RandomState``
     |      instance, that instance is used.

FUNCTIONS
    alexandergovern(*samples, nan_policy='propagate', axis=0, keepdims=False)
        Performs the Alexander Govern test.

        The Alexander-Govern approximation tests the equality of k independent
        means in the face of heterogeneity of variance. The test is applied to
        samples from two or more groups, possibly with differing sizes.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            The sample measurements for each group.  There must be at least
            two samples, and each sample must contain at least two observations.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : AlexanderGovernResult
            An object with attributes:

            statistic : float
                The computed A statistic of the test.
            pvalue : float
                The associated p-value from the chi-squared distribution.

        Warns
        -----
        `~scipy.stats.ConstantInputWarning`
            Raised if an input is a constant array.  The statistic is not defined
            in this case, so ``np.nan`` is returned.

        See Also
        --------

        :func:`f_oneway`
            one-way ANOVA


        Notes
        -----
        The use of this test relies on several assumptions.

        1. The samples are independent.
        2. Each sample is from a normally distributed population.
        3. Unlike `f_oneway`, this test does not assume on homoscedasticity,
           instead relaxing the assumption of equal variances.

        Input samples must be finite, one dimensional, and with size greater than
        one.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Alexander, Ralph A., and Diane M. Govern. "A New and Simpler
               Approximation for ANOVA under Variance Heterogeneity." Journal
               of Educational Statistics, vol. 19, no. 2, 1994, pp. 91-101.
               JSTOR, www.jstor.org/stable/1165140. Accessed 12 Sept. 2020.

        Examples
        --------
        >>> from scipy.stats import alexandergovern

        Here are some data on annual percentage rate of interest charged on
        new car loans at nine of the largest banks in four American cities
        taken from the National Institute of Standards and Technology's
        ANOVA dataset.

        We use `alexandergovern` to test the null hypothesis that all cities
        have the same mean APR against the alternative that the cities do not
        all have the same mean APR. We decide that a significance level of 5%
        is required to reject the null hypothesis in favor of the alternative.

        >>> atlanta = [13.75, 13.75, 13.5, 13.5, 13.0, 13.0, 13.0, 12.75, 12.5]
        >>> chicago = [14.25, 13.0, 12.75, 12.5, 12.5, 12.4, 12.3, 11.9, 11.9]
        >>> houston = [14.0, 14.0, 13.51, 13.5, 13.5, 13.25, 13.0, 12.5, 12.5]
        >>> memphis = [15.0, 14.0, 13.75, 13.59, 13.25, 12.97, 12.5, 12.25,
        ...           11.89]
        >>> alexandergovern(atlanta, chicago, houston, memphis)
        AlexanderGovernResult(statistic=4.65087071883494,
                              pvalue=0.19922132490385214)

        The p-value is 0.1992, indicating a nearly 20% chance of observing
        such an extreme value of the test statistic under the null hypothesis.
        This exceeds 5%, so we do not reject the null hypothesis in favor of
        the alternative.

    anderson(x, dist='norm')
        Anderson-Darling test for data coming from a particular distribution.

        The Anderson-Darling test tests the null hypothesis that a sample is
        drawn from a population that follows a particular distribution.
        For the Anderson-Darling test, the critical values depend on
        which distribution is being tested against.  This function works
        for normal, exponential, logistic, weibull_min, or Gumbel (Extreme Value
        Type I) distributions.

        Parameters
        ----------
        x : array_like
            Array of sample data.
        dist : {'norm', 'expon', 'logistic', 'gumbel', 'gumbel_l', 'gumbel_r', 'extreme1', 'weibull_min'}, optional
            The type of distribution to test against.  The default is 'norm'.
            The names 'extreme1', 'gumbel_l' and 'gumbel' are synonyms for the
            same distribution.

        Returns
        -------
        result : AndersonResult
            An object with the following attributes:

            statistic : float
                The Anderson-Darling test statistic.
            critical_values : list
                The critical values for this distribution.
            significance_level : list
                The significance levels for the corresponding critical values
                in percents.  The function returns critical values for a
                differing set of significance levels depending on the
                distribution that is being tested against.
            fit_result : `~scipy.stats._result_classes.FitResult`
                An object containing the results of fitting the distribution to
                the data.

        See Also
        --------
        kstest : The Kolmogorov-Smirnov test for goodness-of-fit.

        Notes
        -----
        Critical values provided are for the following significance levels:

        normal/exponential
            15%, 10%, 5%, 2.5%, 1%
        logistic
            25%, 10%, 5%, 2.5%, 1%, 0.5%
        gumbel_l / gumbel_r
            25%, 10%, 5%, 2.5%, 1%
        weibull_min
            50%, 25%, 15%, 10%, 5%, 2.5%, 1%, 0.5%

        If the returned statistic is larger than these critical values then
        for the corresponding significance level, the null hypothesis that
        the data come from the chosen distribution can be rejected.
        The returned statistic is referred to as 'A2' in the references.

        For `weibull_min`, maximum likelihood estimation is known to be
        challenging. If the test returns successfully, then the first order
        conditions for a maximum likehood estimate have been verified and
        the critical values correspond relatively well to the significance levels,
        provided that the sample is sufficiently large (>10 observations [7]).
        However, for some data - especially data with no left tail - `anderson`
        is likely to result in an error message. In this case, consider
        performing a custom goodness of fit test using
        `scipy.stats.monte_carlo_test`.

        References
        ----------
        .. [1] https://www.itl.nist.gov/div898/handbook/prc/section2/prc213.htm
        .. [2] Stephens, M. A. (1974). EDF Statistics for Goodness of Fit and
               Some Comparisons, Journal of the American Statistical Association,
               Vol. 69, pp. 730-737.
        .. [3] Stephens, M. A. (1976). Asymptotic Results for Goodness-of-Fit
               Statistics with Unknown Parameters, Annals of Statistics, Vol. 4,
               pp. 357-369.
        .. [4] Stephens, M. A. (1977). Goodness of Fit for the Extreme Value
               Distribution, Biometrika, Vol. 64, pp. 583-588.
        .. [5] Stephens, M. A. (1977). Goodness of Fit with Special Reference
               to Tests for Exponentiality , Technical Report No. 262,
               Department of Statistics, Stanford University, Stanford, CA.
        .. [6] Stephens, M. A. (1979). Tests of Fit for the Logistic Distribution
               Based on the Empirical Distribution Function, Biometrika, Vol. 66,
               pp. 591-595.
        .. [7] Richard A. Lockhart and Michael A. Stephens "Estimation and Tests of
               Fit for the Three-Parameter Weibull Distribution"
               Journal of the Royal Statistical Society.Series B(Methodological)
               Vol. 56, No. 3 (1994), pp. 491-500, Table 0.

        Examples
        --------
        Test the null hypothesis that a random sample was drawn from a normal
        distribution (with unspecified mean and standard deviation).

        >>> import numpy as np
        >>> from scipy.stats import anderson
        >>> rng = np.random.default_rng()
        >>> data = rng.random(size=35)
        >>> res = anderson(data)
        >>> res.statistic
        0.8398018749744764
        >>> res.critical_values
        array([0.527, 0.6  , 0.719, 0.839, 0.998])
        >>> res.significance_level
        array([15. , 10. ,  5. ,  2.5,  1. ])

        The value of the statistic (barely) exceeds the critical value associated
        with a significance level of 2.5%, so the null hypothesis may be rejected
        at a significance level of 2.5%, but not at a significance level of 1%.

    anderson_ksamp(samples, midrank=True, *, method=None)
        The Anderson-Darling test for k-samples.

        The k-sample Anderson-Darling test is a modification of the
        one-sample Anderson-Darling test. It tests the null hypothesis
        that k-samples are drawn from the same population without having
        to specify the distribution function of that population. The
        critical values depend on the number of samples.

        Parameters
        ----------
        samples : sequence of 1-D array_like
            Array of sample data in arrays.
        midrank : bool, optional
            Type of Anderson-Darling test which is computed. Default
            (True) is the midrank test applicable to continuous and
            discrete populations. If False, the right side empirical
            distribution is used.
        method : PermutationMethod, optional
            Defines the method used to compute the p-value. If `method` is an
            instance of `PermutationMethod`, the p-value is computed using
            `scipy.stats.permutation_test` with the provided configuration options
            and other appropriate settings. Otherwise, the p-value is interpolated
            from tabulated values.

        Returns
        -------
        res : Anderson_ksampResult
            An object containing attributes:

            statistic : float
                Normalized k-sample Anderson-Darling test statistic.
            critical_values : array
                The critical values for significance levels 25%, 10%, 5%, 2.5%, 1%,
                0.5%, 0.1%.
            pvalue : float
                The approximate p-value of the test. If `method` is not
                provided, the value is floored / capped at 0.1% / 25%.

        Raises
        ------
        ValueError
            If fewer than 2 samples are provided, a sample is empty, or no
            distinct observations are in the samples.

        See Also
        --------
        ks_2samp : 2 sample Kolmogorov-Smirnov test
        anderson : 1 sample Anderson-Darling test

        Notes
        -----
        [1]_ defines three versions of the k-sample Anderson-Darling test:
        one for continuous distributions and two for discrete
        distributions, in which ties between samples may occur. The
        default of this routine is to compute the version based on the
        midrank empirical distribution function. This test is applicable
        to continuous and discrete data. If midrank is set to False, the
        right side empirical distribution is used for a test for discrete
        data. According to [1]_, the two discrete test statistics differ
        only slightly if a few collisions due to round-off errors occur in
        the test not adjusted for ties between samples.

        The critical values corresponding to the significance levels from 0.01
        to 0.25 are taken from [1]_. p-values are floored / capped
        at 0.1% / 25%. Since the range of critical values might be extended in
        future releases, it is recommended not to test ``p == 0.25``, but rather
        ``p >= 0.25`` (analogously for the lower bound).

        .. versionadded:: 0.14.0

        References
        ----------
        .. [1] Scholz, F. W and Stephens, M. A. (1987), K-Sample
               Anderson-Darling Tests, Journal of the American Statistical
               Association, Vol. 82, pp. 918-924.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> res = stats.anderson_ksamp([rng.normal(size=50),
        ... rng.normal(loc=0.5, size=30)])
        >>> res.statistic, res.pvalue
        (1.974403288713695, 0.04991293614572478)
        >>> res.critical_values
        array([0.325, 1.226, 1.961, 2.718, 3.752, 4.592, 6.546])

        The null hypothesis that the two random samples come from the same
        distribution can be rejected at the 5% level because the returned
        test value is greater than the critical value for 5% (1.961) but
        not at the 2.5% level. The interpolation gives an approximate
        p-value of 4.99%.

        >>> samples = [rng.normal(size=50), rng.normal(size=30),
        ...            rng.normal(size=20)]
        >>> res = stats.anderson_ksamp(samples)
        >>> res.statistic, res.pvalue
        (-0.29103725200789504, 0.25)
        >>> res.critical_values
        array([ 0.44925884,  1.3052767 ,  1.9434184 ,  2.57696569,  3.41634856,
          4.07210043, 5.56419101])

        The null hypothesis cannot be rejected for three samples from an
        identical distribution. The reported p-value (25%) has been capped and
        may not be very accurate (since it corresponds to the value 0.449
        whereas the statistic is -0.291).

        In such cases where the p-value is capped or when sample sizes are
        small, a permutation test may be more accurate.

        >>> method = stats.PermutationMethod(n_resamples=9999, random_state=rng)
        >>> res = stats.anderson_ksamp(samples, method=method)
        >>> res.pvalue
        0.5254

    ansari(x, y, alternative='two-sided', *, axis=0, nan_policy='propagate', keepdims=False)
        Perform the Ansari-Bradley test for equal scale parameters.

        The Ansari-Bradley test ([1]_, [2]_) is a non-parametric test
        for the equality of the scale parameter of the distributions
        from which two samples were drawn. The null hypothesis states that
        the ratio of the scale of the distribution underlying `x` to the scale
        of the distribution underlying `y` is 1.

        Parameters
        ----------
        x, y : array_like
            Arrays of sample data.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the ratio of scales is not equal to 1.
            * 'less': the ratio of scales is less than 1.
            * 'greater': the ratio of scales is greater than 1.

            .. versionadded:: 1.7.0
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The Ansari-Bradley test statistic.
        pvalue : float
            The p-value of the hypothesis test.

        See Also
        --------

        :func:`fligner`
            A non-parametric test for the equality of k variances
        :func:`mood`
            A non-parametric test for the equality of two scale parameters


        Notes
        -----
        The p-value given is exact when the sample sizes are both less than
        55 and there are no ties, otherwise a normal approximation for the
        p-value is used.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Ansari, A. R. and Bradley, R. A. (1960) Rank-sum tests for
               dispersions, Annals of Mathematical Statistics, 31, 1174-1189.
        .. [2] Sprent, Peter and N.C. Smeeton.  Applied nonparametric
               statistical methods.  3rd ed. Chapman and Hall/CRC. 2001.
               Section 5.8.2.
        .. [3] Nathaniel E. Helwig "Nonparametric Dispersion and Equality
               Tests" at http://users.stat.umn.edu/~helwig/notes/npde-Notes.pdf

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import ansari
        >>> rng = np.random.default_rng()

        For these examples, we'll create three random data sets.  The first
        two, with sizes 35 and 25, are drawn from a normal distribution with
        mean 0 and standard deviation 2.  The third data set has size 25 and
        is drawn from a normal distribution with standard deviation 1.25.

        >>> x1 = rng.normal(loc=0, scale=2, size=35)
        >>> x2 = rng.normal(loc=0, scale=2, size=25)
        >>> x3 = rng.normal(loc=0, scale=1.25, size=25)

        First we apply `ansari` to `x1` and `x2`.  These samples are drawn
        from the same distribution, so we expect the Ansari-Bradley test
        should not lead us to conclude that the scales of the distributions
        are different.

        >>> ansari(x1, x2)
        AnsariResult(statistic=541.0, pvalue=0.9762532927399098)

        With a p-value close to 1, we cannot conclude that there is a
        significant difference in the scales (as expected).

        Now apply the test to `x1` and `x3`:

        >>> ansari(x1, x3)
        AnsariResult(statistic=425.0, pvalue=0.0003087020407974518)

        The probability of observing such an extreme value of the statistic
        under the null hypothesis of equal scales is only 0.03087%. We take this
        as evidence against the null hypothesis in favor of the alternative:
        the scales of the distributions from which the samples were drawn
        are not equal.

        We can use the `alternative` parameter to perform a one-tailed test.
        In the above example, the scale of `x1` is greater than `x3` and so
        the ratio of scales of `x1` and `x3` is greater than 1. This means
        that the p-value when ``alternative='greater'`` should be near 0 and
        hence we should be able to reject the null hypothesis:

        >>> ansari(x1, x3, alternative='greater')
        AnsariResult(statistic=425.0, pvalue=0.0001543510203987259)

        As we can see, the p-value is indeed quite low. Use of
        ``alternative='less'`` should thus yield a large p-value:

        >>> ansari(x1, x3, alternative='less')
        AnsariResult(statistic=425.0, pvalue=0.9998643258449039)

    barnard_exact(table, alternative='two-sided', pooled=True, n=32)
        Perform a Barnard exact test on a 2x2 contingency table.

        Parameters
        ----------
        table : array_like of ints
            A 2x2 contingency table.  Elements should be non-negative integers.

        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the null and alternative hypotheses. Default is 'two-sided'.
            Please see explanations in the Notes section below.

        pooled : bool, optional
            Whether to compute score statistic with pooled variance (as in
            Student's t-test, for example) or unpooled variance (as in Welch's
            t-test). Default is ``True``.

        n : int, optional
            Number of sampling points used in the construction of the sampling
            method. Note that this argument will automatically be converted to
            the next higher power of 2 since `scipy.stats.qmc.Sobol` is used to
            select sample points. Default is 32. Must be positive. In most cases,
            32 points is enough to reach good precision. More points comes at
            performance cost.

        Returns
        -------
        ber : BarnardExactResult
            A result object with the following attributes.

            statistic : float
                The Wald statistic with pooled or unpooled variance, depending
                on the user choice of `pooled`.

            pvalue : float
                P-value, the probability of obtaining a distribution at least as
                extreme as the one that was actually observed, assuming that the
                null hypothesis is true.

        See Also
        --------
        chi2_contingency : Chi-square test of independence of variables in a
            contingency table.
        fisher_exact : Fisher exact test on a 2x2 contingency table.
        boschloo_exact : Boschloo's exact test on a 2x2 contingency table,
            which is an uniformly more powerful alternative to Fisher's exact test.

        Notes
        -----
        Barnard's test is an exact test used in the analysis of contingency
        tables. It examines the association of two categorical variables, and
        is a more powerful alternative than Fisher's exact test
        for 2x2 contingency tables.

        Let's define :math:`X_0` a 2x2 matrix representing the observed sample,
        where each column stores the binomial experiment, as in the example
        below. Let's also define :math:`p_1, p_2` the theoretical binomial
        probabilities for  :math:`x_{11}` and :math:`x_{12}`. When using
        Barnard exact test, we can assert three different null hypotheses :

        - :math:`H_0 : p_1 \geq p_2` versus :math:`H_1 : p_1 < p_2`,
          with `alternative` = "less"

        - :math:`H_0 : p_1 \leq p_2` versus :math:`H_1 : p_1 > p_2`,
          with `alternative` = "greater"

        - :math:`H_0 : p_1 = p_2` versus :math:`H_1 : p_1 \neq p_2`,
          with `alternative` = "two-sided" (default one)

        In order to compute Barnard's exact test, we are using the Wald
        statistic [3]_ with pooled or unpooled variance.
        Under the default assumption that both variances are equal
        (``pooled = True``), the statistic is computed as:

        .. math::

            T(X) = \frac{
                \hat{p}_1 - \hat{p}_2
            }{
                \sqrt{
                    \hat{p}(1 - \hat{p})
                    (\frac{1}{c_1} +
                    \frac{1}{c_2})
                }
            }

        with :math:`\hat{p}_1, \hat{p}_2` and :math:`\hat{p}` the estimator of
        :math:`p_1, p_2` and :math:`p`, the latter being the combined probability,
        given the assumption that :math:`p_1 = p_2`.

        If this assumption is invalid (``pooled = False``), the statistic is:

        .. math::

            T(X) = \frac{
                \hat{p}_1 - \hat{p}_2
            }{
                \sqrt{
                    \frac{\hat{p}_1 (1 - \hat{p}_1)}{c_1} +
                    \frac{\hat{p}_2 (1 - \hat{p}_2)}{c_2}
                }
            }

        The p-value is then computed as:

        .. math::

            \sum
                \binom{c_1}{x_{11}}
                \binom{c_2}{x_{12}}
                \pi^{x_{11} + x_{12}}
                (1 - \pi)^{t - x_{11} - x_{12}}

        where the sum is over all  2x2 contingency tables :math:`X` such that:
        * :math:`T(X) \leq T(X_0)` when `alternative` = "less",
        * :math:`T(X) \geq T(X_0)` when `alternative` = "greater", or
        * :math:`T(X) \geq |T(X_0)|` when `alternative` = "two-sided".
        Above, :math:`c_1, c_2` are the sum of the columns 1 and 2,
        and :math:`t` the total (sum of the 4 sample's element).

        The returned p-value is the maximum p-value taken over the nuisance
        parameter :math:`\pi`, where :math:`0 \leq \pi \leq 1`.

        This function's complexity is :math:`O(n c_1 c_2)`, where `n` is the
        number of sample points.

        References
        ----------
        .. [1] Barnard, G. A. "Significance Tests for 2x2 Tables". *Biometrika*.
               34.1/2 (1947): 123-138. :doi:`dpgkg3`

        .. [2] Mehta, Cyrus R., and Pralay Senchaudhuri. "Conditional versus
               unconditional exact tests for comparing two binomials."
               *Cytel Software Corporation* 675 (2003): 1-5.

        .. [3] "Wald Test". *Wikipedia*. https://en.wikipedia.org/wiki/Wald_test

        Examples
        --------
        An example use of Barnard's test is presented in [2]_.

            Consider the following example of a vaccine efficacy study
            (Chan, 1998). In a randomized clinical trial of 30 subjects, 15 were
            inoculated with a recombinant DNA influenza vaccine and the 15 were
            inoculated with a placebo. Twelve of the 15 subjects in the placebo
            group (80%) eventually became infected with influenza whereas for the
            vaccine group, only 7 of the 15 subjects (47%) became infected. The
            data are tabulated as a 2 x 2 table::

                    Vaccine  Placebo
                Yes     7        12
                No      8        3

        When working with statistical hypothesis testing, we usually use a
        threshold probability or significance level upon which we decide
        to reject the null hypothesis :math:`H_0`. Suppose we choose the common
        significance level of 5%.

        Our alternative hypothesis is that the vaccine will lower the chance of
        becoming infected with the virus; that is, the probability :math:`p_1` of
        catching the virus with the vaccine will be *less than* the probability
        :math:`p_2` of catching the virus without the vaccine.  Therefore, we call
        `barnard_exact` with the ``alternative="less"`` option:

        >>> import scipy.stats as stats
        >>> res = stats.barnard_exact([[7, 12], [8, 3]], alternative="less")
        >>> res.statistic
        -1.894
        >>> res.pvalue
        0.03407

        Under the null hypothesis that the vaccine will not lower the chance of
        becoming infected, the probability of obtaining test results at least as
        extreme as the observed data is approximately 3.4%. Since this p-value is
        less than our chosen significance level, we have evidence to reject
        :math:`H_0` in favor of the alternative.

        Suppose we had used Fisher's exact test instead:

        >>> _, pvalue = stats.fisher_exact([[7, 12], [8, 3]], alternative="less")
        >>> pvalue
        0.0640

        With the same threshold significance of 5%, we would not have been able
        to reject the null hypothesis in favor of the alternative. As stated in
        [2]_, Barnard's test is uniformly more powerful than Fisher's exact test
        because Barnard's test does not condition on any margin. Fisher's test
        should only be used when both sets of marginals are fixed.

    bartlett(*samples, axis=0, nan_policy='propagate', keepdims=False)
        Perform Bartlett's test for equal variances.

        Bartlett's test tests the null hypothesis that all input samples
        are from populations with equal variances.  For samples
        from significantly non-normal populations, Levene's test
        `levene` is more robust.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            arrays of sample data.  Only 1d arrays are accepted, they may have
            different lengths.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic.
        pvalue : float
            The p-value of the test.

        See Also
        --------

        :func:`fligner`
            A non-parametric test for the equality of k variances
        :func:`levene`
            A robust parametric test for equality of k variances


        Notes
        -----
        Conover et al. (1981) examine many of the existing parametric and
        nonparametric tests by extensive simulations and they conclude that the
        tests proposed by Fligner and Killeen (1976) and Levene (1960) appear to be
        superior in terms of robustness of departures from normality and power
        ([3]_).

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1]  https://www.itl.nist.gov/div898/handbook/eda/section3/eda357.htm
        .. [2]  Snedecor, George W. and Cochran, William G. (1989), Statistical
                  Methods, Eighth Edition, Iowa State University Press.
        .. [3] Park, C. and Lindsay, B. G. (1999). Robust Scale Estimation and
               Hypothesis Testing based on Quadratic Inference Function. Technical
               Report #99-03, Center for Likelihood Studies, Pennsylvania State
               University.
        .. [4] Bartlett, M. S. (1937). Properties of Sufficiency and Statistical
               Tests. Proceedings of the Royal Society of London. Series A,
               Mathematical and Physical Sciences, Vol. 160, No.901, pp. 268-282.
        .. [5] C.I. BLISS (1952), The Statistics of Bioassay: With Special
               Reference to the Vitamins, pp 499-503,
               :doi:`10.1016/C2013-0-12584-6`.
        .. [6] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [7] Ludbrook, J., & Dudley, H. (1998). Why permutation tests are
               superior to t and F tests in biomedical research. The American
               Statistician, 52(2), 127-132.

        Examples
        --------
        In [5]_, the influence of vitamin C on the tooth growth of guinea pigs
        was investigated. In a control study, 60 subjects were divided into
        small dose, medium dose, and large dose groups that received
        daily doses of 0.5, 1.0 and 2.0 mg of vitamin C, respectively.
        After 42 days, the tooth growth was measured.

        The ``small_dose``, ``medium_dose``, and ``large_dose`` arrays below record
        tooth growth measurements of the three groups in microns.

        >>> import numpy as np
        >>> small_dose = np.array([
        ...     4.2, 11.5, 7.3, 5.8, 6.4, 10, 11.2, 11.2, 5.2, 7,
        ...     15.2, 21.5, 17.6, 9.7, 14.5, 10, 8.2, 9.4, 16.5, 9.7
        ... ])
        >>> medium_dose = np.array([
        ...     16.5, 16.5, 15.2, 17.3, 22.5, 17.3, 13.6, 14.5, 18.8, 15.5,
        ...     19.7, 23.3, 23.6, 26.4, 20, 25.2, 25.8, 21.2, 14.5, 27.3
        ... ])
        >>> large_dose = np.array([
        ...     23.6, 18.5, 33.9, 25.5, 26.4, 32.5, 26.7, 21.5, 23.3, 29.5,
        ...     25.5, 26.4, 22.4, 24.5, 24.8, 30.9, 26.4, 27.3, 29.4, 23
        ... ])

        The `bartlett` statistic is sensitive to differences in variances
        between the samples.

        >>> from scipy import stats
        >>> res = stats.bartlett(small_dose, medium_dose, large_dose)
        >>> res.statistic
        0.6654670663030519

        The value of the statistic tends to be high when there is a large
        difference in variances.

        We can test for inequality of variance among the groups by comparing the
        observed value of the statistic against the null distribution: the
        distribution of statistic values derived under the null hypothesis that
        the population variances of the three groups are equal.

        For this test, the null distribution follows the chi-square distribution
        as shown below.

        >>> import matplotlib.pyplot as plt
        >>> k = 3  # number of samples
        >>> dist = stats.chi2(df=k-1)
        >>> val = np.linspace(0, 5, 100)
        >>> pdf = dist.pdf(val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(val, pdf, color='C0')
        ...     ax.set_title("Bartlett Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        ...     ax.set_xlim(0, 5)
        ...     ax.set_ylim(0, 1)
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution greater than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (1.5, 0.22), (2.25, 0.3), arrowprops=props)
        >>> i = val >= res.statistic
        >>> ax.fill_between(val[i], y1=0, y2=pdf[i], color='C0')
        >>> plt.show()

        >>> res.pvalue
        0.71696121509966

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from distributions with identical variances that produces
        such an extreme value of the statistic - this may be taken as evidence
        against the null hypothesis in favor of the alternative: the variances of
        the groups are not equal. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [6]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).
        - Small p-values are not evidence for a *large* effect; rather, they can
          only provide evidence for a "significant" effect, meaning that they are
          unlikely to have occurred under the null hypothesis.

        Note that the chi-square distribution provides the null distribution
        when the observations are normally distributed. For small samples
        drawn from non-normal populations, it may be more appropriate to
        perform a
        permutation test: Under the null hypothesis that all three samples were
        drawn from the same population, each of the measurements is equally likely
        to have been observed in any of the three samples. Therefore, we can form
        a randomized null distribution by calculating the statistic under many
        randomly-generated partitionings of the observations into the three
        samples.

        >>> def statistic(*samples):
        ...     return stats.bartlett(*samples).statistic
        >>> ref = stats.permutation_test(
        ...     (small_dose, medium_dose, large_dose), statistic,
        ...     permutation_type='independent', alternative='greater'
        ... )
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> bins = np.linspace(0, 5, 25)
        >>> ax.hist(
        ...     ref.null_distribution, bins=bins, density=True, facecolor="C1"
        ... )
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'randomized null distribution'])
        >>> plot(ax)
        >>> plt.show()

        >>> ref.pvalue  # randomized test p-value
        0.5387  # may vary

        Note that there is significant disagreement between the p-value calculated
        here and the asymptotic approximation returned by `bartlett` above.
        The statistical inferences that can be drawn rigorously from a permutation
        test are limited; nonetheless, they may be the preferred approach in many
        circumstances [7]_.

        Following is another generic example where the null hypothesis would be
        rejected.

        Test whether the lists `a`, `b` and `c` come from populations
        with equal variances.

        >>> a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
        >>> b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
        >>> c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
        >>> stat, p = stats.bartlett(a, b, c)
        >>> p
        1.1254782518834628e-05

        The very small p-value suggests that the populations do not have equal
        variances.

        This is not surprising, given that the sample variance of `b` is much
        larger than that of `a` and `c`:

        >>> [np.var(x, ddof=1) for x in [a, b, c]]
        [0.007054444444444413, 0.13073888888888888, 0.008890000000000002]

    bayes_mvs(data, alpha=0.9)
        Bayesian confidence intervals for the mean, var, and std.

        Parameters
        ----------
        data : array_like
            Input data, if multi-dimensional it is flattened to 1-D by `bayes_mvs`.
            Requires 2 or more data points.
        alpha : float, optional
            Probability that the returned confidence interval contains
            the true parameter.

        Returns
        -------
        mean_cntr, var_cntr, std_cntr : tuple
            The three results are for the mean, variance and standard deviation,
            respectively.  Each result is a tuple of the form::

                (center, (lower, upper))

            with `center` the mean of the conditional pdf of the value given the
            data, and `(lower, upper)` a confidence interval, centered on the
            median, containing the estimate to a probability ``alpha``.

        See Also
        --------
        mvsdist

        Notes
        -----
        Each tuple of mean, variance, and standard deviation estimates represent
        the (center, (lower, upper)) with center the mean of the conditional pdf
        of the value given the data and (lower, upper) is a confidence interval
        centered on the median, containing the estimate to a probability
        ``alpha``.

        Converts data to 1-D and assumes all data has the same mean and variance.
        Uses Jeffrey's prior for variance and std.

        Equivalent to ``tuple((x.mean(), x.interval(alpha)) for x in mvsdist(dat))``

        References
        ----------
        T.E. Oliphant, "A Bayesian perspective on estimating mean, variance, and
        standard-deviation from data", https://scholarsarchive.byu.edu/facpub/278,
        2006.

        Examples
        --------
        First a basic example to demonstrate the outputs:

        >>> from scipy import stats
        >>> data = [6, 9, 12, 7, 8, 8, 13]
        >>> mean, var, std = stats.bayes_mvs(data)
        >>> mean
        Mean(statistic=9.0, minmax=(7.103650222612533, 10.896349777387467))
        >>> var
        Variance(statistic=10.0, minmax=(3.176724206, 24.45910382))
        >>> std
        Std_dev(statistic=2.9724954732045084,
                minmax=(1.7823367265645143, 4.945614605014631))

        Now we generate some normally distributed random data, and get estimates of
        mean and standard deviation with 95% confidence intervals for those
        estimates:

        >>> n_samples = 100000
        >>> data = stats.norm.rvs(size=n_samples)
        >>> res_mean, res_var, res_std = stats.bayes_mvs(data, alpha=0.95)

        >>> import matplotlib.pyplot as plt
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.hist(data, bins=100, density=True, label='Histogram of data')
        >>> ax.vlines(res_mean.statistic, 0, 0.5, colors='r', label='Estimated mean')
        >>> ax.axvspan(res_mean.minmax[0],res_mean.minmax[1], facecolor='r',
        ...            alpha=0.2, label=r'Estimated mean (95% limits)')
        >>> ax.vlines(res_std.statistic, 0, 0.5, colors='g', label='Estimated scale')
        >>> ax.axvspan(res_std.minmax[0],res_std.minmax[1], facecolor='g', alpha=0.2,
        ...            label=r'Estimated scale (95% limits)')

        >>> ax.legend(fontsize=10)
        >>> ax.set_xlim([-4, 4])
        >>> ax.set_ylim([0, 0.5])
        >>> plt.show()

    binned_statistic(x, values, statistic='mean', bins=10, range=None)
        Compute a binned statistic for one or more sets of data.

        This is a generalization of a histogram function.  A histogram divides
        the space into bins, and returns the count of the number of points in
        each bin.  This function allows the computation of the sum, mean, median,
        or other statistic of the values (or set of values) within each bin.

        Parameters
        ----------
        x : (N,) array_like
            A sequence of values to be binned.
        values : (N,) array_like or list of (N,) array_like
            The data on which the statistic will be computed.  This must be
            the same shape as `x`, or a set of sequences - each the same shape as
            `x`.  If `values` is a set of sequences, the statistic will be computed
            on each independently.
        statistic : string or callable, optional
            The statistic to compute (default is 'mean').
            The following statistics are available:

              * 'mean' : compute the mean of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'std' : compute the standard deviation within each bin. This
                is implicitly calculated with ddof=0.
              * 'median' : compute the median of values for points within each
                bin. Empty bins will be represented by NaN.
              * 'count' : compute the count of points within each bin.  This is
                identical to an unweighted histogram.  `values` array is not
                referenced.
              * 'sum' : compute the sum of values for points within each bin.
                This is identical to a weighted histogram.
              * 'min' : compute the minimum of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'max' : compute the maximum of values for point within each bin.
                Empty bins will be represented by NaN.
              * function : a user-defined function which takes a 1D array of
                values, and outputs a single numerical statistic. This function
                will be called on the values in each bin.  Empty bins will be
                represented by function([]), or NaN if this returns an error.

        bins : int or sequence of scalars, optional
            If `bins` is an int, it defines the number of equal-width bins in the
            given range (10 by default).  If `bins` is a sequence, it defines the
            bin edges, including the rightmost edge, allowing for non-uniform bin
            widths.  Values in `x` that are smaller than lowest bin edge are
            assigned to bin number 0, values beyond the highest bin are assigned to
            ``bins[-1]``.  If the bin edges are specified, the number of bins will
            be, (nx = len(bins)-1).
        range : (float, float) or [(float, float)], optional
            The lower and upper range of the bins.  If not provided, range
            is simply ``(x.min(), x.max())``.  Values outside the range are
            ignored.

        Returns
        -------
        statistic : array
            The values of the selected statistic in each bin.
        bin_edges : array of dtype float
            Return the bin edges ``(length(statistic)+1)``.
        binnumber: 1-D ndarray of ints
            Indices of the bins (corresponding to `bin_edges`) in which each value
            of `x` belongs.  Same length as `values`.  A binnumber of `i` means the
            corresponding value is between (bin_edges[i-1], bin_edges[i]).

        See Also
        --------
        numpy.digitize, numpy.histogram, binned_statistic_2d, binned_statistic_dd

        Notes
        -----
        All but the last (righthand-most) bin is half-open.  In other words, if
        `bins` is ``[1, 2, 3, 4]``, then the first bin is ``[1, 2)`` (including 1,
        but excluding 2) and the second ``[2, 3)``.  The last bin, however, is
        ``[3, 4]``, which *includes* 4.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        First some basic examples:

        Create two evenly spaced bins in the range of the given sample, and sum the
        corresponding values in each of those bins:

        >>> values = [1.0, 1.0, 2.0, 1.5, 3.0]
        >>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
        BinnedStatisticResult(statistic=array([4. , 4.5]),
                bin_edges=array([1., 4., 7.]), binnumber=array([1, 1, 1, 2, 2]))

        Multiple arrays of values can also be passed.  The statistic is calculated
        on each set independently:

        >>> values = [[1.0, 1.0, 2.0, 1.5, 3.0], [2.0, 2.0, 4.0, 3.0, 6.0]]
        >>> stats.binned_statistic([1, 1, 2, 5, 7], values, 'sum', bins=2)
        BinnedStatisticResult(statistic=array([[4. , 4.5],
               [8. , 9. ]]), bin_edges=array([1., 4., 7.]),
               binnumber=array([1, 1, 1, 2, 2]))

        >>> stats.binned_statistic([1, 2, 1, 2, 4], np.arange(5), statistic='mean',
        ...                        bins=3)
        BinnedStatisticResult(statistic=array([1., 2., 4.]),
                bin_edges=array([1., 2., 3., 4.]),
                binnumber=array([1, 2, 1, 2, 3]))

        As a second example, we now generate some random data of sailing boat speed
        as a function of wind speed, and then determine how fast our boat is for
        certain wind speeds:

        >>> rng = np.random.default_rng()
        >>> windspeed = 8 * rng.random(500)
        >>> boatspeed = .3 * windspeed**.5 + .2 * rng.random(500)
        >>> bin_means, bin_edges, binnumber = stats.binned_statistic(windspeed,
        ...                 boatspeed, statistic='median', bins=[1,2,3,4,5,6,7])
        >>> plt.figure()
        >>> plt.plot(windspeed, boatspeed, 'b.', label='raw data')
        >>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=5,
        ...            label='binned statistic of data')
        >>> plt.legend()

        Now we can use ``binnumber`` to select all datapoints with a windspeed
        below 1:

        >>> low_boatspeed = boatspeed[binnumber == 0]

        As a final example, we will use ``bin_edges`` and ``binnumber`` to make a
        plot of a distribution that shows the mean and distribution around that
        mean per bin, on top of a regular histogram and the probability
        distribution function:

        >>> x = np.linspace(0, 5, num=500)
        >>> x_pdf = stats.maxwell.pdf(x)
        >>> samples = stats.maxwell.rvs(size=10000)

        >>> bin_means, bin_edges, binnumber = stats.binned_statistic(x, x_pdf,
        ...         statistic='mean', bins=25)
        >>> bin_width = (bin_edges[1] - bin_edges[0])
        >>> bin_centers = bin_edges[1:] - bin_width/2

        >>> plt.figure()
        >>> plt.hist(samples, bins=50, density=True, histtype='stepfilled',
        ...          alpha=0.2, label='histogram of data')
        >>> plt.plot(x, x_pdf, 'r-', label='analytical pdf')
        >>> plt.hlines(bin_means, bin_edges[:-1], bin_edges[1:], colors='g', lw=2,
        ...            label='binned statistic of data')
        >>> plt.plot((binnumber - 0.5) * bin_width, x_pdf, 'g.', alpha=0.5)
        >>> plt.legend(fontsize=10)
        >>> plt.show()

    binned_statistic_2d(x, y, values, statistic='mean', bins=10, range=None, expand_binnumbers=False)
        Compute a bidimensional binned statistic for one or more sets of data.

        This is a generalization of a histogram2d function.  A histogram divides
        the space into bins, and returns the count of the number of points in
        each bin.  This function allows the computation of the sum, mean, median,
        or other statistic of the values (or set of values) within each bin.

        Parameters
        ----------
        x : (N,) array_like
            A sequence of values to be binned along the first dimension.
        y : (N,) array_like
            A sequence of values to be binned along the second dimension.
        values : (N,) array_like or list of (N,) array_like
            The data on which the statistic will be computed.  This must be
            the same shape as `x`, or a list of sequences - each with the same
            shape as `x`.  If `values` is such a list, the statistic will be
            computed on each independently.
        statistic : string or callable, optional
            The statistic to compute (default is 'mean').
            The following statistics are available:

              * 'mean' : compute the mean of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'std' : compute the standard deviation within each bin. This
                is implicitly calculated with ddof=0.
              * 'median' : compute the median of values for points within each
                bin. Empty bins will be represented by NaN.
              * 'count' : compute the count of points within each bin.  This is
                identical to an unweighted histogram.  `values` array is not
                referenced.
              * 'sum' : compute the sum of values for points within each bin.
                This is identical to a weighted histogram.
              * 'min' : compute the minimum of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'max' : compute the maximum of values for point within each bin.
                Empty bins will be represented by NaN.
              * function : a user-defined function which takes a 1D array of
                values, and outputs a single numerical statistic. This function
                will be called on the values in each bin.  Empty bins will be
                represented by function([]), or NaN if this returns an error.

        bins : int or [int, int] or array_like or [array, array], optional
            The bin specification:

              * the number of bins for the two dimensions (nx = ny = bins),
              * the number of bins in each dimension (nx, ny = bins),
              * the bin edges for the two dimensions (x_edge = y_edge = bins),
              * the bin edges in each dimension (x_edge, y_edge = bins).

            If the bin edges are specified, the number of bins will be,
            (nx = len(x_edge)-1, ny = len(y_edge)-1).

        range : (2,2) array_like, optional
            The leftmost and rightmost edges of the bins along each dimension
            (if not specified explicitly in the `bins` parameters):
            [[xmin, xmax], [ymin, ymax]]. All values outside of this range will be
            considered outliers and not tallied in the histogram.
        expand_binnumbers : bool, optional
            'False' (default): the returned `binnumber` is a shape (N,) array of
            linearized bin indices.
            'True': the returned `binnumber` is 'unraveled' into a shape (2,N)
            ndarray, where each row gives the bin numbers in the corresponding
            dimension.
            See the `binnumber` returned value, and the `Examples` section.

            .. versionadded:: 0.17.0

        Returns
        -------
        statistic : (nx, ny) ndarray
            The values of the selected statistic in each two-dimensional bin.
        x_edge : (nx + 1) ndarray
            The bin edges along the first dimension.
        y_edge : (ny + 1) ndarray
            The bin edges along the second dimension.
        binnumber : (N,) array of ints or (2,N) ndarray of ints
            This assigns to each element of `sample` an integer that represents the
            bin in which this observation falls.  The representation depends on the
            `expand_binnumbers` argument.  See `Notes` for details.


        See Also
        --------
        numpy.digitize, numpy.histogram2d, binned_statistic, binned_statistic_dd

        Notes
        -----
        Binedges:
        All but the last (righthand-most) bin is half-open.  In other words, if
        `bins` is ``[1, 2, 3, 4]``, then the first bin is ``[1, 2)`` (including 1,
        but excluding 2) and the second ``[2, 3)``.  The last bin, however, is
        ``[3, 4]``, which *includes* 4.

        `binnumber`:
        This returned argument assigns to each element of `sample` an integer that
        represents the bin in which it belongs.  The representation depends on the
        `expand_binnumbers` argument. If 'False' (default): The returned
        `binnumber` is a shape (N,) array of linearized indices mapping each
        element of `sample` to its corresponding bin (using row-major ordering).
        Note that the returned linearized bin indices are used for an array with
        extra bins on the outer binedges to capture values outside of the defined
        bin bounds.
        If 'True': The returned `binnumber` is a shape (2,N) ndarray where
        each row indicates bin placements for each dimension respectively.  In each
        dimension, a binnumber of `i` means the corresponding value is between
        (D_edge[i-1], D_edge[i]), where 'D' is either 'x' or 'y'.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> from scipy import stats

        Calculate the counts with explicit bin-edges:

        >>> x = [0.1, 0.1, 0.1, 0.6]
        >>> y = [2.1, 2.6, 2.1, 2.1]
        >>> binx = [0.0, 0.5, 1.0]
        >>> biny = [2.0, 2.5, 3.0]
        >>> ret = stats.binned_statistic_2d(x, y, None, 'count', bins=[binx, biny])
        >>> ret.statistic
        array([[2., 1.],
               [1., 0.]])

        The bin in which each sample is placed is given by the `binnumber`
        returned parameter.  By default, these are the linearized bin indices:

        >>> ret.binnumber
        array([5, 6, 5, 9])

        The bin indices can also be expanded into separate entries for each
        dimension using the `expand_binnumbers` parameter:

        >>> ret = stats.binned_statistic_2d(x, y, None, 'count', bins=[binx, biny],
        ...                                 expand_binnumbers=True)
        >>> ret.binnumber
        array([[1, 1, 1, 2],
               [1, 2, 1, 1]])

        Which shows that the first three elements belong in the xbin 1, and the
        fourth into xbin 2; and so on for y.

    binned_statistic_dd(sample, values, statistic='mean', bins=10, range=None, expand_binnumbers=False, binned_statistic_result=None)
        Compute a multidimensional binned statistic for a set of data.

        This is a generalization of a histogramdd function.  A histogram divides
        the space into bins, and returns the count of the number of points in
        each bin.  This function allows the computation of the sum, mean, median,
        or other statistic of the values within each bin.

        Parameters
        ----------
        sample : array_like
            Data to histogram passed as a sequence of N arrays of length D, or
            as an (N,D) array.
        values : (N,) array_like or list of (N,) array_like
            The data on which the statistic will be computed.  This must be
            the same shape as `sample`, or a list of sequences - each with the
            same shape as `sample`.  If `values` is such a list, the statistic
            will be computed on each independently.
        statistic : string or callable, optional
            The statistic to compute (default is 'mean').
            The following statistics are available:

              * 'mean' : compute the mean of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'median' : compute the median of values for points within each
                bin. Empty bins will be represented by NaN.
              * 'count' : compute the count of points within each bin.  This is
                identical to an unweighted histogram.  `values` array is not
                referenced.
              * 'sum' : compute the sum of values for points within each bin.
                This is identical to a weighted histogram.
              * 'std' : compute the standard deviation within each bin. This
                is implicitly calculated with ddof=0. If the number of values
                within a given bin is 0 or 1, the computed standard deviation value
                will be 0 for the bin.
              * 'min' : compute the minimum of values for points within each bin.
                Empty bins will be represented by NaN.
              * 'max' : compute the maximum of values for point within each bin.
                Empty bins will be represented by NaN.
              * function : a user-defined function which takes a 1D array of
                values, and outputs a single numerical statistic. This function
                will be called on the values in each bin.  Empty bins will be
                represented by function([]), or NaN if this returns an error.

        bins : sequence or positive int, optional
            The bin specification must be in one of the following forms:

              * A sequence of arrays describing the bin edges along each dimension.
              * The number of bins for each dimension (nx, ny, ... = bins).
              * The number of bins for all dimensions (nx = ny = ... = bins).
        range : sequence, optional
            A sequence of lower and upper bin edges to be used if the edges are
            not given explicitly in `bins`. Defaults to the minimum and maximum
            values along each dimension.
        expand_binnumbers : bool, optional
            'False' (default): the returned `binnumber` is a shape (N,) array of
            linearized bin indices.
            'True': the returned `binnumber` is 'unraveled' into a shape (D,N)
            ndarray, where each row gives the bin numbers in the corresponding
            dimension.
            See the `binnumber` returned value, and the `Examples` section of
            `binned_statistic_2d`.
        binned_statistic_result : binnedStatisticddResult
            Result of a previous call to the function in order to reuse bin edges
            and bin numbers with new values and/or a different statistic.
            To reuse bin numbers, `expand_binnumbers` must have been set to False
            (the default)

            .. versionadded:: 0.17.0

        Returns
        -------
        statistic : ndarray, shape(nx1, nx2, nx3,...)
            The values of the selected statistic in each two-dimensional bin.
        bin_edges : list of ndarrays
            A list of D arrays describing the (nxi + 1) bin edges for each
            dimension.
        binnumber : (N,) array of ints or (D,N) ndarray of ints
            This assigns to each element of `sample` an integer that represents the
            bin in which this observation falls.  The representation depends on the
            `expand_binnumbers` argument.  See `Notes` for details.


        See Also
        --------
        numpy.digitize, numpy.histogramdd, binned_statistic, binned_statistic_2d

        Notes
        -----
        Binedges:
        All but the last (righthand-most) bin is half-open in each dimension.  In
        other words, if `bins` is ``[1, 2, 3, 4]``, then the first bin is
        ``[1, 2)`` (including 1, but excluding 2) and the second ``[2, 3)``.  The
        last bin, however, is ``[3, 4]``, which *includes* 4.

        `binnumber`:
        This returned argument assigns to each element of `sample` an integer that
        represents the bin in which it belongs.  The representation depends on the
        `expand_binnumbers` argument. If 'False' (default): The returned
        `binnumber` is a shape (N,) array of linearized indices mapping each
        element of `sample` to its corresponding bin (using row-major ordering).
        If 'True': The returned `binnumber` is a shape (D,N) ndarray where
        each row indicates bin placements for each dimension respectively.  In each
        dimension, a binnumber of `i` means the corresponding value is between
        (bin_edges[D][i-1], bin_edges[D][i]), for each dimension 'D'.

        .. versionadded:: 0.11.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.mplot3d import Axes3D

        Take an array of 600 (x, y) coordinates as an example.
        `binned_statistic_dd` can handle arrays of higher dimension `D`. But a plot
        of dimension `D+1` is required.

        >>> mu = np.array([0., 1.])
        >>> sigma = np.array([[1., -0.5],[-0.5, 1.5]])
        >>> multinormal = stats.multivariate_normal(mu, sigma)
        >>> data = multinormal.rvs(size=600, random_state=235412)
        >>> data.shape
        (600, 2)

        Create bins and count how many arrays fall in each bin:

        >>> N = 60
        >>> x = np.linspace(-3, 3, N)
        >>> y = np.linspace(-3, 4, N)
        >>> ret = stats.binned_statistic_dd(data, np.arange(600), bins=[x, y],
        ...                                 statistic='count')
        >>> bincounts = ret.statistic

        Set the volume and the location of bars:

        >>> dx = x[1] - x[0]
        >>> dy = y[1] - y[0]
        >>> x, y = np.meshgrid(x[:-1]+dx/2, y[:-1]+dy/2)
        >>> z = 0

        >>> bincounts = bincounts.ravel()
        >>> x = x.ravel()
        >>> y = y.ravel()

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111, projection='3d')
        >>> with np.errstate(divide='ignore'):   # silence random axes3d warning
        ...     ax.bar3d(x, y, z, dx, dy, bincounts)

        Reuse bin numbers and bin edges with new values:

        >>> ret2 = stats.binned_statistic_dd(data, -np.arange(600),
        ...                                  binned_statistic_result=ret,
        ...                                  statistic='mean')

    binomtest(k, n, p=0.5, alternative='two-sided')
        Perform a test that the probability of success is p.

        The binomial test [1]_ is a test of the null hypothesis that the
        probability of success in a Bernoulli experiment is `p`.

        Details of the test can be found in many texts on statistics, such
        as section 24.5 of [2]_.

        Parameters
        ----------
        k : int
            The number of successes.
        n : int
            The number of trials.
        p : float, optional
            The hypothesized probability of success, i.e. the expected
            proportion of successes.  The value must be in the interval
            ``0 <= p <= 1``. The default value is ``p = 0.5``.
        alternative : {'two-sided', 'greater', 'less'}, optional
            Indicates the alternative hypothesis. The default value is
            'two-sided'.

        Returns
        -------
        result : `~scipy.stats._result_classes.BinomTestResult` instance
            The return value is an object with the following attributes:

            k : int
                The number of successes (copied from `binomtest` input).
            n : int
                The number of trials (copied from `binomtest` input).
            alternative : str
                Indicates the alternative hypothesis specified in the input
                to `binomtest`.  It will be one of ``'two-sided'``, ``'greater'``,
                or ``'less'``.
            statistic : float
                The estimate of the proportion of successes.
            pvalue : float
                The p-value of the hypothesis test.

            The object has the following methods:

            proportion_ci(confidence_level=0.95, method='exact') :
                Compute the confidence interval for ``statistic``.

        Notes
        -----
        .. versionadded:: 1.7.0

        References
        ----------
        .. [1] Binomial test, https://en.wikipedia.org/wiki/Binomial_test
        .. [2] Jerrold H. Zar, Biostatistical Analysis (fifth edition),
               Prentice Hall, Upper Saddle River, New Jersey USA (2010)

        Examples
        --------
        >>> from scipy.stats import binomtest

        A car manufacturer claims that no more than 10% of their cars are unsafe.
        15 cars are inspected for safety, 3 were found to be unsafe. Test the
        manufacturer's claim:

        >>> result = binomtest(3, n=15, p=0.1, alternative='greater')
        >>> result.pvalue
        0.18406106910639114

        The null hypothesis cannot be rejected at the 5% level of significance
        because the returned p-value is greater than the critical value of 5%.

        The test statistic is equal to the estimated proportion, which is simply
        ``3/15``:

        >>> result.statistic
        0.2

        We can use the `proportion_ci()` method of the result to compute the
        confidence interval of the estimate:

        >>> result.proportion_ci(confidence_level=0.95)
        ConfidenceInterval(low=0.05684686759024681, high=1.0)

    bootstrap(data, statistic, *, n_resamples=9999, batch=None, vectorized=None, paired=False, axis=0, confidence_level=0.95, alternative='two-sided', method='BCa', bootstrap_result=None, random_state=None)
        Compute a two-sided bootstrap confidence interval of a statistic.

        When `method` is ``'percentile'`` and `alternative` is ``'two-sided'``,
        a bootstrap confidence interval is computed according to the following
        procedure.

        1. Resample the data: for each sample in `data` and for each of
           `n_resamples`, take a random sample of the original sample
           (with replacement) of the same size as the original sample.

        2. Compute the bootstrap distribution of the statistic: for each set of
           resamples, compute the test statistic.

        3. Determine the confidence interval: find the interval of the bootstrap
           distribution that is

           - symmetric about the median and
           - contains `confidence_level` of the resampled statistic values.

        While the ``'percentile'`` method is the most intuitive, it is rarely
        used in practice. Two more common methods are available, ``'basic'``
        ('reverse percentile') and ``'BCa'`` ('bias-corrected and accelerated');
        they differ in how step 3 is performed.

        If the samples in `data` are  taken at random from their respective
        distributions :math:`n` times, the confidence interval returned by
        `bootstrap` will contain the true value of the statistic for those
        distributions approximately `confidence_level`:math:`\, \times \, n` times.

        Parameters
        ----------
        data : sequence of array-like
             Each element of `data` is a sample containing scalar observations from an
             underlying distribution. Elements of `data` must be broadcastable to the
             same shape (with the possible exception of the dimension specified by `axis`).

             .. versionchanged:: 1.14.0
                 `bootstrap` will now emit a ``FutureWarning`` if the shapes of the
                 elements of `data` are not the same (with the exception of the dimension
                 specified by `axis`).
                 Beginning in SciPy 1.16.0, `bootstrap` will explicitly broadcast the
                 elements to the same shape (except along `axis`) before performing
                 the calculation.

        statistic : callable
            Statistic for which the confidence interval is to be calculated.
            `statistic` must be a callable that accepts ``len(data)`` samples
            as separate arguments and returns the resulting statistic.
            If `vectorized` is set ``True``,
            `statistic` must also accept a keyword argument `axis` and be
            vectorized to compute the statistic along the provided `axis`.
        n_resamples : int, default: ``9999``
            The number of resamples performed to form the bootstrap distribution
            of the statistic.
        batch : int, optional
            The number of resamples to process in each vectorized call to
            `statistic`. Memory usage is O( `batch` * ``n`` ), where ``n`` is the
            sample size. Default is ``None``, in which case ``batch = n_resamples``
            (or ``batch = max(n_resamples, n)`` for ``method='BCa'``).
        vectorized : bool, optional
            If `vectorized` is set ``False``, `statistic` will not be passed
            keyword argument `axis` and is expected to calculate the statistic
            only for 1D samples. If ``True``, `statistic` will be passed keyword
            argument `axis` and is expected to calculate the statistic along `axis`
            when passed an ND sample array. If ``None`` (default), `vectorized`
            will be set ``True`` if ``axis`` is a parameter of `statistic`. Use of
            a vectorized statistic typically reduces computation time.
        paired : bool, default: ``False``
            Whether the statistic treats corresponding elements of the samples
            in `data` as paired.
        axis : int, default: ``0``
            The axis of the samples in `data` along which the `statistic` is
            calculated.
        confidence_level : float, default: ``0.95``
            The confidence level of the confidence interval.
        alternative : {'two-sided', 'less', 'greater'}, default: ``'two-sided'``
            Choose ``'two-sided'`` (default) for a two-sided confidence interval,
            ``'less'`` for a one-sided confidence interval with the lower bound
            at ``-np.inf``, and ``'greater'`` for a one-sided confidence interval
            with the upper bound at ``np.inf``. The other bound of the one-sided
            confidence intervals is the same as that of a two-sided confidence
            interval with `confidence_level` twice as far from 1.0; e.g. the upper
            bound of a 95% ``'less'``  confidence interval is the same as the upper
            bound of a 90% ``'two-sided'`` confidence interval.
        method : {'percentile', 'basic', 'bca'}, default: ``'BCa'``
            Whether to return the 'percentile' bootstrap confidence interval
            (``'percentile'``), the 'basic' (AKA 'reverse') bootstrap confidence
            interval (``'basic'``), or the bias-corrected and accelerated bootstrap
            confidence interval (``'BCa'``).
        bootstrap_result : BootstrapResult, optional
            Provide the result object returned by a previous call to `bootstrap`
            to include the previous bootstrap distribution in the new bootstrap
            distribution. This can be used, for example, to change
            `confidence_level`, change `method`, or see the effect of performing
            additional resampling without repeating computations.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            Pseudorandom number generator state used to generate resamples.

            If `random_state` is ``None`` (or `np.random`), the
            `numpy.random.RandomState` singleton is used.
            If `random_state` is an int, a new ``RandomState`` instance is used,
            seeded with `random_state`.
            If `random_state` is already a ``Generator`` or ``RandomState``
            instance then that instance is used.

        Returns
        -------
        res : BootstrapResult
            An object with attributes:

            confidence_interval : ConfidenceInterval
                The bootstrap confidence interval as an instance of
                `collections.namedtuple` with attributes `low` and `high`.
            bootstrap_distribution : ndarray
                The bootstrap distribution, that is, the value of `statistic` for
                each resample. The last dimension corresponds with the resamples
                (e.g. ``res.bootstrap_distribution.shape[-1] == n_resamples``).
            standard_error : float or ndarray
                The bootstrap standard error, that is, the sample standard
                deviation of the bootstrap distribution.

        Warns
        -----
        `~scipy.stats.DegenerateDataWarning`
            Generated when ``method='BCa'`` and the bootstrap distribution is
            degenerate (e.g. all elements are identical).

        Notes
        -----
        Elements of the confidence interval may be NaN for ``method='BCa'`` if
        the bootstrap distribution is degenerate (e.g. all elements are identical).
        In this case, consider using another `method` or inspecting `data` for
        indications that other analysis may be more appropriate (e.g. all
        observations are identical).

        References
        ----------
        .. [1] B. Efron and R. J. Tibshirani, An Introduction to the Bootstrap,
           Chapman & Hall/CRC, Boca Raton, FL, USA (1993)
        .. [2] Nathaniel E. Helwig, "Bootstrap Confidence Intervals",
           http://users.stat.umn.edu/~helwig/notes/bootci-Notes.pdf
        .. [3] Bootstrapping (statistics), Wikipedia,
           https://en.wikipedia.org/wiki/Bootstrapping_%28statistics%29

        Examples
        --------
        Suppose we have sampled data from an unknown distribution.

        >>> import numpy as np
        >>> rng = np.random.default_rng()
        >>> from scipy.stats import norm
        >>> dist = norm(loc=2, scale=4)  # our "unknown" distribution
        >>> data = dist.rvs(size=100, random_state=rng)

        We are interested in the standard deviation of the distribution.

        >>> std_true = dist.std()      # the true value of the statistic
        >>> print(std_true)
        4.0
        >>> std_sample = np.std(data)  # the sample statistic
        >>> print(std_sample)
        3.9460644295563863

        The bootstrap is used to approximate the variability we would expect if we
        were to repeatedly sample from the unknown distribution and calculate the
        statistic of the sample each time. It does this by repeatedly resampling
        values *from the original sample* with replacement and calculating the
        statistic of each resample. This results in a "bootstrap distribution" of
        the statistic.

        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import bootstrap
        >>> data = (data,)  # samples must be in a sequence
        >>> res = bootstrap(data, np.std, confidence_level=0.9,
        ...                 random_state=rng)
        >>> fig, ax = plt.subplots()
        >>> ax.hist(res.bootstrap_distribution, bins=25)
        >>> ax.set_title('Bootstrap Distribution')
        >>> ax.set_xlabel('statistic value')
        >>> ax.set_ylabel('frequency')
        >>> plt.show()

        The standard error quantifies this variability. It is calculated as the
        standard deviation of the bootstrap distribution.

        >>> res.standard_error
        0.24427002125829136
        >>> res.standard_error == np.std(res.bootstrap_distribution, ddof=1)
        True

        The bootstrap distribution of the statistic is often approximately normal
        with scale equal to the standard error.

        >>> x = np.linspace(3, 5)
        >>> pdf = norm.pdf(x, loc=std_sample, scale=res.standard_error)
        >>> fig, ax = plt.subplots()
        >>> ax.hist(res.bootstrap_distribution, bins=25, density=True)
        >>> ax.plot(x, pdf)
        >>> ax.set_title('Normal Approximation of the Bootstrap Distribution')
        >>> ax.set_xlabel('statistic value')
        >>> ax.set_ylabel('pdf')
        >>> plt.show()

        This suggests that we could construct a 90% confidence interval on the
        statistic based on quantiles of this normal distribution.

        >>> norm.interval(0.9, loc=std_sample, scale=res.standard_error)
        (3.5442759991341726, 4.3478528599786)

        Due to central limit theorem, this normal approximation is accurate for a
        variety of statistics and distributions underlying the samples; however,
        the approximation is not reliable in all cases. Because `bootstrap` is
        designed to work with arbitrary underlying distributions and statistics,
        it uses more advanced techniques to generate an accurate confidence
        interval.

        >>> print(res.confidence_interval)
        ConfidenceInterval(low=3.57655333533867, high=4.382043696342881)

        If we sample from the original distribution 100 times and form a bootstrap
        confidence interval for each sample, the confidence interval
        contains the true value of the statistic approximately 90% of the time.

        >>> n_trials = 100
        >>> ci_contains_true_std = 0
        >>> for i in range(n_trials):
        ...    data = (dist.rvs(size=100, random_state=rng),)
        ...    res = bootstrap(data, np.std, confidence_level=0.9,
        ...                    n_resamples=999, random_state=rng)
        ...    ci = res.confidence_interval
        ...    if ci[0] < std_true < ci[1]:
        ...        ci_contains_true_std += 1
        >>> print(ci_contains_true_std)
        88

        Rather than writing a loop, we can also determine the confidence intervals
        for all 100 samples at once.

        >>> data = (dist.rvs(size=(n_trials, 100), random_state=rng),)
        >>> res = bootstrap(data, np.std, axis=-1, confidence_level=0.9,
        ...                 n_resamples=999, random_state=rng)
        >>> ci_l, ci_u = res.confidence_interval

        Here, `ci_l` and `ci_u` contain the confidence interval for each of the
        ``n_trials = 100`` samples.

        >>> print(ci_l[:5])
        [3.86401283 3.33304394 3.52474647 3.54160981 3.80569252]
        >>> print(ci_u[:5])
        [4.80217409 4.18143252 4.39734707 4.37549713 4.72843584]

        And again, approximately 90% contain the true value, ``std_true = 4``.

        >>> print(np.sum((ci_l < std_true) & (std_true < ci_u)))
        93

        `bootstrap` can also be used to estimate confidence intervals of
        multi-sample statistics. For example, to get a confidence interval
        for the difference between means, we write a function that accepts
        two sample arguments and returns only the statistic. The use of the
        ``axis`` argument ensures that all mean calculations are perform in
        a single vectorized call, which is faster than looping over pairs
        of resamples in Python.

        >>> def my_statistic(sample1, sample2, axis=-1):
        ...     mean1 = np.mean(sample1, axis=axis)
        ...     mean2 = np.mean(sample2, axis=axis)
        ...     return mean1 - mean2

        Here, we use the 'percentile' method with the default 95% confidence level.

        >>> sample1 = norm.rvs(scale=1, size=100, random_state=rng)
        >>> sample2 = norm.rvs(scale=2, size=100, random_state=rng)
        >>> data = (sample1, sample2)
        >>> res = bootstrap(data, my_statistic, method='basic', random_state=rng)
        >>> print(my_statistic(sample1, sample2))
        0.16661030792089523
        >>> print(res.confidence_interval)
        ConfidenceInterval(low=-0.29087973240818693, high=0.6371338699912273)

        The bootstrap estimate of the standard error is also available.

        >>> print(res.standard_error)
        0.238323948262459

        Paired-sample statistics work, too. For example, consider the Pearson
        correlation coefficient.

        >>> from scipy.stats import pearsonr
        >>> n = 100
        >>> x = np.linspace(0, 10, n)
        >>> y = x + rng.uniform(size=n)
        >>> print(pearsonr(x, y)[0])  # element 0 is the statistic
        0.9954306665125647

        We wrap `pearsonr` so that it returns only the statistic, ensuring
        that we use the `axis` argument because it is available.

        >>> def my_statistic(x, y, axis=-1):
        ...     return pearsonr(x, y, axis=axis)[0]

        We call `bootstrap` using ``paired=True``.

        >>> res = bootstrap((x, y), my_statistic, paired=True, random_state=rng)
        >>> print(res.confidence_interval)
        ConfidenceInterval(low=0.9941504301315878, high=0.996377412215445)

        The result object can be passed back into `bootstrap` to perform additional
        resampling:

        >>> len(res.bootstrap_distribution)
        9999
        >>> res = bootstrap((x, y), my_statistic, paired=True,
        ...                 n_resamples=1000, random_state=rng,
        ...                 bootstrap_result=res)
        >>> len(res.bootstrap_distribution)
        10999

        or to change the confidence interval options:

        >>> res2 = bootstrap((x, y), my_statistic, paired=True,
        ...                  n_resamples=0, random_state=rng, bootstrap_result=res,
        ...                  method='percentile', confidence_level=0.9)
        >>> np.testing.assert_equal(res2.bootstrap_distribution,
        ...                         res.bootstrap_distribution)
        >>> res.confidence_interval
        ConfidenceInterval(low=0.9941574828235082, high=0.9963781698210212)

        without repeating computation of the original bootstrap distribution.

    boschloo_exact(table, alternative='two-sided', n=32)
        Perform Boschloo's exact test on a 2x2 contingency table.

        Parameters
        ----------
        table : array_like of ints
            A 2x2 contingency table.  Elements should be non-negative integers.

        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the null and alternative hypotheses. Default is 'two-sided'.
            Please see explanations in the Notes section below.

        n : int, optional
            Number of sampling points used in the construction of the sampling
            method. Note that this argument will automatically be converted to
            the next higher power of 2 since `scipy.stats.qmc.Sobol` is used to
            select sample points. Default is 32. Must be positive. In most cases,
            32 points is enough to reach good precision. More points comes at
            performance cost.

        Returns
        -------
        ber : BoschlooExactResult
            A result object with the following attributes.

            statistic : float
                The statistic used in Boschloo's test; that is, the p-value
                from Fisher's exact test.

            pvalue : float
                P-value, the probability of obtaining a distribution at least as
                extreme as the one that was actually observed, assuming that the
                null hypothesis is true.

        See Also
        --------
        chi2_contingency : Chi-square test of independence of variables in a
            contingency table.
        fisher_exact : Fisher exact test on a 2x2 contingency table.
        barnard_exact : Barnard's exact test, which is a more powerful alternative
            than Fisher's exact test for 2x2 contingency tables.

        Notes
        -----
        Boschloo's test is an exact test used in the analysis of contingency
        tables. It examines the association of two categorical variables, and
        is a uniformly more powerful alternative to Fisher's exact test
        for 2x2 contingency tables.

        Boschloo's exact test uses the p-value of Fisher's exact test as a
        statistic, and Boschloo's p-value is the probability under the null
        hypothesis of observing such an extreme value of this statistic.

        Let's define :math:`X_0` a 2x2 matrix representing the observed sample,
        where each column stores the binomial experiment, as in the example
        below. Let's also define :math:`p_1, p_2` the theoretical binomial
        probabilities for  :math:`x_{11}` and :math:`x_{12}`. When using
        Boschloo exact test, we can assert three different alternative hypotheses:

        - :math:`H_0 : p_1=p_2` versus :math:`H_1 : p_1 < p_2`,
          with `alternative` = "less"

        - :math:`H_0 : p_1=p_2` versus :math:`H_1 : p_1 > p_2`,
          with `alternative` = "greater"

        - :math:`H_0 : p_1=p_2` versus :math:`H_1 : p_1 \neq p_2`,
          with `alternative` = "two-sided" (default)

        There are multiple conventions for computing a two-sided p-value when the
        null distribution is asymmetric. Here, we apply the convention that the
        p-value of a two-sided test is twice the minimum of the p-values of the
        one-sided tests (clipped to 1.0). Note that `fisher_exact` follows a
        different convention, so for a given `table`, the statistic reported by
        `boschloo_exact` may differ from the p-value reported by `fisher_exact`
        when ``alternative='two-sided'``.

        .. versionadded:: 1.7.0

        References
        ----------
        .. [1] R.D. Boschloo. "Raised conditional level of significance for the
           2 x 2-table when testing the equality of two probabilities",
           Statistica Neerlandica, 24(1), 1970

        .. [2] "Boschloo's test", Wikipedia,
           https://en.wikipedia.org/wiki/Boschloo%27s_test

        .. [3] Lise M. Saari et al. "Employee attitudes and job satisfaction",
           Human Resource Management, 43(4), 395-407, 2004,
           :doi:`10.1002/hrm.20032`.

        Examples
        --------
        In the following example, we consider the article "Employee
        attitudes and job satisfaction" [3]_
        which reports the results of a survey from 63 scientists and 117 college
        professors. Of the 63 scientists, 31 said they were very satisfied with
        their jobs, whereas 74 of the college professors were very satisfied
        with their work. Is this significant evidence that college
        professors are happier with their work than scientists?
        The following table summarizes the data mentioned above::

                             college professors   scientists
            Very Satisfied   74                     31
            Dissatisfied     43                     32

        When working with statistical hypothesis testing, we usually use a
        threshold probability or significance level upon which we decide
        to reject the null hypothesis :math:`H_0`. Suppose we choose the common
        significance level of 5%.

        Our alternative hypothesis is that college professors are truly more
        satisfied with their work than scientists. Therefore, we expect
        :math:`p_1` the proportion of very satisfied college professors to be
        greater than :math:`p_2`, the proportion of very satisfied scientists.
        We thus call `boschloo_exact` with the ``alternative="greater"`` option:

        >>> import scipy.stats as stats
        >>> res = stats.boschloo_exact([[74, 31], [43, 32]], alternative="greater")
        >>> res.statistic
        0.0483
        >>> res.pvalue
        0.0355

        Under the null hypothesis that scientists are happier in their work than
        college professors, the probability of obtaining test
        results at least as extreme as the observed data is approximately 3.55%.
        Since this p-value is less than our chosen significance level, we have
        evidence to reject :math:`H_0` in favor of the alternative hypothesis.

    boxcox(x, lmbda=None, alpha=None, optimizer=None)
        Return a dataset transformed by a Box-Cox power transformation.

        Parameters
        ----------
        x : ndarray
            Input array to be transformed.

            If `lmbda` is not None, this is an alias of
            `scipy.special.boxcox`.
            Returns nan if ``x < 0``; returns -inf if ``x == 0 and lmbda < 0``.

            If `lmbda` is None, array must be positive, 1-dimensional, and
            non-constant.

        lmbda : scalar, optional
            If `lmbda` is None (default), find the value of `lmbda` that maximizes
            the log-likelihood function and return it as the second output
            argument.

            If `lmbda` is not None, do the transformation for that value.

        alpha : float, optional
            If `lmbda` is None and `alpha` is not None (default), return the
            ``100 * (1-alpha)%`` confidence  interval for `lmbda` as the third
            output argument. Must be between 0.0 and 1.0.

            If `lmbda` is not None, `alpha` is ignored.
        optimizer : callable, optional
            If `lmbda` is None, `optimizer` is the scalar optimizer used to find
            the value of `lmbda` that minimizes the negative log-likelihood
            function. `optimizer` is a callable that accepts one argument:

            fun : callable
                The objective function, which evaluates the negative
                log-likelihood function at a provided value of `lmbda`

            and returns an object, such as an instance of
            `scipy.optimize.OptimizeResult`, which holds the optimal value of
            `lmbda` in an attribute `x`.

            See the example in `boxcox_normmax` or the documentation of
            `scipy.optimize.minimize_scalar` for more information.

            If `lmbda` is not None, `optimizer` is ignored.

        Returns
        -------
        boxcox : ndarray
            Box-Cox power transformed array.
        maxlog : float, optional
            If the `lmbda` parameter is None, the second returned argument is
            the `lmbda` that maximizes the log-likelihood function.
        (min_ci, max_ci) : tuple of float, optional
            If `lmbda` parameter is None and `alpha` is not None, this returned
            tuple of floats represents the minimum and maximum confidence limits
            given `alpha`.

        See Also
        --------
        probplot, boxcox_normplot, boxcox_normmax, boxcox_llf

        Notes
        -----
        The Box-Cox transform is given by::

            y = (x**lmbda - 1) / lmbda,  for lmbda != 0
                log(x),                  for lmbda = 0

        `boxcox` requires the input data to be positive.  Sometimes a Box-Cox
        transformation provides a shift parameter to achieve this; `boxcox` does
        not.  Such a shift parameter is equivalent to adding a positive constant to
        `x` before calling `boxcox`.

        The confidence limits returned when `alpha` is provided give the interval
        where:

        .. math::

            llf(\hat{\lambda}) - llf(\lambda) < \frac{1}{2}\chi^2(1 - \alpha, 1),

        with ``llf`` the log-likelihood function and :math:`\chi^2` the chi-squared
        function.

        References
        ----------
        G.E.P. Box and D.R. Cox, "An Analysis of Transformations", Journal of the
        Royal Statistical Society B, 26, 211-252 (1964).

        Examples
        --------
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        We generate some random variates from a non-normal distribution and make a
        probability plot for it, to show it is non-normal in the tails:

        >>> fig = plt.figure()
        >>> ax1 = fig.add_subplot(211)
        >>> x = stats.loggamma.rvs(5, size=500) + 5
        >>> prob = stats.probplot(x, dist=stats.norm, plot=ax1)
        >>> ax1.set_xlabel('')
        >>> ax1.set_title('Probplot against normal distribution')

        We now use `boxcox` to transform the data so it's closest to normal:

        >>> ax2 = fig.add_subplot(212)
        >>> xt, _ = stats.boxcox(x)
        >>> prob = stats.probplot(xt, dist=stats.norm, plot=ax2)
        >>> ax2.set_title('Probplot after Box-Cox transformation')

        >>> plt.show()

    boxcox_llf(lmb, data)
        The boxcox log-likelihood function.

        Parameters
        ----------
        lmb : scalar
            Parameter for Box-Cox transformation.  See `boxcox` for details.
        data : array_like
            Data to calculate Box-Cox log-likelihood for.  If `data` is
            multi-dimensional, the log-likelihood is calculated along the first
            axis.

        Returns
        -------
        llf : float or ndarray
            Box-Cox log-likelihood of `data` given `lmb`.  A float for 1-D `data`,
            an array otherwise.

        See Also
        --------
        boxcox, probplot, boxcox_normplot, boxcox_normmax

        Notes
        -----
        The Box-Cox log-likelihood function is defined here as

        .. math::

            llf = (\lambda - 1) \sum_i(\log(x_i)) -
                  N/2 \log(\sum_i (y_i - \bar{y})^2 / N),

        where ``y`` is the Box-Cox transformed input data ``x``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.axes_grid1.inset_locator import inset_axes

        Generate some random variates and calculate Box-Cox log-likelihood values
        for them for a range of ``lmbda`` values:

        >>> rng = np.random.default_rng()
        >>> x = stats.loggamma.rvs(5, loc=10, size=1000, random_state=rng)
        >>> lmbdas = np.linspace(-2, 10)
        >>> llf = np.zeros(lmbdas.shape, dtype=float)
        >>> for ii, lmbda in enumerate(lmbdas):
        ...     llf[ii] = stats.boxcox_llf(lmbda, x)

        Also find the optimal lmbda value with `boxcox`:

        >>> x_most_normal, lmbda_optimal = stats.boxcox(x)

        Plot the log-likelihood as function of lmbda.  Add the optimal lmbda as a
        horizontal line to check that that's really the optimum:

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(lmbdas, llf, 'b.-')
        >>> ax.axhline(stats.boxcox_llf(lmbda_optimal, x), color='r')
        >>> ax.set_xlabel('lmbda parameter')
        >>> ax.set_ylabel('Box-Cox log-likelihood')

        Now add some probability plots to show that where the log-likelihood is
        maximized the data transformed with `boxcox` looks closest to normal:

        >>> locs = [3, 10, 4]  # 'lower left', 'center', 'lower right'
        >>> for lmbda, loc in zip([-1, lmbda_optimal, 9], locs):
        ...     xt = stats.boxcox(x, lmbda=lmbda)
        ...     (osm, osr), (slope, intercept, r_sq) = stats.probplot(xt)
        ...     ax_inset = inset_axes(ax, width="20%", height="20%", loc=loc)
        ...     ax_inset.plot(osm, osr, 'c.', osm, slope*osm + intercept, 'k-')
        ...     ax_inset.set_xticklabels([])
        ...     ax_inset.set_yticklabels([])
        ...     ax_inset.set_title(r'$\lambda=%1.2f$' % lmbda)

        >>> plt.show()

    boxcox_normmax(x, brack=None, method='pearsonr', optimizer=None, *, ymax=BIG_FLOAT)
        Compute optimal Box-Cox transform parameter for input data.

        Parameters
        ----------
        x : array_like
            Input array. All entries must be positive, finite, real numbers.
        brack : 2-tuple, optional, default (-2.0, 2.0)
             The starting interval for a downhill bracket search for the default
             `optimize.brent` solver. Note that this is in most cases not
             critical; the final result is allowed to be outside this bracket.
             If `optimizer` is passed, `brack` must be None.
        method : str, optional
            The method to determine the optimal transform parameter (`boxcox`
            ``lmbda`` parameter). Options are:

            'pearsonr'  (default)
                Maximizes the Pearson correlation coefficient between
                ``y = boxcox(x)`` and the expected values for ``y`` if `x` would be
                normally-distributed.

            'mle'
                Maximizes the log-likelihood `boxcox_llf`.  This is the method used
                in `boxcox`.

            'all'
                Use all optimization methods available, and return all results.
                Useful to compare different methods.
        optimizer : callable, optional
            `optimizer` is a callable that accepts one argument:

            fun : callable
                The objective function to be minimized. `fun` accepts one argument,
                the Box-Cox transform parameter `lmbda`, and returns the value of
                the function (e.g., the negative log-likelihood) at the provided
                argument. The job of `optimizer` is to find the value of `lmbda`
                that *minimizes* `fun`.

            and returns an object, such as an instance of
            `scipy.optimize.OptimizeResult`, which holds the optimal value of
            `lmbda` in an attribute `x`.

            See the example below or the documentation of
            `scipy.optimize.minimize_scalar` for more information.
        ymax : float, optional
            The unconstrained optimal transform parameter may cause Box-Cox
            transformed data to have extreme magnitude or even overflow.
            This parameter constrains MLE optimization such that the magnitude
            of the transformed `x` does not exceed `ymax`. The default is
            the maximum value of the input dtype. If set to infinity,
            `boxcox_normmax` returns the unconstrained optimal lambda.
            Ignored when ``method='pearsonr'``.

        Returns
        -------
        maxlog : float or ndarray
            The optimal transform parameter found.  An array instead of a scalar
            for ``method='all'``.

        See Also
        --------
        boxcox, boxcox_llf, boxcox_normplot, scipy.optimize.minimize_scalar

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        We can generate some data and determine the optimal ``lmbda`` in various
        ways:

        >>> rng = np.random.default_rng()
        >>> x = stats.loggamma.rvs(5, size=30, random_state=rng) + 5
        >>> y, lmax_mle = stats.boxcox(x)
        >>> lmax_pearsonr = stats.boxcox_normmax(x)

        >>> lmax_mle
        2.217563431465757
        >>> lmax_pearsonr
        2.238318660200961
        >>> stats.boxcox_normmax(x, method='all')
        array([2.23831866, 2.21756343])

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> prob = stats.boxcox_normplot(x, -10, 10, plot=ax)
        >>> ax.axvline(lmax_mle, color='r')
        >>> ax.axvline(lmax_pearsonr, color='g', ls='--')

        >>> plt.show()

        Alternatively, we can define our own `optimizer` function. Suppose we
        are only interested in values of `lmbda` on the interval [6, 7], we
        want to use `scipy.optimize.minimize_scalar` with ``method='bounded'``,
        and we want to use tighter tolerances when optimizing the log-likelihood
        function. To do this, we define a function that accepts positional argument
        `fun` and uses `scipy.optimize.minimize_scalar` to minimize `fun` subject
        to the provided bounds and tolerances:

        >>> from scipy import optimize
        >>> options = {'xatol': 1e-12}  # absolute tolerance on `x`
        >>> def optimizer(fun):
        ...     return optimize.minimize_scalar(fun, bounds=(6, 7),
        ...                                     method="bounded", options=options)
        >>> stats.boxcox_normmax(x, optimizer=optimizer)
        6.000000000

    boxcox_normplot(x, la, lb, plot=None, N=80)
        Compute parameters for a Box-Cox normality plot, optionally show it.

        A Box-Cox normality plot shows graphically what the best transformation
        parameter is to use in `boxcox` to obtain a distribution that is close
        to normal.

        Parameters
        ----------
        x : array_like
            Input array.
        la, lb : scalar
            The lower and upper bounds for the ``lmbda`` values to pass to `boxcox`
            for Box-Cox transformations.  These are also the limits of the
            horizontal axis of the plot if that is generated.
        plot : object, optional
            If given, plots the quantiles and least squares fit.
            `plot` is an object that has to have methods "plot" and "text".
            The `matplotlib.pyplot` module or a Matplotlib Axes object can be used,
            or a custom object with the same methods.
            Default is None, which means that no plot is created.
        N : int, optional
            Number of points on the horizontal axis (equally distributed from
            `la` to `lb`).

        Returns
        -------
        lmbdas : ndarray
            The ``lmbda`` values for which a Box-Cox transform was done.
        ppcc : ndarray
            Probability Plot Correlelation Coefficient, as obtained from `probplot`
            when fitting the Box-Cox transformed input `x` against a normal
            distribution.

        See Also
        --------
        probplot, boxcox, boxcox_normmax, boxcox_llf, ppcc_max

        Notes
        -----
        Even if `plot` is given, the figure is not shown or saved by
        `boxcox_normplot`; ``plt.show()`` or ``plt.savefig('figname.png')``
        should be used after calling `probplot`.

        Examples
        --------
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        Generate some non-normally distributed data, and create a Box-Cox plot:

        >>> x = stats.loggamma.rvs(5, size=500) + 5
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> prob = stats.boxcox_normplot(x, -20, 20, plot=ax)

        Determine and plot the optimal ``lmbda`` to transform ``x`` and plot it in
        the same plot:

        >>> _, maxlog = stats.boxcox(x)
        >>> ax.axvline(maxlog, color='r')

        >>> plt.show()

    brunnermunzel(x, y, alternative='two-sided', distribution='t', nan_policy='propagate', *, axis=0, keepdims=False)
        Compute the Brunner-Munzel test on samples x and y.

        The Brunner-Munzel test is a nonparametric test of the null hypothesis that
        when values are taken one by one from each group, the probabilities of
        getting large values in both groups are equal.
        Unlike the Wilcoxon-Mann-Whitney's U test, this does not require the
        assumption of equivariance of two groups. Note that this does not assume
        the distributions are same. This test works on two independent samples,
        which may have different sizes.

        Parameters
        ----------
        x, y : array_like
            Array of samples, should be one-dimensional.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

              * 'two-sided'
              * 'less': one-sided
              * 'greater': one-sided
        distribution : {'t', 'normal'}, optional
            Defines how to get the p-value.
            The following options are available (default is 't'):

              * 't': get the p-value by t-distribution
              * 'normal': get the p-value by standard normal distribution.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The Brunner-Munzer W statistic.
        pvalue : float
            p-value assuming an t distribution. One-sided or
            two-sided, depending on the choice of `alternative` and `distribution`.

        See Also
        --------

        :func:`mannwhitneyu`
            Mann-Whitney rank test on two samples.


        Notes
        -----
        Brunner and Munzel recommended to estimate the p-value by t-distribution
        when the size of data is 50 or less. If the size is lower than 10, it would
        be better to use permuted Brunner Munzel test (see [2]_).

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Brunner, E. and Munzel, U. "The nonparametric Benhrens-Fisher
               problem: Asymptotic theory and a small-sample approximation".
               Biometrical Journal. Vol. 42(2000): 17-25.
        .. [2] Neubert, K. and Brunner, E. "A studentized permutation test for the
               non-parametric Behrens-Fisher problem". Computational Statistics and
               Data Analysis. Vol. 51(2007): 5192-5204.

        Examples
        --------
        >>> from scipy import stats
        >>> x1 = [1,2,1,1,1,1,1,1,1,1,2,4,1,1]
        >>> x2 = [3,3,4,3,1,2,3,1,1,5,4]
        >>> w, p_value = stats.brunnermunzel(x1, x2)
        >>> w
        3.1374674823029505
        >>> p_value
        0.0057862086661515377

    bws_test(x, y, *, alternative='two-sided', method=None)
        Perform the Baumgartner-Weiss-Schindler test on two independent samples.

        The Baumgartner-Weiss-Schindler (BWS) test is a nonparametric test of
        the null hypothesis that the distribution underlying sample `x`
        is the same as the distribution underlying sample `y`. Unlike
        the Kolmogorov-Smirnov, Wilcoxon, and Cramer-Von Mises tests,
        the BWS test weights the integral by the variance of the difference
        in cumulative distribution functions (CDFs), emphasizing the tails of the
        distributions, which increases the power of the test in many applications.

        Parameters
        ----------
        x, y : array-like
            1-d arrays of samples.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            Let *F(u)* and *G(u)* be the cumulative distribution functions of the
            distributions underlying `x` and `y`, respectively. Then the following
            alternative hypotheses are available:

            * 'two-sided': the distributions are not equal, i.e. *F(u) ≠ G(u)* for
              at least one *u*.
            * 'less': the distribution underlying `x` is stochastically less than
              the distribution underlying `y`, i.e. *F(u) >= G(u)* for all *u*.
            * 'greater': the distribution underlying `x` is stochastically greater
              than the distribution underlying `y`, i.e. *F(u) <= G(u)* for all
              *u*.

            Under a more restrictive set of assumptions, the alternative hypotheses
            can be expressed in terms of the locations of the distributions;
            see [2] section 5.1.
        method : PermutationMethod, optional
            Configures the method used to compute the p-value. The default is
            the default `PermutationMethod` object.

        Returns
        -------
        res : PermutationTestResult
        An object with attributes:

        statistic : float
            The observed test statistic of the data.
        pvalue : float
            The p-value for the given alternative.
        null_distribution : ndarray
            The values of the test statistic generated under the null hypothesis.

        See also
        --------
        scipy.stats.wilcoxon, scipy.stats.mannwhitneyu, scipy.stats.ttest_ind

        Notes
        -----
        When ``alternative=='two-sided'``, the statistic is defined by the
        equations given in [1]_ Section 2. This statistic is not appropriate for
        one-sided alternatives; in that case, the statistic is the *negative* of
        that given by the equations in [1]_ Section 2. Consequently, when the
        distribution of the first sample is stochastically greater than that of the
        second sample, the statistic will tend to be positive.

        References
        ----------
        .. [1] Neuhäuser, M. (2005). Exact Tests Based on the
               Baumgartner-Weiss-Schindler Statistic: A Survey. Statistical Papers,
               46(1), 1-29.
        .. [2] Fay, M. P., & Proschan, M. A. (2010). Wilcoxon-Mann-Whitney or t-test?
               On assumptions for hypothesis tests and multiple interpretations of
               decision rules. Statistics surveys, 4, 1.

        Examples
        --------
        We follow the example of table 3 in [1]_: Fourteen children were divided
        randomly into two groups. Their ranks at performing a specific tests are
        as follows.

        >>> import numpy as np
        >>> x = [1, 2, 3, 4, 6, 7, 8]
        >>> y = [5, 9, 10, 11, 12, 13, 14]

        We use the BWS test to assess whether there is a statistically significant
        difference between the two groups.
        The null hypothesis is that there is no difference in the distributions of
        performance between the two groups. We decide that a significance level of
        1% is required to reject the null hypothesis in favor of the alternative
        that the distributions are different.
        Since the number of samples is very small, we can compare the observed test
        statistic against the *exact* distribution of the test statistic under the
        null hypothesis.

        >>> from scipy.stats import bws_test
        >>> res = bws_test(x, y)
        >>> print(res.statistic)
        5.132167152575315

        This agrees with :math:`B = 5.132` reported in [1]_. The *p*-value produced
        by `bws_test` also agrees with :math:`p = 0.0029` reported in [1]_.

        >>> print(res.pvalue)
        0.002913752913752914

        Because the p-value is below our threshold of 1%, we take this as evidence
        against the null hypothesis in favor of the alternative that there is a
        difference in performance between the two groups.

    chi2_contingency(observed, correction=True, lambda_=None)
        Chi-square test of independence of variables in a contingency table.

        This function computes the chi-square statistic and p-value for the
        hypothesis test of independence of the observed frequencies in the
        contingency table [1]_ `observed`.  The expected frequencies are computed
        based on the marginal sums under the assumption of independence; see
        `scipy.stats.contingency.expected_freq`.  The number of degrees of
        freedom is (expressed using numpy functions and attributes)::

            dof = observed.size - sum(observed.shape) + observed.ndim - 1


        Parameters
        ----------
        observed : array_like
            The contingency table. The table contains the observed frequencies
            (i.e. number of occurrences) in each category.  In the two-dimensional
            case, the table is often described as an "R x C table".
        correction : bool, optional
            If True, *and* the degrees of freedom is 1, apply Yates' correction
            for continuity.  The effect of the correction is to adjust each
            observed value by 0.5 towards the corresponding expected value.
        lambda_ : float or str, optional
            By default, the statistic computed in this test is Pearson's
            chi-squared statistic [2]_.  `lambda_` allows a statistic from the
            Cressie-Read power divergence family [3]_ to be used instead.  See
            `scipy.stats.power_divergence` for details.

        Returns
        -------
        res : Chi2ContingencyResult
            An object containing attributes:

            statistic : float
                The test statistic.
            pvalue : float
                The p-value of the test.
            dof : int
                The degrees of freedom.
            expected_freq : ndarray, same shape as `observed`
                The expected frequencies, based on the marginal sums of the table.

        See Also
        --------
        scipy.stats.contingency.expected_freq
        scipy.stats.fisher_exact
        scipy.stats.chisquare
        scipy.stats.power_divergence
        scipy.stats.barnard_exact
        scipy.stats.boschloo_exact

        Notes
        -----
        An often quoted guideline for the validity of this calculation is that
        the test should be used only if the observed and expected frequencies
        in each cell are at least 5.

        This is a test for the independence of different categories of a
        population. The test is only meaningful when the dimension of
        `observed` is two or more.  Applying the test to a one-dimensional
        table will always result in `expected` equal to `observed` and a
        chi-square statistic equal to 0.

        This function does not handle masked arrays, because the calculation
        does not make sense with missing values.

        Like `scipy.stats.chisquare`, this function computes a chi-square
        statistic; the convenience this function provides is to figure out the
        expected frequencies and degrees of freedom from the given contingency
        table. If these were already known, and if the Yates' correction was not
        required, one could use `scipy.stats.chisquare`.  That is, if one calls::

            res = chi2_contingency(obs, correction=False)

        then the following is true::

            (res.statistic, res.pvalue) == stats.chisquare(obs.ravel(),
                                                           f_exp=ex.ravel(),
                                                           ddof=obs.size - 1 - dof)

        The `lambda_` argument was added in version 0.13.0 of scipy.

        References
        ----------
        .. [1] "Contingency table",
               https://en.wikipedia.org/wiki/Contingency_table
        .. [2] "Pearson's chi-squared test",
               https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test
        .. [3] Cressie, N. and Read, T. R. C., "Multinomial Goodness-of-Fit
               Tests", J. Royal Stat. Soc. Series B, Vol. 46, No. 3 (1984),
               pp. 440-464.
        .. [4] Berger, Jeffrey S. et al. "Aspirin for the Primary Prevention of
               Cardiovascular Events in Women and Men: A Sex-Specific
               Meta-analysis of Randomized Controlled Trials."
               JAMA, 295(3):306-313, :doi:`10.1001/jama.295.3.306`, 2006.

        Examples
        --------
        In [4]_, the use of aspirin to prevent cardiovascular events in women
        and men was investigated. The study notably concluded:

            ...aspirin therapy reduced the risk of a composite of
            cardiovascular events due to its effect on reducing the risk of
            ischemic stroke in women [...]

        The article lists studies of various cardiovascular events. Let's
        focus on the ischemic stoke in women.

        The following table summarizes the results of the experiment in which
        participants took aspirin or a placebo on a regular basis for several
        years. Cases of ischemic stroke were recorded::

                              Aspirin   Control/Placebo
            Ischemic stroke     176           230
            No stroke         21035         21018

        Is there evidence that the aspirin reduces the risk of ischemic stroke?
        We begin by formulating a null hypothesis :math:`H_0`:

            The effect of aspirin is equivalent to that of placebo.

        Let's assess the plausibility of this hypothesis with
        a chi-square test.

        >>> import numpy as np
        >>> from scipy.stats import chi2_contingency
        >>> table = np.array([[176, 230], [21035, 21018]])
        >>> res = chi2_contingency(table)
        >>> res.statistic
        6.892569132546561
        >>> res.pvalue
        0.008655478161175739

        Using a significance level of 5%, we would reject the null hypothesis in
        favor of the alternative hypothesis: "the effect of aspirin
        is not equivalent to the effect of placebo".
        Because `scipy.stats.contingency.chi2_contingency` performs a two-sided
        test, the alternative hypothesis does not indicate the direction of the
        effect. We can use `stats.contingency.odds_ratio` to support the
        conclusion that aspirin *reduces* the risk of ischemic stroke.

        Below are further examples showing how larger contingency tables can be
        tested.

        A two-way example (2 x 3):

        >>> obs = np.array([[10, 10, 20], [20, 20, 20]])
        >>> res = chi2_contingency(obs)
        >>> res.statistic
        2.7777777777777777
        >>> res.pvalue
        0.24935220877729619
        >>> res.dof
        2
        >>> res.expected_freq
        array([[ 12.,  12.,  16.],
               [ 18.,  18.,  24.]])

        Perform the test using the log-likelihood ratio (i.e. the "G-test")
        instead of Pearson's chi-squared statistic.

        >>> res = chi2_contingency(obs, lambda_="log-likelihood")
        >>> res.statistic
        2.7688587616781319
        >>> res.pvalue
        0.25046668010954165

        A four-way example (2 x 2 x 2 x 2):

        >>> obs = np.array(
        ...     [[[[12, 17],
        ...        [11, 16]],
        ...       [[11, 12],
        ...        [15, 16]]],
        ...      [[[23, 15],
        ...        [30, 22]],
        ...       [[14, 17],
        ...        [15, 16]]]])
        >>> res = chi2_contingency(obs)
        >>> res.statistic
        8.7584514426741897
        >>> res.pvalue
        0.64417725029295503

    chisquare(f_obs, f_exp=None, ddof=0, axis=0)
        Calculate a one-way chi-square test.

        The chi-square test tests the null hypothesis that the categorical data
        has the given frequencies.

        Parameters
        ----------
        f_obs : array_like
            Observed frequencies in each category.
        f_exp : array_like, optional
            Expected frequencies in each category.  By default the categories are
            assumed to be equally likely.
        ddof : int, optional
            "Delta degrees of freedom": adjustment to the degrees of freedom
            for the p-value.  The p-value is computed using a chi-squared
            distribution with ``k - 1 - ddof`` degrees of freedom, where `k`
            is the number of observed frequencies.  The default value of `ddof`
            is 0.
        axis : int or None, optional
            The axis of the broadcast result of `f_obs` and `f_exp` along which to
            apply the test.  If axis is None, all values in `f_obs` are treated
            as a single data set.  Default is 0.

        Returns
        -------
        res: Power_divergenceResult
            An object containing attributes:

            statistic : float or ndarray
                The chi-squared test statistic.  The value is a float if `axis` is
                None or `f_obs` and `f_exp` are 1-D.
            pvalue : float or ndarray
                The p-value of the test.  The value is a float if `ddof` and the
                result attribute `statistic` are scalars.

        See Also
        --------
        scipy.stats.power_divergence
        scipy.stats.fisher_exact : Fisher exact test on a 2x2 contingency table.
        scipy.stats.barnard_exact : An unconditional exact test. An alternative
            to chi-squared test for small sample sizes.

        Notes
        -----
        This test is invalid when the observed or expected frequencies in each
        category are too small.  A typical rule is that all of the observed
        and expected frequencies should be at least 5. According to [3]_, the
        total number of samples is recommended to be greater than 13,
        otherwise exact tests (such as Barnard's Exact test) should be used
        because they do not overreject.

        Also, the sum of the observed and expected frequencies must be the same
        for the test to be valid; `chisquare` raises an error if the sums do not
        agree within a relative tolerance of ``1e-8``.

        The default degrees of freedom, k-1, are for the case when no parameters
        of the distribution are estimated. If p parameters are estimated by
        efficient maximum likelihood then the correct degrees of freedom are
        k-1-p. If the parameters are estimated in a different way, then the
        dof can be between k-1-p and k-1. However, it is also possible that
        the asymptotic distribution is not chi-square, in which case this test
        is not appropriate.

        References
        ----------
        .. [1] Lowry, Richard.  "Concepts and Applications of Inferential
               Statistics". Chapter 8.
               https://web.archive.org/web/20171022032306/http://vassarstats.net:80/textbook/ch8pt1.html
        .. [2] "Chi-squared test", https://en.wikipedia.org/wiki/Chi-squared_test
        .. [3] Pearson, Karl. "On the criterion that a given system of deviations from the probable
               in the case of a correlated system of variables is such that it can be reasonably
               supposed to have arisen from random sampling", Philosophical Magazine. Series 5. 50
               (1900), pp. 157-175.
        .. [4] Mannan, R. William and E. Charles. Meslow. "Bird populations and
               vegetation characteristics in managed and old-growth forests,
               northeastern Oregon." Journal of Wildlife Management
               48, 1219-1238, :doi:`10.2307/3801783`, 1984.

        Examples
        --------
        In [4]_, bird foraging behavior was investigated in an old-growth forest
        of Oregon.
        In the forest, 44% of the canopy volume was Douglas fir,
        24% was ponderosa pine, 29% was grand fir, and 3% was western larch.
        The authors observed the behavior of several species of birds, one of
        which was the red-breasted nuthatch. They made 189 observations of this
        species foraging, recording 43 ("23%") of observations in Douglas fir,
        52 ("28%") in ponderosa pine, 54 ("29%") in grand fir, and 40 ("21%") in
        western larch.

        Using a chi-square test, we can test the null hypothesis that the
        proportions of foraging events are equal to the proportions of canopy
        volume. The authors of the paper considered a p-value less than 1% to be
        significant.

        Using the above proportions of canopy volume and observed events, we can
        infer expected frequencies.

        >>> import numpy as np
        >>> f_exp = np.array([44, 24, 29, 3]) / 100 * 189

        The observed frequencies of foraging were:

        >>> f_obs = np.array([43, 52, 54, 40])

        We can now compare the observed frequencies with the expected frequencies.

        >>> from scipy.stats import chisquare
        >>> chisquare(f_obs=f_obs, f_exp=f_exp)
        Power_divergenceResult(statistic=228.23515947653874, pvalue=3.3295585338846486e-49)

        The p-value is well below the chosen significance level. Hence, the
        authors considered the difference to be significant and concluded
        that the relative proportions of foraging events were not the same
        as the relative proportions of tree canopy volume.

        Following are other generic examples to demonstrate how the other
        parameters can be used.

        When just `f_obs` is given, it is assumed that the expected frequencies
        are uniform and given by the mean of the observed frequencies.

        >>> chisquare([16, 18, 16, 14, 12, 12])
        Power_divergenceResult(statistic=2.0, pvalue=0.84914503608460956)

        With `f_exp` the expected frequencies can be given.

        >>> chisquare([16, 18, 16, 14, 12, 12], f_exp=[16, 16, 16, 16, 16, 8])
        Power_divergenceResult(statistic=3.5, pvalue=0.62338762774958223)

        When `f_obs` is 2-D, by default the test is applied to each column.

        >>> obs = np.array([[16, 18, 16, 14, 12, 12], [32, 24, 16, 28, 20, 24]]).T
        >>> obs.shape
        (6, 2)
        >>> chisquare(obs)
        Power_divergenceResult(statistic=array([2.        , 6.66666667]), pvalue=array([0.84914504, 0.24663415]))

        By setting ``axis=None``, the test is applied to all data in the array,
        which is equivalent to applying the test to the flattened array.

        >>> chisquare(obs, axis=None)
        Power_divergenceResult(statistic=23.31034482758621, pvalue=0.015975692534127565)
        >>> chisquare(obs.ravel())
        Power_divergenceResult(statistic=23.310344827586206, pvalue=0.01597569253412758)

        `ddof` is the change to make to the default degrees of freedom.

        >>> chisquare([16, 18, 16, 14, 12, 12], ddof=1)
        Power_divergenceResult(statistic=2.0, pvalue=0.7357588823428847)

        The calculation of the p-values is done by broadcasting the
        chi-squared statistic with `ddof`.

        >>> chisquare([16, 18, 16, 14, 12, 12], ddof=[0,1,2])
        Power_divergenceResult(statistic=2.0, pvalue=array([0.84914504, 0.73575888, 0.5724067 ]))

        `f_obs` and `f_exp` are also broadcast.  In the following, `f_obs` has
        shape (6,) and `f_exp` has shape (2, 6), so the result of broadcasting
        `f_obs` and `f_exp` has shape (2, 6).  To compute the desired chi-squared
        statistics, we use ``axis=1``:

        >>> chisquare([16, 18, 16, 14, 12, 12],
        ...           f_exp=[[16, 16, 16, 16, 16, 8], [8, 20, 20, 16, 12, 12]],
        ...           axis=1)
        Power_divergenceResult(statistic=array([3.5 , 9.25]), pvalue=array([0.62338763, 0.09949846]))

    circmean(samples, high=6.283185307179586, low=0, axis=None, nan_policy='propagate', *, keepdims=False)
        Compute the circular mean of a sample of angle observations.

        Given :math:`n` angle observations :math:`x_1, \cdots, x_n` measured in
        radians, their `circular mean` is defined by ([1]_, Eq. 2.2.4)

        .. math::

           \mathrm{Arg} \left( \frac{1}{n} \sum_{k=1}^n e^{i x_k} \right)

        where :math:`i` is the imaginary unit and :math:`\mathop{\mathrm{Arg}} z`
        gives the principal value of the argument of complex number :math:`z`,
        restricted to the range :math:`[0,2\pi]` by default.  :math:`z` in the
        above expression is known as the `mean resultant vector`.

        Parameters
        ----------
        samples : array_like
            Input array of angle observations.  The value of a full angle is
            equal to ``(high - low)``.
        high : float, optional
            Upper boundary of the principal value of an angle.  Default is ``2*pi``.
        low : float, optional
            Lower boundary of the principal value of an angle.  Default is ``0``.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        circmean : float
            Circular mean, restricted to the range ``[low, high]``.

            If the mean resultant vector is zero, an input-dependent,
            implementation-defined number between ``[low, high]`` is returned.
            If the input array is empty, ``np.nan`` is returned.

        See Also
        --------

        :func:`circstd`
            Circular standard deviation.
        :func:`circvar`
            Circular variance.


        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Mardia, K. V. and Jupp, P. E. *Directional Statistics*.
               John Wiley & Sons, 1999.

        Examples
        --------
        For readability, all angles are printed out in degrees.

        >>> import numpy as np
        >>> from scipy.stats import circmean
        >>> import matplotlib.pyplot as plt
        >>> angles = np.deg2rad(np.array([20, 30, 330]))
        >>> circmean = circmean(angles)
        >>> np.rad2deg(circmean)
        7.294976657784009

        >>> mean = angles.mean()
        >>> np.rad2deg(mean)
        126.66666666666666

        Plot and compare the circular mean against the arithmetic mean.

        >>> plt.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
        ...          np.sin(np.linspace(0, 2*np.pi, 500)),
        ...          c='k')
        >>> plt.scatter(np.cos(angles), np.sin(angles), c='k')
        >>> plt.scatter(np.cos(circmean), np.sin(circmean), c='b',
        ...             label='circmean')
        >>> plt.scatter(np.cos(mean), np.sin(mean), c='r', label='mean')
        >>> plt.legend()
        >>> plt.axis('equal')
        >>> plt.show()

    circstd(samples, high=6.283185307179586, low=0, axis=None, nan_policy='propagate', *, normalize=False, keepdims=False)
        Compute the circular standard deviation of a sample of angle observations.

        Given :math:`n` angle observations :math:`x_1, \cdots, x_n` measured in
        radians, their `circular standard deviation` is defined by
        ([2]_, Eq. 2.3.11)

        .. math::

           \sqrt{ -2 \log \left| \frac{1}{n} \sum_{k=1}^n e^{i x_k} \right| }

        where :math:`i` is the imaginary unit and :math:`|z|` gives the length
        of the complex number :math:`z`.  :math:`|z|` in the above expression
        is known as the `mean resultant length`.

        Parameters
        ----------
        samples : array_like
            Input array of angle observations.  The value of a full angle is
            equal to ``(high - low)``.
        high : float, optional
            Upper boundary of the principal value of an angle.  Default is ``2*pi``.
        low : float, optional
            Lower boundary of the principal value of an angle.  Default is ``0``.
        normalize : boolean, optional
            If ``False`` (the default), the return value is computed from the
            above formula with the input scaled by ``(2*pi)/(high-low)`` and
            the output scaled (back) by ``(high-low)/(2*pi)``.  If ``True``,
            the output is not scaled and is returned directly.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        circstd : float
            Circular standard deviation, optionally normalized.

            If the input array is empty, ``np.nan`` is returned.

        See Also
        --------

        :func:`circmean`
            Circular mean.
        :func:`circvar`
            Circular variance.


        Notes
        -----
        In the limit of small angles, the circular standard deviation is close
        to the 'linear' standard deviation if ``normalize`` is ``False``.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Mardia, K. V. (1972). 2. In *Statistics of Directional Data*
           (pp. 18-24). Academic Press. :doi:`10.1016/C2013-0-07425-7`.
        .. [2] Mardia, K. V. and Jupp, P. E. *Directional Statistics*.
               John Wiley & Sons, 1999.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import circstd
        >>> import matplotlib.pyplot as plt
        >>> samples_1 = np.array([0.072, -0.158, 0.077, 0.108, 0.286,
        ...                       0.133, -0.473, -0.001, -0.348, 0.131])
        >>> samples_2 = np.array([0.111, -0.879, 0.078, 0.733, 0.421,
        ...                       0.104, -0.136, -0.867,  0.012,  0.105])
        >>> circstd_1 = circstd(samples_1)
        >>> circstd_2 = circstd(samples_2)

        Plot the samples.

        >>> fig, (left, right) = plt.subplots(ncols=2)
        >>> for image in (left, right):
        ...     image.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
        ...                np.sin(np.linspace(0, 2*np.pi, 500)),
        ...                c='k')
        ...     image.axis('equal')
        ...     image.axis('off')
        >>> left.scatter(np.cos(samples_1), np.sin(samples_1), c='k', s=15)
        >>> left.set_title(f"circular std: {np.round(circstd_1, 2)!r}")
        >>> right.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
        ...            np.sin(np.linspace(0, 2*np.pi, 500)),
        ...            c='k')
        >>> right.scatter(np.cos(samples_2), np.sin(samples_2), c='k', s=15)
        >>> right.set_title(f"circular std: {np.round(circstd_2, 2)!r}")
        >>> plt.show()

    circvar(samples, high=6.283185307179586, low=0, axis=None, nan_policy='propagate', *, keepdims=False)
        Compute the circular variance of a sample of angle observations.

        Given :math:`n` angle observations :math:`x_1, \cdots, x_n` measured in
        radians, their `circular variance` is defined by ([2]_, Eq. 2.3.3)

        .. math::

           1 - \left| \frac{1}{n} \sum_{k=1}^n e^{i x_k} \right|

        where :math:`i` is the imaginary unit and :math:`|z|` gives the length
        of the complex number :math:`z`.  :math:`|z|` in the above expression
        is known as the `mean resultant length`.

        Parameters
        ----------
        samples : array_like
            Input array of angle observations.  The value of a full angle is
            equal to ``(high - low)``.
        high : float, optional
            Upper boundary of the principal value of an angle.  Default is ``2*pi``.
        low : float, optional
            Lower boundary of the principal value of an angle.  Default is ``0``.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        circvar : float
            Circular variance.  The returned value is in the range ``[0, 1]``,
            where ``0`` indicates no variance and ``1`` indicates large variance.

            If the input array is empty, ``np.nan`` is returned.

        See Also
        --------

        :func:`circmean`
            Circular mean.
        :func:`circstd`
            Circular standard deviation.


        Notes
        -----
        In the limit of small angles, the circular variance is close to
        half the 'linear' variance if measured in radians.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Fisher, N.I. *Statistical analysis of circular data*. Cambridge
               University Press, 1993.
        .. [2] Mardia, K. V. and Jupp, P. E. *Directional Statistics*.
               John Wiley & Sons, 1999.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import circvar
        >>> import matplotlib.pyplot as plt
        >>> samples_1 = np.array([0.072, -0.158, 0.077, 0.108, 0.286,
        ...                       0.133, -0.473, -0.001, -0.348, 0.131])
        >>> samples_2 = np.array([0.111, -0.879, 0.078, 0.733, 0.421,
        ...                       0.104, -0.136, -0.867,  0.012,  0.105])
        >>> circvar_1 = circvar(samples_1)
        >>> circvar_2 = circvar(samples_2)

        Plot the samples.

        >>> fig, (left, right) = plt.subplots(ncols=2)
        >>> for image in (left, right):
        ...     image.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
        ...                np.sin(np.linspace(0, 2*np.pi, 500)),
        ...                c='k')
        ...     image.axis('equal')
        ...     image.axis('off')
        >>> left.scatter(np.cos(samples_1), np.sin(samples_1), c='k', s=15)
        >>> left.set_title(f"circular variance: {np.round(circvar_1, 2)!r}")
        >>> right.scatter(np.cos(samples_2), np.sin(samples_2), c='k', s=15)
        >>> right.set_title(f"circular variance: {np.round(circvar_2, 2)!r}")
        >>> plt.show()

    combine_pvalues(pvalues, method='fisher', weights=None, *, axis=0, nan_policy='propagate', keepdims=False)
        Combine p-values from independent tests that bear upon the same hypothesis.

        These methods are intended only for combining p-values from hypothesis
        tests based upon continuous distributions.

        Each method assumes that under the null hypothesis, the p-values are
        sampled independently and uniformly from the interval [0, 1]. A test
        statistic (different for each method) is computed and a combined
        p-value is calculated based upon the distribution of this test statistic
        under the null hypothesis.

        Parameters
        ----------
        pvalues : array_like
            Array of p-values assumed to come from independent tests based on
            continuous distributions.
        method : {'fisher', 'pearson', 'tippett', 'stouffer', 'mudholkar_george'}
            Name of method to use to combine p-values.

            The available methods are (see Notes for details):

            * 'fisher': Fisher's method (Fisher's combined probability test)
            * 'pearson': Pearson's method
            * 'mudholkar_george': Mudholkar's and George's method
            * 'tippett': Tippett's method
            * 'stouffer': Stouffer's Z-score method
        weights : array_like, optional
            Optional array of weights used only for Stouffer's Z-score method.
            Ignored by other methods.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : SignificanceResult
            An object containing attributes:

            statistic : float
                The statistic calculated by the specified method.
            pvalue : float
                The combined p-value.

        Notes
        -----
        If this function is applied to tests with a discrete statistics such as
        any rank test or contingency-table test, it will yield systematically
        wrong results, e.g. Fisher's method will systematically overestimate the
        p-value [1]_. This problem becomes less severe for large sample sizes
        when the discrete distributions become approximately continuous.

        The differences between the methods can be best illustrated by their
        statistics and what aspects of a combination of p-values they emphasise
        when considering significance [2]_. For example, methods emphasising large
        p-values are more sensitive to strong false and true negatives; conversely
        methods focussing on small p-values are sensitive to positives.

        * The statistics of Fisher's method (also known as Fisher's combined
          probability test) [3]_ is :math:`-2\sum_i \log(p_i)`, which is
          equivalent (as a test statistics) to the product of individual p-values:
          :math:`\prod_i p_i`. Under the null hypothesis, this statistics follows
          a :math:`\chi^2` distribution. This method emphasises small p-values.
        * Pearson's method uses :math:`-2\sum_i\log(1-p_i)`, which is equivalent
          to :math:`\prod_i \frac{1}{1-p_i}` [2]_.
          It thus emphasises large p-values.
        * Mudholkar and George compromise between Fisher's and Pearson's method by
          averaging their statistics [4]_. Their method emphasises extreme
          p-values, both close to 1 and 0.
        * Stouffer's method [5]_ uses Z-scores and the statistic:
          :math:`\sum_i \Phi^{-1} (p_i)`, where :math:`\Phi` is the CDF of the
          standard normal distribution. The advantage of this method is that it is
          straightforward to introduce weights, which can make Stouffer's method
          more powerful than Fisher's method when the p-values are from studies
          of different size [6]_ [7]_.
        * Tippett's method uses the smallest p-value as a statistic.
          (Mind that this minimum is not the combined p-value.)

        Fisher's method may be extended to combine p-values from dependent tests
        [8]_. Extensions such as Brown's method and Kost's method are not currently
        implemented.

        .. versionadded:: 0.15.0

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Kincaid, W. M., "The Combination of Tests Based on Discrete
               Distributions." Journal of the American Statistical Association 57,
               no. 297 (1962), 10-19.
        .. [2] Heard, N. and Rubin-Delanchey, P. "Choosing between methods of
               combining p-values."  Biometrika 105.1 (2018): 239-246.
        .. [3] https://en.wikipedia.org/wiki/Fisher%27s_method
        .. [4] George, E. O., and G. S. Mudholkar. "On the convolution of logistic
               random variables." Metrika 30.1 (1983): 1-13.
        .. [5] https://en.wikipedia.org/wiki/Fisher%27s_method#Relation_to_Stouffer.27s_Z-score_method
        .. [6] Whitlock, M. C. "Combining probability from independent tests: the
               weighted Z-method is superior to Fisher's approach." Journal of
               Evolutionary Biology 18, no. 5 (2005): 1368-1373.
        .. [7] Zaykin, Dmitri V. "Optimally weighted Z-test is a powerful method
               for combining probabilities in meta-analysis." Journal of
               Evolutionary Biology 24, no. 8 (2011): 1836-1841.
        .. [8] https://en.wikipedia.org/wiki/Extensions_of_Fisher%27s_method

        Examples
        --------
        Suppose we wish to combine p-values from four independent tests
        of the same null hypothesis using Fisher's method (default).

        >>> from scipy.stats import combine_pvalues
        >>> pvalues = [0.1, 0.05, 0.02, 0.3]
        >>> combine_pvalues(pvalues)
        SignificanceResult(statistic=20.828626352604235, pvalue=0.007616871850449092)

        When the individual p-values carry different weights, consider Stouffer's
        method.

        >>> weights = [1, 2, 3, 4]
        >>> res = combine_pvalues(pvalues, method='stouffer', weights=weights)
        >>> res.pvalue
        0.009578891494533616

    cramervonmises(rvs, cdf, args=(), *, axis=0, nan_policy='propagate', keepdims=False)
        Perform the one-sample Cramér-von Mises test for goodness of fit.

        This performs a test of the goodness of fit of a cumulative distribution
        function (cdf) :math:`F` compared to the empirical distribution function
        :math:`F_n` of observed random variates :math:`X_1, ..., X_n` that are
        assumed to be independent and identically distributed ([1]_).
        The null hypothesis is that the :math:`X_i` have cumulative distribution
        :math:`F`.

        Parameters
        ----------
        rvs : array_like
            A 1-D array of observed values of the random variables :math:`X_i`.
            The sample must contain at least two observations.
        cdf : str or callable
            The cumulative distribution function :math:`F` to test the
            observations against. If a string, it should be the name of a
            distribution in `scipy.stats`. If a callable, that callable is used
            to calculate the cdf: ``cdf(x, *args) -> float``.
        args : tuple, optional
            Distribution parameters. These are assumed to be known; see Notes.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : object with attributes
            statistic : float
                Cramér-von Mises statistic.
            pvalue : float
                The p-value.

        See Also
        --------

        :func:`kstest`, :func:`cramervonmises_2samp`
            ..

        Notes
        -----
        .. versionadded:: 1.6.0

        The p-value relies on the approximation given by equation 1.8 in [2]_.
        It is important to keep in mind that the p-value is only accurate if
        one tests a simple hypothesis, i.e. the parameters of the reference
        distribution are known. If the parameters are estimated from the data
        (composite hypothesis), the computed p-value is not reliable.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Cramér-von Mises criterion, Wikipedia,
               https://en.wikipedia.org/wiki/Cram%C3%A9r%E2%80%93von_Mises_criterion
        .. [2] Csörgő, S. and Faraway, J. (1996). The Exact and Asymptotic
               Distribution of Cramér-von Mises Statistics. Journal of the
               Royal Statistical Society, pp. 221-234.

        Examples
        --------
        Suppose we wish to test whether data generated by ``scipy.stats.norm.rvs``
        were, in fact, drawn from the standard normal distribution. We choose a
        significance level of ``alpha=0.05``.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng(165417232101553420507139617764912913465)
        >>> x = stats.norm.rvs(size=500, random_state=rng)
        >>> res = stats.cramervonmises(x, 'norm')
        >>> res.statistic, res.pvalue
        (0.1072085112565724, 0.5508482238203407)

        The p-value exceeds our chosen significance level, so we do not
        reject the null hypothesis that the observed sample is drawn from the
        standard normal distribution.

        Now suppose we wish to check whether the same samples shifted by 2.1 is
        consistent with being drawn from a normal distribution with a mean of 2.

        >>> y = x + 2.1
        >>> res = stats.cramervonmises(y, 'norm', args=(2,))
        >>> res.statistic, res.pvalue
        (0.8364446265294695, 0.00596286797008283)

        Here we have used the `args` keyword to specify the mean (``loc``)
        of the normal distribution to test the data against. This is equivalent
        to the following, in which we create a frozen normal distribution with
        mean 2.1, then pass its ``cdf`` method as an argument.

        >>> frozen_dist = stats.norm(loc=2)
        >>> res = stats.cramervonmises(y, frozen_dist.cdf)
        >>> res.statistic, res.pvalue
        (0.8364446265294695, 0.00596286797008283)

        In either case, we would reject the null hypothesis that the observed
        sample is drawn from a normal distribution with a mean of 2 (and default
        variance of 1) because the p-value is less than our chosen
        significance level.

    cramervonmises_2samp(x, y, method='auto', *, axis=0, nan_policy='propagate', keepdims=False)
        Perform the two-sample Cramér-von Mises test for goodness of fit.

        This is the two-sample version of the Cramér-von Mises test ([1]_):
        for two independent samples :math:`X_1, ..., X_n` and
        :math:`Y_1, ..., Y_m`, the null hypothesis is that the samples
        come from the same (unspecified) continuous distribution.

        Parameters
        ----------
        x : array_like
            A 1-D array of observed values of the random variables :math:`X_i`.
            Must contain at least two observations.
        y : array_like
            A 1-D array of observed values of the random variables :math:`Y_i`.
            Must contain at least two observations.
        method : {'auto', 'asymptotic', 'exact'}, optional
            The method used to compute the p-value, see Notes for details.
            The default is 'auto'.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : object with attributes
            statistic : float
                Cramér-von Mises statistic.
            pvalue : float
                The p-value.

        See Also
        --------

        :func:`cramervonmises`, :func:`anderson_ksamp`, :func:`epps_singleton_2samp`, :func:`ks_2samp`
            ..

        Notes
        -----
        .. versionadded:: 1.7.0

        The statistic is computed according to equation 9 in [2]_. The
        calculation of the p-value depends on the keyword `method`:

        - ``asymptotic``: The p-value is approximated by using the limiting
          distribution of the test statistic.
        - ``exact``: The exact p-value is computed by enumerating all
          possible combinations of the test statistic, see [2]_.

        If ``method='auto'``, the exact approach is used
        if both samples contain equal to or less than 20 observations,
        otherwise the asymptotic distribution is used.

        If the underlying distribution is not continuous, the p-value is likely to
        be conservative (Section 6.2 in [3]_). When ranking the data to compute
        the test statistic, midranks are used if there are ties.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Cramer-von_Mises_criterion
        .. [2] Anderson, T.W. (1962). On the distribution of the two-sample
               Cramer-von-Mises criterion. The Annals of Mathematical
               Statistics, pp. 1148-1159.
        .. [3] Conover, W.J., Practical Nonparametric Statistics, 1971.

        Examples
        --------
        Suppose we wish to test whether two samples generated by
        ``scipy.stats.norm.rvs`` have the same distribution. We choose a
        significance level of alpha=0.05.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> x = stats.norm.rvs(size=100, random_state=rng)
        >>> y = stats.norm.rvs(size=70, random_state=rng)
        >>> res = stats.cramervonmises_2samp(x, y)
        >>> res.statistic, res.pvalue
        (0.29376470588235293, 0.1412873014573014)

        The p-value exceeds our chosen significance level, so we do not
        reject the null hypothesis that the observed samples are drawn from the
        same distribution.

        For small sample sizes, one can compute the exact p-values:

        >>> x = stats.norm.rvs(size=7, random_state=rng)
        >>> y = stats.t.rvs(df=2, size=6, random_state=rng)
        >>> res = stats.cramervonmises_2samp(x, y, method='exact')
        >>> res.statistic, res.pvalue
        (0.197802197802198, 0.31643356643356646)

        The p-value based on the asymptotic distribution is a good approximation
        even though the sample size is small.

        >>> res = stats.cramervonmises_2samp(x, y, method='asymptotic')
        >>> res.statistic, res.pvalue
        (0.197802197802198, 0.2966041181527128)

        Independent of the method, one would not reject the null hypothesis at the
        chosen significance level in this example.

    cumfreq(a, numbins=10, defaultreallimits=None, weights=None)
        Return a cumulative frequency histogram, using the histogram function.

        A cumulative histogram is a mapping that counts the cumulative number of
        observations in all of the bins up to the specified bin.

        Parameters
        ----------
        a : array_like
            Input array.
        numbins : int, optional
            The number of bins to use for the histogram. Default is 10.
        defaultreallimits : tuple (lower, upper), optional
            The lower and upper values for the range of the histogram.
            If no value is given, a range slightly larger than the range of the
            values in `a` is used. Specifically ``(a.min() - s, a.max() + s)``,
            where ``s = (1/2)(a.max() - a.min()) / (numbins - 1)``.
        weights : array_like, optional
            The weights for each value in `a`. Default is None, which gives each
            value a weight of 1.0

        Returns
        -------
        cumcount : ndarray
            Binned values of cumulative frequency.
        lowerlimit : float
            Lower real limit
        binsize : float
            Width of each bin.
        extrapoints : int
            Extra points.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> x = [1, 4, 2, 1, 3, 1]
        >>> res = stats.cumfreq(x, numbins=4, defaultreallimits=(1.5, 5))
        >>> res.cumcount
        array([ 1.,  2.,  3.,  3.])
        >>> res.extrapoints
        3

        Create a normal distribution with 1000 random values

        >>> samples = stats.norm.rvs(size=1000, random_state=rng)

        Calculate cumulative frequencies

        >>> res = stats.cumfreq(samples, numbins=25)

        Calculate space of values for x

        >>> x = res.lowerlimit + np.linspace(0, res.binsize*res.cumcount.size,
        ...                                  res.cumcount.size)

        Plot histogram and cumulative histogram

        >>> fig = plt.figure(figsize=(10, 4))
        >>> ax1 = fig.add_subplot(1, 2, 1)
        >>> ax2 = fig.add_subplot(1, 2, 2)
        >>> ax1.hist(samples, bins=25)
        >>> ax1.set_title('Histogram')
        >>> ax2.bar(x, res.cumcount, width=res.binsize)
        >>> ax2.set_title('Cumulative histogram')
        >>> ax2.set_xlim([x.min(), x.max()])

        >>> plt.show()

    describe(a, axis=0, ddof=1, bias=True, nan_policy='propagate')
        Compute several descriptive statistics of the passed array.

        Parameters
        ----------
        a : array_like
            Input data.
        axis : int or None, optional
            Axis along which statistics are calculated. Default is 0.
            If None, compute over the whole array `a`.
        ddof : int, optional
            Delta degrees of freedom (only for variance).  Default is 1.
        bias : bool, optional
            If False, then the skewness and kurtosis calculations are corrected
            for statistical bias.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is 'propagate'):

            * 'propagate': returns nan
            * 'raise': throws an error
            * 'omit': performs the calculations ignoring nan values

        Returns
        -------
        nobs : int or ndarray of ints
            Number of observations (length of data along `axis`).
            When 'omit' is chosen as nan_policy, the length along each axis
            slice is counted separately.
        minmax: tuple of ndarrays or floats
            Minimum and maximum value of `a` along the given axis.
        mean : ndarray or float
            Arithmetic mean of `a` along the given axis.
        variance : ndarray or float
            Unbiased variance of `a` along the given axis; denominator is number
            of observations minus one.
        skewness : ndarray or float
            Skewness of `a` along the given axis, based on moment calculations
            with denominator equal to the number of observations, i.e. no degrees
            of freedom correction.
        kurtosis : ndarray or float
            Kurtosis (Fisher) of `a` along the given axis.  The kurtosis is
            normalized so that it is zero for the normal distribution.  No
            degrees of freedom are used.

        See Also
        --------
        skew, kurtosis

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> a = np.arange(10)
        >>> stats.describe(a)
        DescribeResult(nobs=10, minmax=(0, 9), mean=4.5,
                       variance=9.166666666666666, skewness=0.0,
                       kurtosis=-1.2242424242424244)
        >>> b = [[1, 2], [3, 4]]
        >>> stats.describe(b)
        DescribeResult(nobs=2, minmax=(array([1, 2]), array([3, 4])),
                       mean=array([2., 3.]), variance=array([2., 2.]),
                       skewness=array([0., 0.]), kurtosis=array([-2., -2.]))

    differential_entropy(values: 'np.typing.ArrayLike', *, window_length: 'int | None' = None, base: 'float | None' = None, axis: 'int' = 0, method: 'str' = 'auto', nan_policy='propagate', keepdims=False) -> 'np.number | np.ndarray'
        Given a sample of a distribution, estimate the differential entropy.

        Several estimation methods are available using the `method` parameter. By
        default, a method is selected based the size of the sample.

        Parameters
        ----------
        values : sequence
            Sample from a continuous distribution.
        window_length : int, optional
            Window length for computing Vasicek estimate. Must be an integer
            between 1 and half of the sample size. If ``None`` (the default), it
            uses the heuristic value

            .. math::
                \left \lfloor \sqrt{n} + 0.5 \right \rfloor

            where :math:`n` is the sample size. This heuristic was originally
            proposed in [2]_ and has become common in the literature.
        base : float, optional
            The logarithmic base to use, defaults to ``e`` (natural logarithm).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        method : {'vasicek', 'van es', 'ebrahimi', 'correa', 'auto'}, optional
            The method used to estimate the differential entropy from the sample.
            Default is ``'auto'``.  See Notes for more information.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        entropy : float
            The calculated differential entropy.

        Notes
        -----
        This function will converge to the true differential entropy in the limit

        .. math::
            n \to \infty, \quad m \to \infty, \quad \frac{m}{n} \to 0

        The optimal choice of ``window_length`` for a given sample size depends on
        the (unknown) distribution. Typically, the smoother the density of the
        distribution, the larger the optimal value of ``window_length`` [1]_.

        The following options are available for the `method` parameter.

        * ``'vasicek'`` uses the estimator presented in [1]_. This is
          one of the first and most influential estimators of differential entropy.
        * ``'van es'`` uses the bias-corrected estimator presented in [3]_, which
          is not only consistent but, under some conditions, asymptotically normal.
        * ``'ebrahimi'`` uses an estimator presented in [4]_, which was shown
          in simulation to have smaller bias and mean squared error than
          the Vasicek estimator.
        * ``'correa'`` uses the estimator presented in [5]_ based on local linear
          regression. In a simulation study, it had consistently smaller mean
          square error than the Vasiceck estimator, but it is more expensive to
          compute.
        * ``'auto'`` selects the method automatically (default). Currently,
          this selects ``'van es'`` for very small samples (<10), ``'ebrahimi'``
          for moderate sample sizes (11-1000), and ``'vasicek'`` for larger
          samples, but this behavior is subject to change in future versions.

        All estimators are implemented as described in [6]_.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Vasicek, O. (1976). A test for normality based on sample entropy.
               Journal of the Royal Statistical Society:
               Series B (Methodological), 38(1), 54-59.
        .. [2] Crzcgorzewski, P., & Wirczorkowski, R. (1999). Entropy-based
               goodness-of-fit test for exponentiality. Communications in
               Statistics-Theory and Methods, 28(5), 1183-1202.
        .. [3] Van Es, B. (1992). Estimating functionals related to a density by a
               class of statistics based on spacings. Scandinavian Journal of
               Statistics, 61-72.
        .. [4] Ebrahimi, N., Pflughoeft, K., & Soofi, E. S. (1994). Two measures
               of sample entropy. Statistics & Probability Letters, 20(3), 225-234.
        .. [5] Correa, J. C. (1995). A new estimator of entropy. Communications
               in Statistics-Theory and Methods, 24(10), 2439-2449.
        .. [6] Noughabi, H. A. (2015). Entropy Estimation Using Numerical Methods.
               Annals of Data Science, 2(2), 231-241.
               https://link.springer.com/article/10.1007/s40745-015-0045-9

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import differential_entropy, norm

        Entropy of a standard normal distribution:

        >>> rng = np.random.default_rng()
        >>> values = rng.standard_normal(100)
        >>> differential_entropy(values)
        1.3407817436640392

        Compare with the true entropy:

        >>> float(norm.entropy())
        1.4189385332046727

        For several sample sizes between 5 and 1000, compare the accuracy of
        the ``'vasicek'``, ``'van es'``, and ``'ebrahimi'`` methods. Specifically,
        compare the root mean squared error (over 1000 trials) between the estimate
        and the true differential entropy of the distribution.

        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>>
        >>>
        >>> def rmse(res, expected):
        ...     '''Root mean squared error'''
        ...     return np.sqrt(np.mean((res - expected)**2))
        >>>
        >>>
        >>> a, b = np.log10(5), np.log10(1000)
        >>> ns = np.round(np.logspace(a, b, 10)).astype(int)
        >>> reps = 1000  # number of repetitions for each sample size
        >>> expected = stats.expon.entropy()
        >>>
        >>> method_errors = {'vasicek': [], 'van es': [], 'ebrahimi': []}
        >>> for method in method_errors:
        ...     for n in ns:
        ...        rvs = stats.expon.rvs(size=(reps, n), random_state=rng)
        ...        res = stats.differential_entropy(rvs, method=method, axis=-1)
        ...        error = rmse(res, expected)
        ...        method_errors[method].append(error)
        >>>
        >>> for method, errors in method_errors.items():
        ...     plt.loglog(ns, errors, label=method)
        >>>
        >>> plt.legend()
        >>> plt.xlabel('sample size')
        >>> plt.ylabel('RMSE (1000 trials)')
        >>> plt.title('Entropy Estimator Error (Exponential Distribution)')

    directional_stats(samples, *, axis=0, normalize=True)
        Computes sample statistics for directional data.

        Computes the directional mean (also called the mean direction vector) and
        mean resultant length of a sample of vectors.

        The directional mean is a measure of "preferred direction" of vector data.
        It is analogous to the sample mean, but it is for use when the length of
        the data is irrelevant (e.g. unit vectors).

        The mean resultant length is a value between 0 and 1 used to quantify the
        dispersion of directional data: the smaller the mean resultant length, the
        greater the dispersion. Several definitions of directional variance
        involving the mean resultant length are given in [1]_ and [2]_.

        Parameters
        ----------
        samples : array_like
            Input array. Must be at least two-dimensional, and the last axis of the
            input must correspond with the dimensionality of the vector space.
            When the input is exactly two dimensional, this means that each row
            of the data is a vector observation.
        axis : int, default: 0
            Axis along which the directional mean is computed.
        normalize: boolean, default: True
            If True, normalize the input to ensure that each observation is a
            unit vector. It the observations are already unit vectors, consider
            setting this to False to avoid unnecessary computation.

        Returns
        -------
        res : DirectionalStats
            An object containing attributes:

            mean_direction : ndarray
                Directional mean.
            mean_resultant_length : ndarray
                The mean resultant length [1]_.

        See Also
        --------
        circmean: circular mean; i.e. directional mean for 2D *angles*
        circvar: circular variance; i.e. directional variance for 2D *angles*

        Notes
        -----
        This uses a definition of directional mean from [1]_.
        Assuming the observations are unit vectors, the calculation is as follows.

        .. code-block:: python

            mean = samples.mean(axis=0)
            mean_resultant_length = np.linalg.norm(mean)
            mean_direction = mean / mean_resultant_length

        This definition is appropriate for *directional* data (i.e. vector data
        for which the magnitude of each observation is irrelevant) but not
        for *axial* data (i.e. vector data for which the magnitude and *sign* of
        each observation is irrelevant).

        Several definitions of directional variance involving the mean resultant
        length ``R`` have been proposed, including ``1 - R`` [1]_, ``1 - R**2``
        [2]_, and ``2 * (1 - R)`` [2]_. Rather than choosing one, this function
        returns ``R`` as attribute `mean_resultant_length` so the user can compute
        their preferred measure of dispersion.

        References
        ----------
        .. [1] Mardia, Jupp. (2000). *Directional Statistics*
           (p. 163). Wiley.

        .. [2] https://en.wikipedia.org/wiki/Directional_statistics

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import directional_stats
        >>> data = np.array([[3, 4],    # first observation, 2D vector space
        ...                  [6, -8]])  # second observation
        >>> dirstats = directional_stats(data)
        >>> dirstats.mean_direction
        array([1., 0.])

        In contrast, the regular sample mean of the vectors would be influenced
        by the magnitude of each observation. Furthermore, the result would not be
        a unit vector.

        >>> data.mean(axis=0)
        array([4.5, -2.])

        An exemplary use case for `directional_stats` is to find a *meaningful*
        center for a set of observations on a sphere, e.g. geographical locations.

        >>> data = np.array([[0.8660254, 0.5, 0.],
        ...                  [0.8660254, -0.5, 0.]])
        >>> dirstats = directional_stats(data)
        >>> dirstats.mean_direction
        array([1., 0., 0.])

        The regular sample mean on the other hand yields a result which does not
        lie on the surface of the sphere.

        >>> data.mean(axis=0)
        array([0.8660254, 0., 0.])

        The function also returns the mean resultant length, which
        can be used to calculate a directional variance. For example, using the
        definition ``Var(z) = 1 - R`` from [2]_ where ``R`` is the
        mean resultant length, we can calculate the directional variance of the
        vectors in the above example as:

        >>> 1 - dirstats.mean_resultant_length
        0.13397459716167093

    dunnett(*samples: 'npt.ArrayLike', control: 'npt.ArrayLike', alternative: "Literal['two-sided', 'less', 'greater']" = 'two-sided', random_state: 'SeedType' = None) -> 'DunnettResult'
        Dunnett's test: multiple comparisons of means against a control group.

        This is an implementation of Dunnett's original, single-step test as
        described in [1]_.

        Parameters
        ----------
        sample1, sample2, ... : 1D array_like
            The sample measurements for each experimental group.
        control : 1D array_like
            The sample measurements for the control group.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.

            The null hypothesis is that the means of the distributions underlying
            the samples and control are equal. The following alternative
            hypotheses are available (default is 'two-sided'):

            * 'two-sided': the means of the distributions underlying the samples
              and control are unequal.
            * 'less': the means of the distributions underlying the samples
              are less than the mean of the distribution underlying the control.
            * 'greater': the means of the distributions underlying the
              samples are greater than the mean of the distribution underlying
              the control.
        random_state : {None, int, `numpy.random.Generator`}, optional
            If `random_state` is an int or None, a new `numpy.random.Generator` is
            created using ``np.random.default_rng(random_state)``.
            If `random_state` is already a ``Generator`` instance, then the
            provided instance is used.

            The random number generator is used to control the randomized
            Quasi-Monte Carlo integration of the multivariate-t distribution.

        Returns
        -------
        res : `~scipy.stats._result_classes.DunnettResult`
            An object containing attributes:

            statistic : float ndarray
                The computed statistic of the test for each comparison. The element
                at index ``i`` is the statistic for the comparison between
                groups ``i`` and the control.
            pvalue : float ndarray
                The computed p-value of the test for each comparison. The element
                at index ``i`` is the p-value for the comparison between
                group ``i`` and the control.

            And the following method:

            confidence_interval(confidence_level=0.95) :
                Compute the difference in means of the groups
                with the control +- the allowance.

        See Also
        --------
        tukey_hsd : performs pairwise comparison of means.

        Notes
        -----
        Like the independent-sample t-test, Dunnett's test [1]_ is used to make
        inferences about the means of distributions from which samples were drawn.
        However, when multiple t-tests are performed at a fixed significance level,
        the "family-wise error rate" - the probability of incorrectly rejecting the
        null hypothesis in at least one test - will exceed the significance level.
        Dunnett's test is designed to perform multiple comparisons while
        controlling the family-wise error rate.

        Dunnett's test compares the means of multiple experimental groups
        against a single control group. Tukey's Honestly Significant Difference Test
        is another multiple-comparison test that controls the family-wise error
        rate, but `tukey_hsd` performs *all* pairwise comparisons between groups.
        When pairwise comparisons between experimental groups are not needed,
        Dunnett's test is preferable due to its higher power.


        The use of this test relies on several assumptions.

        1. The observations are independent within and among groups.
        2. The observations within each group are normally distributed.
        3. The distributions from which the samples are drawn have the same finite
           variance.

        References
        ----------
        .. [1] Charles W. Dunnett. "A Multiple Comparison Procedure for Comparing
           Several Treatments with a Control."
           Journal of the American Statistical Association, 50:272, 1096-1121,
           :doi:`10.1080/01621459.1955.10501294`, 1955.

        Examples
        --------
        In [1]_, the influence of drugs on blood count measurements on three groups
        of animal is investigated.

        The following table summarizes the results of the experiment in which
        two groups received different drugs, and one group acted as a control.
        Blood counts (in millions of cells per cubic millimeter) were recorded::

        >>> import numpy as np
        >>> control = np.array([7.40, 8.50, 7.20, 8.24, 9.84, 8.32])
        >>> drug_a = np.array([9.76, 8.80, 7.68, 9.36])
        >>> drug_b = np.array([12.80, 9.68, 12.16, 9.20, 10.55])

        We would like to see if the means between any of the groups are
        significantly different. First, visually examine a box and whisker plot.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.boxplot([control, drug_a, drug_b])
        >>> ax.set_xticklabels(["Control", "Drug A", "Drug B"])  # doctest: +SKIP
        >>> ax.set_ylabel("mean")  # doctest: +SKIP
        >>> plt.show()

        Note the overlapping interquartile ranges of the drug A group and control
        group and the apparent separation between the drug B group and control
        group.

        Next, we will use Dunnett's test to assess whether the difference
        between group means is significant while controlling the family-wise error
        rate: the probability of making any false discoveries.
        Let the null hypothesis be that the experimental groups have the same
        mean as the control and the alternative be that an experimental group does
        not have the same mean as the control. We will consider a 5% family-wise
        error rate to be acceptable, and therefore we choose 0.05 as the threshold
        for significance.

        >>> from scipy.stats import dunnett
        >>> res = dunnett(drug_a, drug_b, control=control)
        >>> res.pvalue
        array([0.62004941, 0.0059035 ])  # may vary

        The p-value corresponding with the comparison between group A and control
        exceeds 0.05, so we do not reject the null hypothesis for that comparison.
        However, the p-value corresponding with the comparison between group B
        and control is less than 0.05, so we consider the experimental results
        to be evidence against the null hypothesis in favor of the alternative:
        group B has a different mean than the control group.

    ecdf(sample: 'npt.ArrayLike | CensoredData') -> 'ECDFResult'
        Empirical cumulative distribution function of a sample.

        The empirical cumulative distribution function (ECDF) is a step function
        estimate of the CDF of the distribution underlying a sample. This function
        returns objects representing both the empirical distribution function and
        its complement, the empirical survival function.

        Parameters
        ----------
        sample : 1D array_like or `scipy.stats.CensoredData`
            Besides array_like, instances of `scipy.stats.CensoredData` containing
            uncensored and right-censored observations are supported. Currently,
            other instances of `scipy.stats.CensoredData` will result in a
            ``NotImplementedError``.

        Returns
        -------
        res : `~scipy.stats._result_classes.ECDFResult`
            An object with the following attributes.

            cdf : `~scipy.stats._result_classes.EmpiricalDistributionFunction`
                An object representing the empirical cumulative distribution
                function.
            sf : `~scipy.stats._result_classes.EmpiricalDistributionFunction`
                An object representing the empirical survival function.

            The `cdf` and `sf` attributes themselves have the following attributes.

            quantiles : ndarray
                The unique values in the sample that defines the empirical CDF/SF.
            probabilities : ndarray
                The point estimates of the probabilities corresponding with
                `quantiles`.

            And the following methods:

            evaluate(x) :
                Evaluate the CDF/SF at the argument.

            plot(ax) :
                Plot the CDF/SF on the provided axes.

            confidence_interval(confidence_level=0.95) :
                Compute the confidence interval around the CDF/SF at the values in
                `quantiles`.

        Notes
        -----
        When each observation of the sample is a precise measurement, the ECDF
        steps up by ``1/len(sample)`` at each of the observations [1]_.

        When observations are lower bounds, upper bounds, or both upper and lower
        bounds, the data is said to be "censored", and `sample` may be provided as
        an instance of `scipy.stats.CensoredData`.

        For right-censored data, the ECDF is given by the Kaplan-Meier estimator
        [2]_; other forms of censoring are not supported at this time.

        Confidence intervals are computed according to the Greenwood formula or the
        more recent "Exponential Greenwood" formula as described in [4]_.

        References
        ----------
        .. [1] Conover, William Jay. Practical nonparametric statistics. Vol. 350.
               John Wiley & Sons, 1999.

        .. [2] Kaplan, Edward L., and Paul Meier. "Nonparametric estimation from
               incomplete observations." Journal of the American statistical
               association 53.282 (1958): 457-481.

        .. [3] Goel, Manish Kumar, Pardeep Khanna, and Jugal Kishore.
               "Understanding survival analysis: Kaplan-Meier estimate."
               International journal of Ayurveda research 1.4 (2010): 274.

        .. [4] Sawyer, Stanley. "The Greenwood and Exponential Greenwood Confidence
               Intervals in Survival Analysis."
               https://www.math.wustl.edu/~sawyer/handouts/greenwood.pdf

        Examples
        --------
        **Uncensored Data**

        As in the example from [1]_ page 79, five boys were selected at random from
        those in a single high school. Their one-mile run times were recorded as
        follows.

        >>> sample = [6.23, 5.58, 7.06, 6.42, 5.20]  # one-mile run times (minutes)

        The empirical distribution function, which approximates the distribution
        function of one-mile run times of the population from which the boys were
        sampled, is calculated as follows.

        >>> from scipy import stats
        >>> res = stats.ecdf(sample)
        >>> res.cdf.quantiles
        array([5.2 , 5.58, 6.23, 6.42, 7.06])
        >>> res.cdf.probabilities
        array([0.2, 0.4, 0.6, 0.8, 1. ])

        To plot the result as a step function:

        >>> import matplotlib.pyplot as plt
        >>> ax = plt.subplot()
        >>> res.cdf.plot(ax)
        >>> ax.set_xlabel('One-Mile Run Time (minutes)')
        >>> ax.set_ylabel('Empirical CDF')
        >>> plt.show()

        **Right-censored Data**

        As in the example from [1]_ page 91, the lives of ten car fanbelts were
        tested. Five tests concluded because the fanbelt being tested broke, but
        the remaining tests concluded for other reasons (e.g. the study ran out of
        funding, but the fanbelt was still functional). The mileage driven
        with the fanbelts were recorded as follows.

        >>> broken = [77, 47, 81, 56, 80]  # in thousands of miles driven
        >>> unbroken = [62, 60, 43, 71, 37]

        Precise survival times of the fanbelts that were still functional at the
        end of the tests are unknown, but they are known to exceed the values
        recorded in ``unbroken``. Therefore, these observations are said to be
        "right-censored", and the data is represented using
        `scipy.stats.CensoredData`.

        >>> sample = stats.CensoredData(uncensored=broken, right=unbroken)

        The empirical survival function is calculated as follows.

        >>> res = stats.ecdf(sample)
        >>> res.sf.quantiles
        array([37., 43., 47., 56., 60., 62., 71., 77., 80., 81.])
        >>> res.sf.probabilities
        array([1.   , 1.   , 0.875, 0.75 , 0.75 , 0.75 , 0.75 , 0.5  , 0.25 , 0.   ])

        To plot the result as a step function:

        >>> ax = plt.subplot()
        >>> res.cdf.plot(ax)
        >>> ax.set_xlabel('Fanbelt Survival Time (thousands of miles)')
        >>> ax.set_ylabel('Empirical SF')
        >>> plt.show()

    energy_distance(u_values, v_values, u_weights=None, v_weights=None)
        Compute the energy distance between two 1D distributions.

        .. versionadded:: 1.0.0

        Parameters
        ----------
        u_values, v_values : array_like
            Values observed in the (empirical) distribution.
        u_weights, v_weights : array_like, optional
            Weight for each value. If unspecified, each value is assigned the same
            weight.
            `u_weights` (resp. `v_weights`) must have the same length as
            `u_values` (resp. `v_values`). If the weight sum differs from 1, it
            must still be positive and finite so that the weights can be normalized
            to sum to 1.

        Returns
        -------
        distance : float
            The computed distance between the distributions.

        Notes
        -----
        The energy distance between two distributions :math:`u` and :math:`v`, whose
        respective CDFs are :math:`U` and :math:`V`, equals to:

        .. math::

            D(u, v) = \left( 2\mathbb E|X - Y| - \mathbb E|X - X'| -
            \mathbb E|Y - Y'| \right)^{1/2}

        where :math:`X` and :math:`X'` (resp. :math:`Y` and :math:`Y'`) are
        independent random variables whose probability distribution is :math:`u`
        (resp. :math:`v`).

        Sometimes the square of this quantity is referred to as the "energy
        distance" (e.g. in [2]_, [4]_), but as noted in [1]_ and [3]_, only the
        definition above satisfies the axioms of a distance function (metric).

        As shown in [2]_, for one-dimensional real-valued variables, the energy
        distance is linked to the non-distribution-free version of the Cramér-von
        Mises distance:

        .. math::

            D(u, v) = \sqrt{2} l_2(u, v) = \left( 2 \int_{-\infty}^{+\infty} (U-V)^2
            \right)^{1/2}

        Note that the common Cramér-von Mises criterion uses the distribution-free
        version of the distance. See [2]_ (section 2), for more details about both
        versions of the distance.

        The input distributions can be empirical, therefore coming from samples
        whose values are effectively inputs of the function, or they can be seen as
        generalized functions, in which case they are weighted sums of Dirac delta
        functions located at the specified values.

        References
        ----------
        .. [1] Rizzo, Szekely "Energy distance." Wiley Interdisciplinary Reviews:
               Computational Statistics, 8(1):27-38 (2015).
        .. [2] Szekely "E-statistics: The energy of statistical samples." Bowling
               Green State University, Department of Mathematics and Statistics,
               Technical Report 02-16 (2002).
        .. [3] "Energy distance", https://en.wikipedia.org/wiki/Energy_distance
        .. [4] Bellemare, Danihelka, Dabney, Mohamed, Lakshminarayanan, Hoyer,
               Munos "The Cramer Distance as a Solution to Biased Wasserstein
               Gradients" (2017). :arXiv:`1705.10743`.

        Examples
        --------
        >>> from scipy.stats import energy_distance
        >>> energy_distance([0], [2])
        2.0000000000000004
        >>> energy_distance([0, 8], [0, 8], [3, 1], [2, 2])
        1.0000000000000002
        >>> energy_distance([0.7, 7.4, 2.4, 6.8], [1.4, 8. ],
        ...                 [2.1, 4.2, 7.4, 8. ], [7.6, 8.8])
        0.88003340976158217

    entropy(pk: 'np.typing.ArrayLike', qk: 'np.typing.ArrayLike | None' = None, base: 'float | None' = None, axis: 'int' = 0, *, nan_policy='propagate', keepdims=False) -> 'np.number | np.ndarray'
        Calculate the Shannon entropy/relative entropy of given distribution(s).

        If only probabilities `pk` are given, the Shannon entropy is calculated as
        ``H = -sum(pk * log(pk))``.

        If `qk` is not None, then compute the relative entropy
        ``D = sum(pk * log(pk / qk))``. This quantity is also known
        as the Kullback-Leibler divergence.

        This routine will normalize `pk` and `qk` if they don't sum to 1.

        Parameters
        ----------
        pk : array_like
            Defines the (discrete) distribution. Along each axis-slice of ``pk``,
            element ``i`` is the  (possibly unnormalized) probability of event
            ``i``.
        qk : array_like, optional
            Sequence against which the relative entropy is computed. Should be in
            the same format as `pk`.
        base : float, optional
            The logarithmic base to use, defaults to ``e`` (natural logarithm).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        S : {float, array_like}
            The calculated entropy.

        Notes
        -----
        Informally, the Shannon entropy quantifies the expected uncertainty
        inherent in the possible outcomes of a discrete random variable.
        For example,
        if messages consisting of sequences of symbols from a set are to be
        encoded and transmitted over a noiseless channel, then the Shannon entropy
        ``H(pk)`` gives a tight lower bound for the average number of units of
        information needed per symbol if the symbols occur with frequencies
        governed by the discrete distribution `pk` [1]_. The choice of base
        determines the choice of units; e.g., ``e`` for nats, ``2`` for bits, etc.

        The relative entropy, ``D(pk|qk)``, quantifies the increase in the average
        number of units of information needed per symbol if the encoding is
        optimized for the probability distribution `qk` instead of the true
        distribution `pk`. Informally, the relative entropy quantifies the expected
        excess in surprise experienced if one believes the true distribution is
        `qk` when it is actually `pk`.

        A related quantity, the cross entropy ``CE(pk, qk)``, satisfies the
        equation ``CE(pk, qk) = H(pk) + D(pk|qk)`` and can also be calculated with
        the formula ``CE = -sum(pk * log(qk))``. It gives the average
        number of units of information needed per symbol if an encoding is
        optimized for the probability distribution `qk` when the true distribution
        is `pk`. It is not computed directly by `entropy`, but it can be computed
        using two calls to the function (see Examples).

        See [2]_ for more information.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Shannon, C.E. (1948), A Mathematical Theory of Communication.
               Bell System Technical Journal, 27: 379-423.
               https://doi.org/10.1002/j.1538-7305.1948.tb01338.x
        .. [2] Thomas M. Cover and Joy A. Thomas. 2006. Elements of Information
               Theory (Wiley Series in Telecommunications and Signal Processing).
               Wiley-Interscience, USA.

        Examples
        --------
        The outcome of a fair coin is the most uncertain:

        >>> import numpy as np
        >>> from scipy.stats import entropy
        >>> base = 2  # work in units of bits
        >>> pk = np.array([1/2, 1/2])  # fair coin
        >>> H = entropy(pk, base=base)
        >>> H
        1.0
        >>> H == -np.sum(pk * np.log(pk)) / np.log(base)
        True

        The outcome of a biased coin is less uncertain:

        >>> qk = np.array([9/10, 1/10])  # biased coin
        >>> entropy(qk, base=base)
        0.46899559358928117

        The relative entropy between the fair coin and biased coin is calculated
        as:

        >>> D = entropy(pk, qk, base=base)
        >>> D
        0.7369655941662062
        >>> D == np.sum(pk * np.log(pk/qk)) / np.log(base)
        True

        The cross entropy can be calculated as the sum of the entropy and
        relative entropy`:

        >>> CE = entropy(pk, base=base) + entropy(pk, qk, base=base)
        >>> CE
        1.736965594166206
        >>> CE == -np.sum(pk * np.log(qk)) / np.log(base)
        True

    epps_singleton_2samp(x, y, t=(0.4, 0.8), *, axis=0, nan_policy='propagate', keepdims=False)
        Compute the Epps-Singleton (ES) test statistic.

        Test the null hypothesis that two samples have the same underlying
        probability distribution.

        Parameters
        ----------
        x, y : array-like
            The two samples of observations to be tested. Input must not have more
            than one dimension. Samples can have different lengths, but both
            must have at least five observations.
        t : array-like, optional
            The points (t1, ..., tn) where the empirical characteristic function is
            to be evaluated. It should be positive distinct numbers. The default
            value (0.4, 0.8) is proposed in [1]_. Input must not have more than
            one dimension.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic.
        pvalue : float
            The associated p-value based on the asymptotic chi2-distribution.

        See Also
        --------

        :func:`ks_2samp`, :func:`anderson_ksamp`
            ..

        Notes
        -----
        Testing whether two samples are generated by the same underlying
        distribution is a classical question in statistics. A widely used test is
        the Kolmogorov-Smirnov (KS) test which relies on the empirical
        distribution function. Epps and Singleton introduce a test based on the
        empirical characteristic function in [1]_.

        One advantage of the ES test compared to the KS test is that is does
        not assume a continuous distribution. In [1]_, the authors conclude
        that the test also has a higher power than the KS test in many
        examples. They recommend the use of the ES test for discrete samples as
        well as continuous samples with at least 25 observations each, whereas
        `anderson_ksamp` is recommended for smaller sample sizes in the
        continuous case.

        The p-value is computed from the asymptotic distribution of the test
        statistic which follows a `chi2` distribution. If the sample size of both
        `x` and `y` is below 25, the small sample correction proposed in [1]_ is
        applied to the test statistic.

        The default values of `t` are determined in [1]_ by considering
        various distributions and finding good values that lead to a high power
        of the test in general. Table III in [1]_ gives the optimal values for
        the distributions tested in that study. The values of `t` are scaled by
        the semi-interquartile range in the implementation, see [1]_.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] T. W. Epps and K. J. Singleton, "An omnibus test for the two-sample
           problem using the empirical characteristic function", Journal of
           Statistical Computation and Simulation 26, p. 177--203, 1986.

        .. [2] S. J. Goerg and J. Kaiser, "Nonparametric testing of distributions
           - the Epps-Singleton two-sample test using the empirical characteristic
           function", The Stata Journal 9(3), p. 454--465, 2009.

    expectile(a, alpha=0.5, *, weights=None)
        Compute the expectile at the specified level.

        Expectiles are a generalization of the expectation in the same way as
        quantiles are a generalization of the median. The expectile at level
        `alpha = 0.5` is the mean (average). See Notes for more details.

        Parameters
        ----------
        a : array_like
            Array containing numbers whose expectile is desired.
        alpha : float, default: 0.5
            The level of the expectile; e.g., `alpha=0.5` gives the mean.
        weights : array_like, optional
            An array of weights associated with the values in `a`.
            The `weights` must be broadcastable to the same shape as `a`.
            Default is None, which gives each value a weight of 1.0.
            An integer valued weight element acts like repeating the corresponding
            observation in `a` that many times. See Notes for more details.

        Returns
        -------
        expectile : ndarray
            The empirical expectile at level `alpha`.

        See Also
        --------
        numpy.mean : Arithmetic average
        numpy.quantile : Quantile

        Notes
        -----
        In general, the expectile at level :math:`\alpha` of a random variable
        :math:`X` with cumulative distribution function (CDF) :math:`F` is given
        by the unique solution :math:`t` of:

        .. math::

            \alpha E((X - t)_+) = (1 - \alpha) E((t - X)_+) \,.

        Here, :math:`(x)_+ = \max(0, x)` is the positive part of :math:`x`.
        This equation can be equivalently written as:

        .. math::

            \alpha \int_t^\infty (x - t)\mathrm{d}F(x)
            = (1 - \alpha) \int_{-\infty}^t (t - x)\mathrm{d}F(x) \,.

        The empirical expectile at level :math:`\alpha` (`alpha`) of a sample
        :math:`a_i` (the array `a`) is defined by plugging in the empirical CDF of
        `a`. Given sample or case weights :math:`w` (the array `weights`), it
        reads :math:`F_a(x) = \frac{1}{\sum_i w_i} \sum_i w_i 1_{a_i \leq x}`
        with indicator function :math:`1_{A}`. This leads to the definition of the
        empirical expectile at level `alpha` as the unique solution :math:`t` of:

        .. math::

            \alpha \sum_{i=1}^n w_i (a_i - t)_+ =
                (1 - \alpha) \sum_{i=1}^n w_i (t - a_i)_+ \,.

        For :math:`\alpha=0.5`, this simplifies to the weighted average.
        Furthermore, the larger :math:`\alpha`, the larger the value of the
        expectile.

        As a final remark, the expectile at level :math:`\alpha` can also be
        written as a minimization problem. One often used choice is

        .. math::

            \operatorname{argmin}_t
            E(\lvert 1_{t\geq X} - \alpha\rvert(t - X)^2) \,.

        References
        ----------
        .. [1] W. K. Newey and J. L. Powell (1987), "Asymmetric Least Squares
               Estimation and Testing," Econometrica, 55, 819-847.
        .. [2] T. Gneiting (2009). "Making and Evaluating Point Forecasts,"
               Journal of the American Statistical Association, 106, 746 - 762.
               :doi:`10.48550/arXiv.0912.0902`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import expectile
        >>> a = [1, 4, 2, -1]
        >>> expectile(a, alpha=0.5) == np.mean(a)
        True
        >>> expectile(a, alpha=0.2)
        0.42857142857142855
        >>> expectile(a, alpha=0.8)
        2.5714285714285716
        >>> weights = [1, 3, 1, 1]

    f_oneway(*samples, axis=0, nan_policy='propagate', keepdims=False)
        Perform one-way ANOVA.

        The one-way ANOVA tests the null hypothesis that two or more groups have
        the same population mean.  The test is applied to samples from two or
        more groups, possibly with differing sizes.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            The sample measurements for each group.  There must be at least
            two arguments.  If the arrays are multidimensional, then all the
            dimensions of the array must be the same except for `axis`.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The computed F statistic of the test.
        pvalue : float
            The associated p-value from the F distribution.

        Warns
        -----
        `~scipy.stats.ConstantInputWarning`
            Emitted if all values within each of the input arrays are identical.
            In this case the F statistic is either infinite or isn't defined,
            so ``np.inf`` or ``np.nan`` is returned.
        RuntimeWarning
            Emitted if the length of any input array is 0, or if all the input
            arrays have length 1.  ``np.nan`` is returned for the F statistic
            and the p-value in these cases.

        Notes
        -----
        The ANOVA test has important assumptions that must be satisfied in order
        for the associated p-value to be valid.

        1. The samples are independent.
        2. Each sample is from a normally distributed population.
        3. The population standard deviations of the groups are all equal.  This
           property is known as homoscedasticity.

        If these assumptions are not true for a given set of data, it may still
        be possible to use the Kruskal-Wallis H-test (`scipy.stats.kruskal`) or
        the Alexander-Govern test (`scipy.stats.alexandergovern`) although with
        some loss of power.

        The length of each group must be at least one, and there must be at
        least one group with length greater than one.  If these conditions
        are not satisfied, a warning is generated and (``np.nan``, ``np.nan``)
        is returned.

        If all values in each group are identical, and there exist at least two
        groups with different values, the function generates a warning and
        returns (``np.inf``, 0).

        If all values in all groups are the same, function generates a warning
        and returns (``np.nan``, ``np.nan``).

        The algorithm is from Heiman [2]_, pp.394-7.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] R. Lowry, "Concepts and Applications of Inferential Statistics",
               Chapter 14, 2014, http://vassarstats.net/textbook/

        .. [2] G.W. Heiman, "Understanding research methods and statistics: An
               integrated introduction for psychology", Houghton, Mifflin and
               Company, 2001.

        .. [3] G.H. McDonald, "Handbook of Biological Statistics", One-way ANOVA.
               http://www.biostathandbook.com/onewayanova.html

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import f_oneway

        Here are some data [3]_ on a shell measurement (the length of the anterior
        adductor muscle scar, standardized by dividing by length) in the mussel
        Mytilus trossulus from five locations: Tillamook, Oregon; Newport, Oregon;
        Petersburg, Alaska; Magadan, Russia; and Tvarminne, Finland, taken from a
        much larger data set used in McDonald et al. (1991).

        >>> tillamook = [0.0571, 0.0813, 0.0831, 0.0976, 0.0817, 0.0859, 0.0735,
        ...              0.0659, 0.0923, 0.0836]
        >>> newport = [0.0873, 0.0662, 0.0672, 0.0819, 0.0749, 0.0649, 0.0835,
        ...            0.0725]
        >>> petersburg = [0.0974, 0.1352, 0.0817, 0.1016, 0.0968, 0.1064, 0.105]
        >>> magadan = [0.1033, 0.0915, 0.0781, 0.0685, 0.0677, 0.0697, 0.0764,
        ...            0.0689]
        >>> tvarminne = [0.0703, 0.1026, 0.0956, 0.0973, 0.1039, 0.1045]
        >>> f_oneway(tillamook, newport, petersburg, magadan, tvarminne)
        F_onewayResult(statistic=7.121019471642447, pvalue=0.0002812242314534544)

        `f_oneway` accepts multidimensional input arrays.  When the inputs
        are multidimensional and `axis` is not given, the test is performed
        along the first axis of the input arrays.  For the following data, the
        test is performed three times, once for each column.

        >>> a = np.array([[9.87, 9.03, 6.81],
        ...               [7.18, 8.35, 7.00],
        ...               [8.39, 7.58, 7.68],
        ...               [7.45, 6.33, 9.35],
        ...               [6.41, 7.10, 9.33],
        ...               [8.00, 8.24, 8.44]])
        >>> b = np.array([[6.35, 7.30, 7.16],
        ...               [6.65, 6.68, 7.63],
        ...               [5.72, 7.73, 6.72],
        ...               [7.01, 9.19, 7.41],
        ...               [7.75, 7.87, 8.30],
        ...               [6.90, 7.97, 6.97]])
        >>> c = np.array([[3.31, 8.77, 1.01],
        ...               [8.25, 3.24, 3.62],
        ...               [6.32, 8.81, 5.19],
        ...               [7.48, 8.83, 8.91],
        ...               [8.59, 6.01, 6.07],
        ...               [3.07, 9.72, 7.48]])
        >>> F, p = f_oneway(a, b, c)
        >>> F
        array([1.75676344, 0.03701228, 3.76439349])
        >>> p
        array([0.20630784, 0.96375203, 0.04733157])

    false_discovery_control(ps, *, axis=0, method='bh')
        Adjust p-values to control the false discovery rate.

        The false discovery rate (FDR) is the expected proportion of rejected null
        hypotheses that are actually true.
        If the null hypothesis is rejected when the *adjusted* p-value falls below
        a specified level, the false discovery rate is controlled at that level.

        Parameters
        ----------
        ps : 1D array_like
            The p-values to adjust. Elements must be real numbers between 0 and 1.
        axis : int
            The axis along which to perform the adjustment. The adjustment is
            performed independently along each axis-slice. If `axis` is None, `ps`
            is raveled before performing the adjustment.
        method : {'bh', 'by'}
            The false discovery rate control procedure to apply: ``'bh'`` is for
            Benjamini-Hochberg [1]_ (Eq. 1), ``'by'`` is for Benjaminini-Yekutieli
            [2]_ (Theorem 1.3). The latter is more conservative, but it is
            guaranteed to control the FDR even when the p-values are not from
            independent tests.

        Returns
        -------
        ps_adusted : array_like
            The adjusted p-values. If the null hypothesis is rejected where these
            fall below a specified level, the false discovery rate is controlled
            at that level.

        See Also
        --------
        combine_pvalues
        statsmodels.stats.multitest.multipletests

        Notes
        -----
        In multiple hypothesis testing, false discovery control procedures tend to
        offer higher power than familywise error rate control procedures (e.g.
        Bonferroni correction [1]_).

        If the p-values correspond with independent tests (or tests with
        "positive regression dependencies" [2]_), rejecting null hypotheses
        corresponding with Benjamini-Hochberg-adjusted p-values below :math:`q`
        controls the false discovery rate at a level less than or equal to
        :math:`q m_0 / m`, where :math:`m_0` is the number of true null hypotheses
        and :math:`m` is the total number of null hypotheses tested. The same is
        true even for dependent tests when the p-values are adjusted accorded to
        the more conservative Benjaminini-Yekutieli procedure.

        The adjusted p-values produced by this function are comparable to those
        produced by the R function ``p.adjust`` and the statsmodels function
        `statsmodels.stats.multitest.multipletests`. Please consider the latter
        for more advanced methods of multiple comparison correction.

        References
        ----------
        .. [1] Benjamini, Yoav, and Yosef Hochberg. "Controlling the false
               discovery rate: a practical and powerful approach to multiple
               testing." Journal of the Royal statistical society: series B
               (Methodological) 57.1 (1995): 289-300.

        .. [2] Benjamini, Yoav, and Daniel Yekutieli. "The control of the false
               discovery rate in multiple testing under dependency." Annals of
               statistics (2001): 1165-1188.

        .. [3] TileStats. FDR - Benjamini-Hochberg explained - Youtube.
               https://www.youtube.com/watch?v=rZKa4tW2NKs.

        .. [4] Neuhaus, Karl-Ludwig, et al. "Improved thrombolysis in acute
               myocardial infarction with front-loaded administration of alteplase:
               results of the rt-PA-APSAC patency study (TAPS)." Journal of the
               American College of Cardiology 19.5 (1992): 885-891.

        Examples
        --------
        We follow the example from [1]_.

            Thrombolysis with recombinant tissue-type plasminogen activator (rt-PA)
            and anisoylated plasminogen streptokinase activator (APSAC) in
            myocardial infarction has been proved to reduce mortality. [4]_
            investigated the effects of a new front-loaded administration of rt-PA
            versus those obtained with a standard regimen of APSAC, in a randomized
            multicentre trial in 421 patients with acute myocardial infarction.

        There were four families of hypotheses tested in the study, the last of
        which was "cardiac and other events after the start of thrombolitic
        treatment". FDR control may be desired in this family of hypotheses
        because it would not be appropriate to conclude that the front-loaded
        treatment is better if it is merely equivalent to the previous treatment.

        The p-values corresponding with the 15 hypotheses in this family were

        >>> ps = [0.0001, 0.0004, 0.0019, 0.0095, 0.0201, 0.0278, 0.0298, 0.0344,
        ...       0.0459, 0.3240, 0.4262, 0.5719, 0.6528, 0.7590, 1.000]

        If the chosen significance level is 0.05, we may be tempted to reject the
        null hypotheses for the tests corresponding with the first nine p-values,
        as the first nine p-values fall below the chosen significance level.
        However, this would ignore the problem of "multiplicity": if we fail to
        correct for the fact that multiple comparisons are being performed, we
        are more likely to incorrectly reject true null hypotheses.

        One approach to the multiplicity problem is to control the family-wise
        error rate (FWER), that is, the rate at which the null hypothesis is
        rejected when it is actually true. A common procedure of this kind is the
        Bonferroni correction [1]_.  We begin by multiplying the p-values by the
        number of hypotheses tested.

        >>> import numpy as np
        >>> np.array(ps) * len(ps)
        array([1.5000e-03, 6.0000e-03, 2.8500e-02, 1.4250e-01, 3.0150e-01,
               4.1700e-01, 4.4700e-01, 5.1600e-01, 6.8850e-01, 4.8600e+00,
               6.3930e+00, 8.5785e+00, 9.7920e+00, 1.1385e+01, 1.5000e+01])

        To control the FWER at 5%, we reject only the hypotheses corresponding
        with adjusted p-values less than 0.05. In this case, only the hypotheses
        corresponding with the first three p-values can be rejected. According to
        [1]_, these three hypotheses concerned "allergic reaction" and "two
        different aspects of bleeding."

        An alternative approach is to control the false discovery rate: the
        expected fraction of rejected null hypotheses that are actually true. The
        advantage of this approach is that it typically affords greater power: an
        increased rate of rejecting the null hypothesis when it is indeed false. To
        control the false discovery rate at 5%, we apply the Benjamini-Hochberg
        p-value adjustment.

        >>> from scipy import stats
        >>> stats.false_discovery_control(ps)
        array([0.0015    , 0.003     , 0.0095    , 0.035625  , 0.0603    ,
               0.06385714, 0.06385714, 0.0645    , 0.0765    , 0.486     ,
               0.58118182, 0.714875  , 0.75323077, 0.81321429, 1.        ])

        Now, the first *four* adjusted p-values fall below 0.05, so we would reject
        the null hypotheses corresponding with these *four* p-values. Rejection
        of the fourth null hypothesis was particularly important to the original
        study as it led to the conclusion that the new treatment had a
        "substantially lower in-hospital mortality rate."

    find_repeats(arr)
        Find repeats and repeat counts.

        Parameters
        ----------
        arr : array_like
            Input array. This is cast to float64.

        Returns
        -------
        values : ndarray
            The unique values from the (flattened) input that are repeated.

        counts : ndarray
            Number of times the corresponding 'value' is repeated.

        Notes
        -----
        In numpy >= 1.9 `numpy.unique` provides similar functionality. The main
        difference is that `find_repeats` only returns repeated values.

        Examples
        --------
        >>> from scipy import stats
        >>> stats.find_repeats([2, 1, 2, 3, 2, 2, 5])
        RepeatedResults(values=array([2.]), counts=array([4]))

        >>> stats.find_repeats([[10, 20, 1, 2], [5, 5, 4, 4]])
        RepeatedResults(values=array([4.,  5.]), counts=array([2, 2]))

    fisher_exact(table, alternative='two-sided')
        Perform a Fisher exact test on a 2x2 contingency table.

        The null hypothesis is that the true odds ratio of the populations
        underlying the observations is one, and the observations were sampled
        from these populations under a condition: the marginals of the
        resulting table must equal those of the observed table. The statistic
        returned is the unconditional maximum likelihood estimate of the odds
        ratio, and the p-value is the probability under the null hypothesis of
        obtaining a table at least as extreme as the one that was actually
        observed. There are other possible choices of statistic and two-sided
        p-value definition associated with Fisher's exact test; please see the
        Notes for more information.

        Parameters
        ----------
        table : array_like of ints
            A 2x2 contingency table.  Elements must be non-negative integers.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the odds ratio of the underlying population is not one
            * 'less': the odds ratio of the underlying population is less than one
            * 'greater': the odds ratio of the underlying population is greater
              than one

            See the Notes for more details.

        Returns
        -------
        res : SignificanceResult
            An object containing attributes:

            statistic : float
                This is the prior odds ratio, not a posterior estimate.
            pvalue : float
                The probability under the null hypothesis of obtaining a
                table at least as extreme as the one that was actually observed.

        See Also
        --------
        chi2_contingency : Chi-square test of independence of variables in a
            contingency table.  This can be used as an alternative to
            `fisher_exact` when the numbers in the table are large.
        contingency.odds_ratio : Compute the odds ratio (sample or conditional
            MLE) for a 2x2 contingency table.
        barnard_exact : Barnard's exact test, which is a more powerful alternative
            than Fisher's exact test for 2x2 contingency tables.
        boschloo_exact : Boschloo's exact test, which is a more powerful
            alternative than Fisher's exact test for 2x2 contingency tables.

        Notes
        -----
        *Null hypothesis and p-values*

        The null hypothesis is that the true odds ratio of the populations
        underlying the observations is one, and the observations were sampled at
        random from these populations under a condition: the marginals of the
        resulting table must equal those of the observed table. Equivalently,
        the null hypothesis is that the input table is from the hypergeometric
        distribution with parameters (as used in `hypergeom`)
        ``M = a + b + c + d``, ``n = a + b`` and ``N = a + c``, where the
        input table is ``[[a, b], [c, d]]``.  This distribution has support
        ``max(0, N + n - M) <= x <= min(N, n)``, or, in terms of the values
        in the input table, ``min(0, a - d) <= x <= a + min(b, c)``.  ``x``
        can be interpreted as the upper-left element of a 2x2 table, so the
        tables in the distribution have form::

            [  x           n - x     ]
            [N - x    M - (n + N) + x]

        For example, if::

            table = [6  2]
                    [1  4]

        then the support is ``2 <= x <= 7``, and the tables in the distribution
        are::

            [2 6]   [3 5]   [4 4]   [5 3]   [6 2]  [7 1]
            [5 0]   [4 1]   [3 2]   [2 3]   [1 4]  [0 5]

        The probability of each table is given by the hypergeometric distribution
        ``hypergeom.pmf(x, M, n, N)``.  For this example, these are (rounded to
        three significant digits)::

            x       2      3      4      5       6        7
            p  0.0163  0.163  0.408  0.326  0.0816  0.00466

        These can be computed with::

            >>> import numpy as np
            >>> from scipy.stats import hypergeom
            >>> table = np.array([[6, 2], [1, 4]])
            >>> M = table.sum()
            >>> n = table[0].sum()
            >>> N = table[:, 0].sum()
            >>> start, end = hypergeom.support(M, n, N)
            >>> hypergeom.pmf(np.arange(start, end+1), M, n, N)
            array([0.01631702, 0.16317016, 0.40792541, 0.32634033, 0.08158508,
                   0.004662  ])

        The two-sided p-value is the probability that, under the null hypothesis,
        a random table would have a probability equal to or less than the
        probability of the input table.  For our example, the probability of
        the input table (where ``x = 6``) is 0.0816.  The x values where the
        probability does not exceed this are 2, 6 and 7, so the two-sided p-value
        is ``0.0163 + 0.0816 + 0.00466 ~= 0.10256``::

            >>> from scipy.stats import fisher_exact
            >>> res = fisher_exact(table, alternative='two-sided')
            >>> res.pvalue
            0.10256410256410257

        The one-sided p-value for ``alternative='greater'`` is the probability
        that a random table has ``x >= a``, which in our example is ``x >= 6``,
        or ``0.0816 + 0.00466 ~= 0.08626``::

            >>> res = fisher_exact(table, alternative='greater')
            >>> res.pvalue
            0.08624708624708627

        This is equivalent to computing the survival function of the
        distribution at ``x = 5`` (one less than ``x`` from the input table,
        because we want to include the probability of ``x = 6`` in the sum)::

            >>> hypergeom.sf(5, M, n, N)
            0.08624708624708627

        For ``alternative='less'``, the one-sided p-value is the probability
        that a random table has ``x <= a``, (i.e. ``x <= 6`` in our example),
        or ``0.0163 + 0.163 + 0.408 + 0.326 + 0.0816 ~= 0.9949``::

            >>> res = fisher_exact(table, alternative='less')
            >>> res.pvalue
            0.9953379953379957

        This is equivalent to computing the cumulative distribution function
        of the distribution at ``x = 6``:

            >>> hypergeom.cdf(6, M, n, N)
            0.9953379953379957

        *Odds ratio*

        The calculated odds ratio is different from the value computed by the
        R function ``fisher.test``.  This implementation returns the "sample"
        or "unconditional" maximum likelihood estimate, while ``fisher.test``
        in R uses the conditional maximum likelihood estimate.  To compute the
        conditional maximum likelihood estimate of the odds ratio, use
        `scipy.stats.contingency.odds_ratio`.

        References
        ----------
        .. [1] Fisher, Sir Ronald A, "The Design of Experiments:
               Mathematics of a Lady Tasting Tea." ISBN 978-0-486-41151-4, 1935.
        .. [2] "Fisher's exact test",
               https://en.wikipedia.org/wiki/Fisher's_exact_test
        .. [3] Emma V. Low et al. "Identifying the lowest effective dose of
               acetazolamide for the prophylaxis of acute mountain sickness:
               systematic review and meta-analysis."
               BMJ, 345, :doi:`10.1136/bmj.e6779`, 2012.

        Examples
        --------
        In [3]_, the effective dose of acetazolamide for the prophylaxis of acute
        mountain sickness was investigated. The study notably concluded:

            Acetazolamide 250 mg, 500 mg, and 750 mg daily were all efficacious for
            preventing acute mountain sickness. Acetazolamide 250 mg was the lowest
            effective dose with available evidence for this indication.

        The following table summarizes the results of the experiment in which
        some participants took a daily dose of acetazolamide 250 mg while others
        took a placebo.
        Cases of acute mountain sickness were recorded::

                                        Acetazolamide   Control/Placebo
            Acute mountain sickness            7           17
            No                                15            5


        Is there evidence that the acetazolamide 250 mg reduces the risk of
        acute mountain sickness?
        We begin by formulating a null hypothesis :math:`H_0`:

            The odds of experiencing acute mountain sickness are the same with
            the acetazolamide treatment as they are with placebo.

        Let's assess the plausibility of this hypothesis with
        Fisher's test.

        >>> from scipy.stats import fisher_exact
        >>> res = fisher_exact([[7, 17], [15, 5]], alternative='less')
        >>> res.statistic
        0.13725490196078433
        >>> res.pvalue
        0.0028841933752349743

        Using a significance level of 5%, we would reject the null hypothesis in
        favor of the alternative hypothesis: "The odds of experiencing acute
        mountain sickness with acetazolamide treatment are less than the odds of
        experiencing acute mountain sickness with placebo."

        .. note::

            Because the null distribution of Fisher's exact test is formed under
            the assumption that both row and column sums are fixed, the result of
            the test are conservative when applied to an experiment in which the
            row sums are not fixed.

            In this case, the column sums are fixed; there are 22 subjects in each
            group. But the number of cases of acute mountain sickness is not
            (and cannot be) fixed before conducting the experiment. It is a
            consequence.

            Boschloo's test does not depend on the assumption that the row sums
            are fixed, and consequently, it provides a more powerful test in this
            situation.

            >>> from scipy.stats import boschloo_exact
            >>> res = boschloo_exact([[7, 17], [15, 5]], alternative='less')
            >>> res.statistic
            0.0028841933752349743
            >>> res.pvalue
            0.0015141406667567101

            We verify that the p-value is less than with `fisher_exact`.

    fit(dist, data, bounds=None, *, guess=None, method='mle', optimizer=<function differential_evolution at 0x000001D8F19F1EE0>)
        Fit a discrete or continuous distribution to data

        Given a distribution, data, and bounds on the parameters of the
        distribution, return maximum likelihood estimates of the parameters.

        Parameters
        ----------
        dist : `scipy.stats.rv_continuous` or `scipy.stats.rv_discrete`
            The object representing the distribution to be fit to the data.
        data : 1D array_like
            The data to which the distribution is to be fit. If the data contain
            any of ``np.nan``, ``np.inf``, or -``np.inf``, the fit method will
            raise a ``ValueError``.
        bounds : dict or sequence of tuples, optional
            If a dictionary, each key is the name of a parameter of the
            distribution, and the corresponding value is a tuple containing the
            lower and upper bound on that parameter.  If the distribution is
            defined only for a finite range of values of that parameter, no entry
            for that parameter is required; e.g., some distributions have
            parameters which must be on the interval [0, 1]. Bounds for parameters
            location (``loc``) and scale (``scale``) are optional; by default,
            they are fixed to 0 and 1, respectively.

            If a sequence, element *i* is a tuple containing the lower and upper
            bound on the *i*\ th parameter of the distribution. In this case,
            bounds for *all* distribution shape parameters must be provided.
            Optionally, bounds for location and scale may follow the
            distribution shape parameters.

            If a shape is to be held fixed (e.g. if it is known), the
            lower and upper bounds may be equal. If a user-provided lower or upper
            bound is beyond a bound of the domain for which the distribution is
            defined, the bound of the distribution's domain will replace the
            user-provided value. Similarly, parameters which must be integral
            will be constrained to integral values within the user-provided bounds.
        guess : dict or array_like, optional
            If a dictionary, each key is the name of a parameter of the
            distribution, and the corresponding value is a guess for the value
            of the parameter.

            If a sequence, element *i* is a guess for the *i*\ th parameter of the
            distribution. In this case, guesses for *all* distribution shape
            parameters must be provided.

            If `guess` is not provided, guesses for the decision variables will
            not be passed to the optimizer. If `guess` is provided, guesses for
            any missing parameters will be set at the mean of the lower and
            upper bounds. Guesses for parameters which must be integral will be
            rounded to integral values, and guesses that lie outside the
            intersection of the user-provided bounds and the domain of the
            distribution will be clipped.
        method : {'mle', 'mse'}
            With ``method="mle"`` (default), the fit is computed by minimizing
            the negative log-likelihood function. A large, finite penalty
            (rather than infinite negative log-likelihood) is applied for
            observations beyond the support of the distribution.
            With ``method="mse"``, the fit is computed by minimizing
            the negative log-product spacing function. The same penalty is applied
            for observations beyond the support. We follow the approach of [1]_,
            which is generalized for samples with repeated observations.
        optimizer : callable, optional
            `optimizer` is a callable that accepts the following positional
            argument.

            fun : callable
                The objective function to be optimized. `fun` accepts one argument
                ``x``, candidate shape parameters of the distribution, and returns
                the objective function value given ``x``, `dist`, and the provided
                `data`.
                The job of `optimizer` is to find values of the decision variables
                that minimizes `fun`.

            `optimizer` must also accept the following keyword argument.

            bounds : sequence of tuples
                The bounds on values of the decision variables; each element will
                be a tuple containing the lower and upper bound on a decision
                variable.

            If `guess` is provided, `optimizer` must also accept the following
            keyword argument.

            x0 : array_like
                The guesses for each decision variable.

            If the distribution has any shape parameters that must be integral or
            if the distribution is discrete and the location parameter is not
            fixed, `optimizer` must also accept the following keyword argument.

            integrality : array_like of bools
                For each decision variable, True if the decision variable
                must be constrained to integer values and False if the decision
                variable is continuous.

            `optimizer` must return an object, such as an instance of
            `scipy.optimize.OptimizeResult`, which holds the optimal values of
            the decision variables in an attribute ``x``. If attributes
            ``fun``, ``status``, or ``message`` are provided, they will be
            included in the result object returned by `fit`.

        Returns
        -------
        result : `~scipy.stats._result_classes.FitResult`
            An object with the following fields.

            params : namedtuple
                A namedtuple containing the maximum likelihood estimates of the
                shape parameters, location, and (if applicable) scale of the
                distribution.
            success : bool or None
                Whether the optimizer considered the optimization to terminate
                successfully or not.
            message : str or None
                Any status message provided by the optimizer.

            The object has the following method:

            nllf(params=None, data=None)
                By default, the negative log-likehood function at the fitted
                `params` for the given `data`. Accepts a tuple containing
                alternative shapes, location, and scale of the distribution and
                an array of alternative data.

            plot(ax=None)
                Superposes the PDF/PMF of the fitted distribution over a normalized
                histogram of the data.

        See Also
        --------
        rv_continuous,  rv_discrete

        Notes
        -----
        Optimization is more likely to converge to the maximum likelihood estimate
        when the user provides tight bounds containing the maximum likelihood
        estimate. For example, when fitting a binomial distribution to data, the
        number of experiments underlying each sample may be known, in which case
        the corresponding shape parameter ``n`` can be fixed.

        References
        ----------
        .. [1] Shao, Yongzhao, and Marjorie G. Hahn. "Maximum product of spacings
               method: a unified formulation with illustration of strong
               consistency." Illinois Journal of Mathematics 43.3 (1999): 489-499.

        Examples
        --------
        Suppose we wish to fit a distribution to the following data.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> dist = stats.nbinom
        >>> shapes = (5, 0.5)
        >>> data = dist.rvs(*shapes, size=1000, random_state=rng)

        Suppose we do not know how the data were generated, but we suspect that
        it follows a negative binomial distribution with parameters *n* and *p*\.
        (See `scipy.stats.nbinom`.) We believe that the parameter *n* was fewer
        than 30, and we know that the parameter *p* must lie on the interval
        [0, 1]. We record this information in a variable `bounds` and pass
        this information to `fit`.

        >>> bounds = [(0, 30), (0, 1)]
        >>> res = stats.fit(dist, data, bounds)

        `fit` searches within the user-specified `bounds` for the
        values that best match the data (in the sense of maximum likelihood
        estimation). In this case, it found shape values similar to those
        from which the data were actually generated.

        >>> res.params
        FitParams(n=5.0, p=0.5028157644634368, loc=0.0)  # may vary

        We can visualize the results by superposing the probability mass function
        of the distribution (with the shapes fit to the data) over a normalized
        histogram of the data.

        >>> import matplotlib.pyplot as plt  # matplotlib must be installed to plot
        >>> res.plot()
        >>> plt.show()

        Note that the estimate for *n* was exactly integral; this is because
        the domain of the `nbinom` PMF includes only integral *n*, and the `nbinom`
        object "knows" that. `nbinom` also knows that the shape *p* must be a
        value between 0 and 1. In such a case - when the domain of the distribution
        with respect to a parameter is finite - we are not required to specify
        bounds for the parameter.

        >>> bounds = {'n': (0, 30)}  # omit parameter p using a `dict`
        >>> res2 = stats.fit(dist, data, bounds)
        >>> res2.params
        FitParams(n=5.0, p=0.5016492009232932, loc=0.0)  # may vary

        If we wish to force the distribution to be fit with *n* fixed at 6, we can
        set both the lower and upper bounds on *n* to 6. Note, however, that the
        value of the objective function being optimized is typically worse (higher)
        in this case.

        >>> bounds = {'n': (6, 6)}  # fix parameter `n`
        >>> res3 = stats.fit(dist, data, bounds)
        >>> res3.params
        FitParams(n=6.0, p=0.5486556076755706, loc=0.0)  # may vary
        >>> res3.nllf() > res.nllf()
        True  # may vary

        Note that the numerical results of the previous examples are typical, but
        they may vary because the default optimizer used by `fit`,
        `scipy.optimize.differential_evolution`, is stochastic. However, we can
        customize the settings used by the optimizer to ensure reproducibility -
        or even use a different optimizer entirely - using the `optimizer`
        parameter.

        >>> from scipy.optimize import differential_evolution
        >>> rng = np.random.default_rng(767585560716548)
        >>> def optimizer(fun, bounds, *, integrality):
        ...     return differential_evolution(fun, bounds, strategy='best2bin',
        ...                                   seed=rng, integrality=integrality)
        >>> bounds = [(0, 30), (0, 1)]
        >>> res4 = stats.fit(dist, data, bounds, optimizer=optimizer)
        >>> res4.params
        FitParams(n=5.0, p=0.5015183149259951, loc=0.0)

    fligner(*samples, center='median', proportiontocut=0.05, axis=0, nan_policy='propagate', keepdims=False)
        Perform Fligner-Killeen test for equality of variance.

        Fligner's test tests the null hypothesis that all input samples
        are from populations with equal variances.  Fligner-Killeen's test is
        distribution free when populations are identical [2]_.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            Arrays of sample data.  Need not be the same length.
        center : {'mean', 'median', 'trimmed'}, optional
            Keyword argument controlling which function of the data is used in
            computing the test statistic.  The default is 'median'.
        proportiontocut : float, optional
            When `center` is 'trimmed', this gives the proportion of data points
            to cut from each end. (See `scipy.stats.trim_mean`.)
            Default is 0.05.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic.
        pvalue : float
            The p-value for the hypothesis test.

        See Also
        --------

        :func:`bartlett`
            A parametric test for equality of k variances in normal samples
        :func:`levene`
            A robust parametric test for equality of k variances


        Notes
        -----
        As with Levene's test there are three variants of Fligner's test that
        differ by the measure of central tendency used in the test.  See `levene`
        for more information.

        Conover et al. (1981) examine many of the existing parametric and
        nonparametric tests by extensive simulations and they conclude that the
        tests proposed by Fligner and Killeen (1976) and Levene (1960) appear to be
        superior in terms of robustness of departures from normality and power
        [3]_.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Park, C. and Lindsay, B. G. (1999). Robust Scale Estimation and
               Hypothesis Testing based on Quadratic Inference Function. Technical
               Report #99-03, Center for Likelihood Studies, Pennsylvania State
               University.
               https://cecas.clemson.edu/~cspark/cv/paper/qif/draftqif2.pdf
        .. [2] Fligner, M.A. and Killeen, T.J. (1976). Distribution-free two-sample
               tests for scale. 'Journal of the American Statistical Association.'
               71(353), 210-213.
        .. [3] Park, C. and Lindsay, B. G. (1999). Robust Scale Estimation and
               Hypothesis Testing based on Quadratic Inference Function. Technical
               Report #99-03, Center for Likelihood Studies, Pennsylvania State
               University.
        .. [4] Conover, W. J., Johnson, M. E. and Johnson M. M. (1981). A
               comparative study of tests for homogeneity of variances, with
               applications to the outer continental shelf bidding data.
               Technometrics, 23(4), 351-361.
        .. [5] C.I. BLISS (1952), The Statistics of Bioassay: With Special
               Reference to the Vitamins, pp 499-503,
               :doi:`10.1016/C2013-0-12584-6`.
        .. [6] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [7] Ludbrook, J., & Dudley, H. (1998). Why permutation tests are
               superior to t and F tests in biomedical research. The American
               Statistician, 52(2), 127-132.

        Examples
        --------
        In [5]_, the influence of vitamin C on the tooth growth of guinea pigs
        was investigated. In a control study, 60 subjects were divided into
        small dose, medium dose, and large dose groups that received
        daily doses of 0.5, 1.0 and 2.0 mg of vitamin C, respectively.
        After 42 days, the tooth growth was measured.

        The ``small_dose``, ``medium_dose``, and ``large_dose`` arrays below record
        tooth growth measurements of the three groups in microns.

        >>> import numpy as np
        >>> small_dose = np.array([
        ...     4.2, 11.5, 7.3, 5.8, 6.4, 10, 11.2, 11.2, 5.2, 7,
        ...     15.2, 21.5, 17.6, 9.7, 14.5, 10, 8.2, 9.4, 16.5, 9.7
        ... ])
        >>> medium_dose = np.array([
        ...     16.5, 16.5, 15.2, 17.3, 22.5, 17.3, 13.6, 14.5, 18.8, 15.5,
        ...     19.7, 23.3, 23.6, 26.4, 20, 25.2, 25.8, 21.2, 14.5, 27.3
        ... ])
        >>> large_dose = np.array([
        ...     23.6, 18.5, 33.9, 25.5, 26.4, 32.5, 26.7, 21.5, 23.3, 29.5,
        ...     25.5, 26.4, 22.4, 24.5, 24.8, 30.9, 26.4, 27.3, 29.4, 23
        ... ])

        The `fligner` statistic is sensitive to differences in variances
        between the samples.

        >>> from scipy import stats
        >>> res = stats.fligner(small_dose, medium_dose, large_dose)
        >>> res.statistic
        1.3878943408857916

        The value of the statistic tends to be high when there is a large
        difference in variances.

        We can test for inequality of variance among the groups by comparing the
        observed value of the statistic against the null distribution: the
        distribution of statistic values derived under the null hypothesis that
        the population variances of the three groups are equal.

        For this test, the null distribution follows the chi-square distribution
        as shown below.

        >>> import matplotlib.pyplot as plt
        >>> k = 3  # number of samples
        >>> dist = stats.chi2(df=k-1)
        >>> val = np.linspace(0, 8, 100)
        >>> pdf = dist.pdf(val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(val, pdf, color='C0')
        ...     ax.set_title("Fligner Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        ...     ax.set_xlim(0, 8)
        ...     ax.set_ylim(0, 0.5)
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution greater than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.4f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (1.5, 0.22), (2.25, 0.3), arrowprops=props)
        >>> i = val >= res.statistic
        >>> ax.fill_between(val[i], y1=0, y2=pdf[i], color='C0')
        >>> plt.show()

        >>> res.pvalue
        0.49960016501182125

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from distributions with identical variances that produces
        such an extreme value of the statistic - this may be taken as evidence
        against the null hypothesis in favor of the alternative: the variances of
        the groups are not equal. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [6]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).
        - Small p-values are not evidence for a *large* effect; rather, they can
          only provide evidence for a "significant" effect, meaning that they are
          unlikely to have occurred under the null hypothesis.

        Note that the chi-square distribution provides an asymptotic approximation
        of the null distribution.
        For small samples, it may be more appropriate to perform a
        permutation test: Under the null hypothesis that all three samples were
        drawn from the same population, each of the measurements is equally likely
        to have been observed in any of the three samples. Therefore, we can form
        a randomized null distribution by calculating the statistic under many
        randomly-generated partitionings of the observations into the three
        samples.

        >>> def statistic(*samples):
        ...     return stats.fligner(*samples).statistic
        >>> ref = stats.permutation_test(
        ...     (small_dose, medium_dose, large_dose), statistic,
        ...     permutation_type='independent', alternative='greater'
        ... )
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> bins = np.linspace(0, 8, 25)
        >>> ax.hist(
        ...     ref.null_distribution, bins=bins, density=True, facecolor="C1"
        ... )
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'randomized null distribution'])
        >>> plot(ax)
        >>> plt.show()

        >>> ref.pvalue  # randomized test p-value
        0.4332  # may vary

        Note that there is significant disagreement between the p-value calculated
        here and the asymptotic approximation returned by `fligner` above.
        The statistical inferences that can be drawn rigorously from a permutation
        test are limited; nonetheless, they may be the preferred approach in many
        circumstances [7]_.

        Following is another generic example where the null hypothesis would be
        rejected.

        Test whether the lists `a`, `b` and `c` come from populations
        with equal variances.

        >>> a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
        >>> b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
        >>> c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
        >>> stat, p = stats.fligner(a, b, c)
        >>> p
        0.00450826080004775

        The small p-value suggests that the populations do not have equal
        variances.

        This is not surprising, given that the sample variance of `b` is much
        larger than that of `a` and `c`:

        >>> [np.var(x, ddof=1) for x in [a, b, c]]
        [0.007054444444444413, 0.13073888888888888, 0.008890000000000002]

    friedmanchisquare(*samples, axis=0, nan_policy='propagate', keepdims=False)
        Compute the Friedman test for repeated samples.

        The Friedman test tests the null hypothesis that repeated samples of
        the same individuals have the same distribution.  It is often used
        to test for consistency among samples obtained in different ways.
        For example, if two sampling techniques are used on the same set of
        individuals, the Friedman test can be used to determine if the two
        sampling techniques are consistent.

        Parameters
        ----------
        sample1, sample2, sample3... : array_like
            Arrays of observations.  All of the arrays must have the same number
            of elements.  At least three samples must be given.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic, correcting for ties.
        pvalue : float
            The associated p-value assuming that the test statistic has a chi
            squared distribution.

        Notes
        -----
        Due to the assumption that the test statistic has a chi squared
        distribution, the p-value is only reliable for n > 10 and more than
        6 repeated samples.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Friedman_test
        .. [2] P. Sprent and N.C. Smeeton, "Applied Nonparametric Statistical
               Methods, Third Edition". Chapter 6, Section 6.3.2.

        Examples
        --------
        In [2]_, the pulse rate (per minute) of a group of seven students was
        measured before exercise, immediately after exercise and 5 minutes
        after exercise. Is there evidence to suggest that the pulse rates on
        these three occasions are similar?

        We begin by formulating a null hypothesis :math:`H_0`:

            The pulse rates are identical on these three occasions.

        Let's assess the plausibility of this hypothesis with a Friedman test.

        >>> from scipy.stats import friedmanchisquare
        >>> before = [72, 96, 88, 92, 74, 76, 82]
        >>> immediately_after = [120, 120, 132, 120, 101, 96, 112]
        >>> five_min_after = [76, 95, 104, 96, 84, 72, 76]
        >>> res = friedmanchisquare(before, immediately_after, five_min_after)
        >>> res.statistic
        10.57142857142857
        >>> res.pvalue
        0.005063414171757498

        Using a significance level of 5%, we would reject the null hypothesis in
        favor of the alternative hypothesis: "the pulse rates are different on
        these three occasions".

    gmean(a, axis=0, dtype=None, weights=None, *, nan_policy='propagate', keepdims=False)
        Compute the weighted geometric mean along the specified axis.

        The weighted geometric mean of the array :math:`a_i` associated to weights
        :math:`w_i` is:

        .. math::

            \exp \left( \frac{ \sum_{i=1}^n w_i \ln a_i }{ \sum_{i=1}^n w_i }
                       \right) \, ,

        and, with equal weights, it gives:

        .. math::

            \sqrt[n]{ \prod_{i=1}^n a_i } \, .

        Parameters
        ----------
        a : array_like
            Input array or object that can be converted to an array.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        dtype : dtype, optional
            Type to which the input arrays are cast before the calculation is
            performed.
        weights : array_like, optional
            The `weights` array must be broadcastable to the same shape as `a`.
            Default is None, which gives each value a weight of 1.0.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        gmean : ndarray
            See `dtype` parameter above.

        See Also
        --------

        :func:`numpy.mean`
            Arithmetic average
        :func:`numpy.average`
            Weighted average
        :func:`hmean`
            Harmonic mean


        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] "Weighted Geometric Mean", *Wikipedia*,
               https://en.wikipedia.org/wiki/Weighted_geometric_mean.
        .. [2] Grossman, J., Grossman, M., Katz, R., "Averages: A New Approach",
               Archimedes Foundation, 1983

        Examples
        --------
        >>> from scipy.stats import gmean
        >>> gmean([1, 4])
        2.0
        >>> gmean([1, 2, 3, 4, 5, 6, 7])
        3.3800151591412964
        >>> gmean([1, 4, 7], weights=[3, 1, 3])
        2.80668351922014

    goodness_of_fit(dist, data, *, known_params=None, fit_params=None, guessed_params=None, statistic='ad', n_mc_samples=9999, random_state=None)
        Perform a goodness of fit test comparing data to a distribution family.

        Given a distribution family and data, perform a test of the null hypothesis
        that the data were drawn from a distribution in that family. Any known
        parameters of the distribution may be specified. Remaining parameters of
        the distribution will be fit to the data, and the p-value of the test
        is computed accordingly. Several statistics for comparing the distribution
        to data are available.

        Parameters
        ----------
        dist : `scipy.stats.rv_continuous`
            The object representing the distribution family under the null
            hypothesis.
        data : 1D array_like
            Finite, uncensored data to be tested.
        known_params : dict, optional
            A dictionary containing name-value pairs of known distribution
            parameters. Monte Carlo samples are randomly drawn from the
            null-hypothesized distribution with these values of the parameters.
            Before the statistic is evaluated for each Monte Carlo sample, only
            remaining unknown parameters of the null-hypothesized distribution
            family are fit to the samples; the known parameters are held fixed.
            If all parameters of the distribution family are known, then the step
            of fitting the distribution family to each sample is omitted.
        fit_params : dict, optional
            A dictionary containing name-value pairs of distribution parameters
            that have already been fit to the data, e.g. using `scipy.stats.fit`
            or the ``fit`` method of `dist`. Monte Carlo samples are drawn from the
            null-hypothesized distribution with these specified values of the
            parameter. On those Monte Carlo samples, however, these and all other
            unknown parameters of the null-hypothesized distribution family are
            fit before the statistic is evaluated.
        guessed_params : dict, optional
            A dictionary containing name-value pairs of distribution parameters
            which have been guessed. These parameters are always considered as
            free parameters and are fit both to the provided `data` as well as
            to the Monte Carlo samples drawn from the null-hypothesized
            distribution. The purpose of these `guessed_params` is to be used as
            initial values for the numerical fitting procedure.
        statistic : {"ad", "ks", "cvm", "filliben"} or callable, optional
            The statistic used to compare data to a distribution after fitting
            unknown parameters of the distribution family to the data. The
            Anderson-Darling ("ad") [1]_, Kolmogorov-Smirnov ("ks") [1]_,
            Cramer-von Mises ("cvm") [1]_, and Filliben ("filliben") [7]_
            statistics are available.  Alternatively, a callable with signature
            ``(dist, data, axis)`` may be supplied to compute the statistic. Here
            ``dist`` is a frozen distribution object (potentially with array
            parameters), ``data`` is an array of Monte Carlo samples (of
            compatible shape), and ``axis`` is the axis of ``data`` along which
            the statistic must be computed.
        n_mc_samples : int, default: 9999
            The number of Monte Carlo samples drawn from the null hypothesized
            distribution to form the null distribution of the statistic. The
            sample size of each is the same as the given `data`.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            Pseudorandom number generator state used to generate the Monte Carlo
            samples.

            If `random_state` is ``None`` (default), the
            `numpy.random.RandomState` singleton is used.
            If `random_state` is an int, a new ``RandomState`` instance is used,
            seeded with `random_state`.
            If `random_state` is already a ``Generator`` or ``RandomState``
            instance, then the provided instance is used.

        Returns
        -------
        res : GoodnessOfFitResult
            An object with the following attributes.

            fit_result : `~scipy.stats._result_classes.FitResult`
                An object representing the fit of the provided `dist` to `data`.
                This  object includes the values of distribution family parameters
                that fully define the null-hypothesized distribution, that is,
                the distribution from which Monte Carlo samples are drawn.
            statistic : float
                The value of the statistic comparing provided `data` to the
                null-hypothesized distribution.
            pvalue : float
                The proportion of elements in the null distribution with
                statistic values at least as extreme as the statistic value of the
                provided `data`.
            null_distribution : ndarray
                The value of the statistic for each Monte Carlo sample
                drawn from the null-hypothesized distribution.

        Notes
        -----
        This is a generalized Monte Carlo goodness-of-fit procedure, special cases
        of which correspond with various Anderson-Darling tests, Lilliefors' test,
        etc. The test is described in [2]_, [3]_, and [4]_ as a parametric
        bootstrap test. This is a Monte Carlo test in which parameters that
        specify the distribution from which samples are drawn have been estimated
        from the data. We describe the test using "Monte Carlo" rather than
        "parametric bootstrap" throughout to avoid confusion with the more familiar
        nonparametric bootstrap, and describe how the test is performed below.

        *Traditional goodness of fit tests*

        Traditionally, critical values corresponding with a fixed set of
        significance levels are pre-calculated using Monte Carlo methods. Users
        perform the test by calculating the value of the test statistic only for
        their observed `data` and comparing this value to tabulated critical
        values. This practice is not very flexible, as tables are not available for
        all distributions and combinations of known and unknown parameter values.
        Also, results can be inaccurate when critical values are interpolated from
        limited tabulated data to correspond with the user's sample size and
        fitted parameter values. To overcome these shortcomings, this function
        allows the user to perform the Monte Carlo trials adapted to their
        particular data.

        *Algorithmic overview*

        In brief, this routine executes the following steps:

          1. Fit unknown parameters to the given `data`, thereby forming the
             "null-hypothesized" distribution, and compute the statistic of
             this pair of data and distribution.
          2. Draw random samples from this null-hypothesized distribution.
          3. Fit the unknown parameters to each random sample.
          4. Calculate the statistic between each sample and the distribution that
             has been fit to the sample.
          5. Compare the value of the statistic corresponding with `data` from (1)
             against the values of the statistic corresponding with the random
             samples from (4). The p-value is the proportion of samples with a
             statistic value greater than or equal to the statistic of the observed
             data.

        In more detail, the steps are as follows.

        First, any unknown parameters of the distribution family specified by
        `dist` are fit to the provided `data` using maximum likelihood estimation.
        (One exception is the normal distribution with unknown location and scale:
        we use the bias-corrected standard deviation ``np.std(data, ddof=1)`` for
        the scale as recommended in [1]_.)
        These values of the parameters specify a particular member of the
        distribution family referred to as the "null-hypothesized distribution",
        that is, the distribution from which the data were sampled under the null
        hypothesis. The `statistic`, which compares data to a distribution, is
        computed between `data` and the null-hypothesized distribution.

        Next, many (specifically `n_mc_samples`) new samples, each containing the
        same number of observations as `data`, are drawn from the
        null-hypothesized distribution. All unknown parameters of the distribution
        family `dist` are fit to *each resample*, and the `statistic` is computed
        between each sample and its corresponding fitted distribution. These
        values of the statistic form the Monte Carlo null distribution (not to be
        confused with the "null-hypothesized distribution" above).

        The p-value of the test is the proportion of statistic values in the Monte
        Carlo null distribution that are at least as extreme as the statistic value
        of the provided `data`. More precisely, the p-value is given by

        .. math::

            p = \frac{b + 1}
                     {m + 1}

        where :math:`b` is the number of statistic values in the Monte Carlo null
        distribution that are greater than or equal to the statistic value
        calculated for `data`, and :math:`m` is the number of elements in the
        Monte Carlo null distribution (`n_mc_samples`). The addition of :math:`1`
        to the numerator and denominator can be thought of as including the
        value of the statistic corresponding with `data` in the null distribution,
        but a more formal explanation is given in [5]_.

        *Limitations*

        The test can be very slow for some distribution families because unknown
        parameters of the distribution family must be fit to each of the Monte
        Carlo samples, and for most distributions in SciPy, distribution fitting
        performed via numerical optimization.

        *Anti-Pattern*

        For this reason, it may be tempting
        to treat parameters of the distribution pre-fit to `data` (by the user)
        as though they were `known_params`, as specification of all parameters of
        the distribution precludes the need to fit the distribution to each Monte
        Carlo sample. (This is essentially how the original Kilmogorov-Smirnov
        test is performed.) Although such a test can provide evidence against the
        null hypothesis, the test is conservative in the sense that small p-values
        will tend to (greatly) *overestimate* the probability of making a type I
        error (that is, rejecting the null hypothesis although it is true), and the
        power of the test is low (that is, it is less likely to reject the null
        hypothesis even when the null hypothesis is false).
        This is because the Monte Carlo samples are less likely to agree with the
        null-hypothesized distribution as well as `data`. This tends to increase
        the values of the statistic recorded in the null distribution, so that a
        larger number of them exceed the value of statistic for `data`, thereby
        inflating the p-value.

        References
        ----------
        .. [1] M. A. Stephens (1974). "EDF Statistics for Goodness of Fit and
               Some Comparisons." Journal of the American Statistical Association,
               Vol. 69, pp. 730-737.
        .. [2] W. Stute, W. G. Manteiga, and M. P. Quindimil (1993).
               "Bootstrap based goodness-of-fit-tests." Metrika 40.1: 243-256.
        .. [3] C. Genest, & B Rémillard. (2008). "Validity of the parametric
               bootstrap for goodness-of-fit testing in semiparametric models."
               Annales de l'IHP Probabilités et statistiques. Vol. 44. No. 6.
        .. [4] I. Kojadinovic and J. Yan (2012). "Goodness-of-fit testing based on
               a weighted bootstrap: A fast large-sample alternative to the
               parametric bootstrap." Canadian Journal of Statistics 40.3: 480-500.
        .. [5] B. Phipson and G. K. Smyth (2010). "Permutation P-values Should
               Never Be Zero: Calculating Exact P-values When Permutations Are
               Randomly Drawn." Statistical Applications in Genetics and Molecular
               Biology 9.1.
        .. [6] H. W. Lilliefors (1967). "On the Kolmogorov-Smirnov test for
               normality with mean and variance unknown." Journal of the American
               statistical Association 62.318: 399-402.
        .. [7] Filliben, James J. "The probability plot correlation coefficient
               test for normality." Technometrics 17.1 (1975): 111-117.

        Examples
        --------
        A well-known test of the null hypothesis that data were drawn from a
        given distribution is the Kolmogorov-Smirnov (KS) test, available in SciPy
        as `scipy.stats.ks_1samp`. Suppose we wish to test whether the following
        data:

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> x = stats.uniform.rvs(size=75, random_state=rng)

        were sampled from a normal distribution. To perform a KS test, the
        empirical distribution function of the observed data will be compared
        against the (theoretical) cumulative distribution function of a normal
        distribution. Of course, to do this, the normal distribution under the null
        hypothesis must be fully specified. This is commonly done by first fitting
        the ``loc`` and ``scale`` parameters of the distribution to the observed
        data, then performing the test.

        >>> loc, scale = np.mean(x), np.std(x, ddof=1)
        >>> cdf = stats.norm(loc, scale).cdf
        >>> stats.ks_1samp(x, cdf)
        KstestResult(statistic=0.1119257570456813,
                     pvalue=0.2827756409939257,
                     statistic_location=0.7751845155861765,
                     statistic_sign=-1)

        An advantage of the KS-test is that the p-value - the probability of
        obtaining a value of the test statistic under the null hypothesis as
        extreme as the value obtained from the observed data - can be calculated
        exactly and efficiently. `goodness_of_fit` can only approximate these
        results.

        >>> known_params = {'loc': loc, 'scale': scale}
        >>> res = stats.goodness_of_fit(stats.norm, x, known_params=known_params,
        ...                             statistic='ks', random_state=rng)
        >>> res.statistic, res.pvalue
        (0.1119257570456813, 0.2788)

        The statistic matches exactly, but the p-value is estimated by forming
        a "Monte Carlo null distribution", that is, by explicitly drawing random
        samples from `scipy.stats.norm` with the provided parameters and
        calculating the stastic for each. The fraction of these statistic values
        at least as extreme as ``res.statistic`` approximates the exact p-value
        calculated by `scipy.stats.ks_1samp`.

        However, in many cases, we would prefer to test only that the data were
        sampled from one of *any* member of the normal distribution family, not
        specifically from the normal distribution with the location and scale
        fitted to the observed sample. In this case, Lilliefors [6]_ argued that
        the KS test is far too conservative (that is, the p-value overstates
        the actual probability of rejecting a true null hypothesis) and thus lacks
        power - the ability to reject the null hypothesis when the null hypothesis
        is actually false.
        Indeed, our p-value above is approximately 0.28, which is far too large
        to reject the null hypothesis at any common significance level.

        Consider why this might be. Note that in the KS test above, the statistic
        always compares data against the CDF of a normal distribution fitted to the
        *observed data*. This tends to reduce the value of the statistic for the
        observed data, but it is "unfair" when computing the statistic for other
        samples, such as those we randomly draw to form the Monte Carlo null
        distribution. It is easy to correct for this: whenever we compute the KS
        statistic of a sample, we use the CDF of a normal distribution fitted
        to *that sample*. The null distribution in this case has not been
        calculated exactly and is tyically approximated using Monte Carlo methods
        as described above. This is where `goodness_of_fit` excels.

        >>> res = stats.goodness_of_fit(stats.norm, x, statistic='ks',
        ...                             random_state=rng)
        >>> res.statistic, res.pvalue
        (0.1119257570456813, 0.0196)

        Indeed, this p-value is much smaller, and small enough to (correctly)
        reject the null hypothesis at common significance levels, including 5% and
        2.5%.

        However, the KS statistic is not very sensitive to all deviations from
        normality. The original advantage of the KS statistic was the ability
        to compute the null distribution theoretically, but a more sensitive
        statistic - resulting in a higher test power - can be used now that we can
        approximate the null distribution
        computationally. The Anderson-Darling statistic [1]_ tends to be more
        sensitive, and critical values of the this statistic have been tabulated
        for various significance levels and sample sizes using Monte Carlo methods.

        >>> res = stats.anderson(x, 'norm')
        >>> print(res.statistic)
        1.2139573337497467
        >>> print(res.critical_values)
        [0.549 0.625 0.75  0.875 1.041]
        >>> print(res.significance_level)
        [15.  10.   5.   2.5  1. ]

        Here, the observed value of the statistic exceeds the critical value
        corresponding with a 1% significance level. This tells us that the p-value
        of the observed data is less than 1%, but what is it? We could interpolate
        from these (already-interpolated) values, but `goodness_of_fit` can
        estimate it directly.

        >>> res = stats.goodness_of_fit(stats.norm, x, statistic='ad',
        ...                             random_state=rng)
        >>> res.statistic, res.pvalue
        (1.2139573337497467, 0.0034)

        A further advantage is that use of `goodness_of_fit` is not limited to
        a particular set of distributions or conditions on which parameters
        are known versus which must be estimated from data. Instead,
        `goodness_of_fit` can estimate p-values relatively quickly for any
        distribution with a sufficiently fast and reliable ``fit`` method. For
        instance, here we perform a goodness of fit test using the Cramer-von Mises
        statistic against the Rayleigh distribution with known location and unknown
        scale.

        >>> rng = np.random.default_rng()
        >>> x = stats.chi(df=2.2, loc=0, scale=2).rvs(size=1000, random_state=rng)
        >>> res = stats.goodness_of_fit(stats.rayleigh, x, statistic='cvm',
        ...                             known_params={'loc': 0}, random_state=rng)

        This executes fairly quickly, but to check the reliability of the ``fit``
        method, we should inspect the fit result.

        >>> res.fit_result  # location is as specified, and scale is reasonable
          params: FitParams(loc=0.0, scale=2.1026719844231243)
         success: True
         message: 'The fit was performed successfully.'
        >>> import matplotlib.pyplot as plt  # matplotlib must be installed to plot
        >>> res.fit_result.plot()
        >>> plt.show()

        If the distribution is not fit to the observed data as well as possible,
        the test may not control the type I error rate, that is, the chance of
        rejecting the null hypothesis even when it is true.

        We should also look for extreme outliers in the null distribution that
        may be caused by unreliable fitting. These do not necessarily invalidate
        the result, but they tend to reduce the test's power.

        >>> _, ax = plt.subplots()
        >>> ax.hist(np.log10(res.null_distribution))
        >>> ax.set_xlabel("log10 of CVM statistic under the null hypothesis")
        >>> ax.set_ylabel("Frequency")
        >>> ax.set_title("Histogram of the Monte Carlo null distribution")
        >>> plt.show()

        This plot seems reassuring.

        If ``fit`` method is working reliably, and if the distribution of the test
        statistic is not particularly sensitive to the values of the fitted
        parameters, then the p-value provided by `goodness_of_fit` is expected to
        be a good approximation.

        >>> res.statistic, res.pvalue
        (0.2231991510248692, 0.0525)

    gstd(a, axis=0, ddof=1)
        Calculate the geometric standard deviation of an array.

        The geometric standard deviation describes the spread of a set of numbers
        where the geometric mean is preferred. It is a multiplicative factor, and
        so a dimensionless quantity.

        It is defined as the exponential of the standard deviation of the
        natural logarithms of the observations.

        Parameters
        ----------
        a : array_like
            An array containing finite, strictly positive, real numbers.

            .. deprecated:: 1.14.0
                Support for masked array input was deprecated in
                SciPy 1.14.0 and will be removed in version 1.16.0.

        axis : int, tuple or None, optional
            Axis along which to operate. Default is 0. If None, compute over
            the whole array `a`.
        ddof : int, optional
            Degree of freedom correction in the calculation of the
            geometric standard deviation. Default is 1.

        Returns
        -------
        gstd : ndarray or float
            An array of the geometric standard deviation. If `axis` is None or `a`
            is a 1d array a float is returned.

        See Also
        --------
        gmean : Geometric mean
        numpy.std : Standard deviation
        gzscore : Geometric standard score

        Notes
        -----
        Mathematically, the sample geometric standard deviation :math:`s_G` can be
        defined in terms of the natural logarithms of the observations
        :math:`y_i = \log(x_i)`:

        .. math::

            s_G = \exp(s), \quad s = \sqrt{\frac{1}{n - d} \sum_{i=1}^n (y_i - \bar y)^2}

        where :math:`n` is the number of observations, :math:`d` is the adjustment `ddof`
        to the degrees of freedom, and :math:`\bar y` denotes the mean of the natural
        logarithms of the observations. Note that the default ``ddof=1`` is different from
        the default value used by similar functions, such as `numpy.std` and `numpy.var`.

        When an observation is infinite, the geometric standard deviation is
        NaN (undefined). Non-positive observations will also produce NaNs in the
        output because the *natural* logarithm (as opposed to the *complex*
        logarithm) is defined and finite only for positive reals.
        The geometric standard deviation is sometimes confused with the exponential
        of the standard deviation, ``exp(std(a))``. Instead, the geometric standard
        deviation is ``exp(std(log(a)))``.

        References
        ----------
        .. [1] "Geometric standard deviation", *Wikipedia*,
               https://en.wikipedia.org/wiki/Geometric_standard_deviation.
        .. [2] Kirkwood, T. B., "Geometric means and measures of dispersion",
               Biometrics, vol. 35, pp. 908-909, 1979

        Examples
        --------
        Find the geometric standard deviation of a log-normally distributed sample.
        Note that the standard deviation of the distribution is one; on a
        log scale this evaluates to approximately ``exp(1)``.

        >>> import numpy as np
        >>> from scipy.stats import gstd
        >>> rng = np.random.default_rng()
        >>> sample = rng.lognormal(mean=0, sigma=1, size=1000)
        >>> gstd(sample)
        2.810010162475324

        Compute the geometric standard deviation of a multidimensional array and
        of a given axis.

        >>> a = np.arange(1, 25).reshape(2, 3, 4)
        >>> gstd(a, axis=None)
        2.2944076136018947
        >>> gstd(a, axis=2)
        array([[1.82424757, 1.22436866, 1.13183117],
               [1.09348306, 1.07244798, 1.05914985]])
        >>> gstd(a, axis=(1,2))
        array([2.12939215, 1.22120169])

    gzscore(a, *, axis=0, ddof=0, nan_policy='propagate')
        Compute the geometric standard score.

        Compute the geometric z score of each strictly positive value in the
        sample, relative to the geometric mean and standard deviation.
        Mathematically the geometric z score can be evaluated as::

            gzscore = log(a/gmu) / log(gsigma)

        where ``gmu`` (resp. ``gsigma``) is the geometric mean (resp. standard
        deviation).

        Parameters
        ----------
        a : array_like
            Sample data.
        axis : int or None, optional
            Axis along which to operate. Default is 0. If None, compute over
            the whole array `a`.
        ddof : int, optional
            Degrees of freedom correction in the calculation of the
            standard deviation. Default is 0.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan. 'propagate' returns nan,
            'raise' throws an error, 'omit' performs the calculations ignoring nan
            values. Default is 'propagate'.  Note that when the value is 'omit',
            nans in the input also propagate to the output, but they do not affect
            the geometric z scores computed for the non-nan values.

        Returns
        -------
        gzscore : array_like
            The geometric z scores, standardized by geometric mean and geometric
            standard deviation of input array `a`.

        See Also
        --------
        gmean : Geometric mean
        gstd : Geometric standard deviation
        zscore : Standard score

        Notes
        -----
        This function preserves ndarray subclasses, and works also with
        matrices and masked arrays (it uses ``asanyarray`` instead of
        ``asarray`` for parameters).

        .. versionadded:: 1.8

        References
        ----------
        .. [1] "Geometric standard score", *Wikipedia*,
               https://en.wikipedia.org/wiki/Geometric_standard_deviation#Geometric_standard_score.

        Examples
        --------
        Draw samples from a log-normal distribution:

        >>> import numpy as np
        >>> from scipy.stats import zscore, gzscore
        >>> import matplotlib.pyplot as plt

        >>> rng = np.random.default_rng()
        >>> mu, sigma = 3., 1.  # mean and standard deviation
        >>> x = rng.lognormal(mu, sigma, size=500)

        Display the histogram of the samples:

        >>> fig, ax = plt.subplots()
        >>> ax.hist(x, 50)
        >>> plt.show()

        Display the histogram of the samples standardized by the classical zscore.
        Distribution is rescaled but its shape is unchanged.

        >>> fig, ax = plt.subplots()
        >>> ax.hist(zscore(x), 50)
        >>> plt.show()

        Demonstrate that the distribution of geometric zscores is rescaled and
        quasinormal:

        >>> fig, ax = plt.subplots()
        >>> ax.hist(gzscore(x), 50)
        >>> plt.show()

    hmean(a, axis=0, dtype=None, *, weights=None, nan_policy='propagate', keepdims=False)
        Calculate the weighted harmonic mean along the specified axis.

        The weighted harmonic mean of the array :math:`a_i` associated to weights
        :math:`w_i` is:

        .. math::

            \frac{ \sum_{i=1}^n w_i }{ \sum_{i=1}^n \frac{w_i}{a_i} } \, ,

        and, with equal weights, it gives:

        .. math::

            \frac{ n }{ \sum_{i=1}^n \frac{1}{a_i} } \, .

        Parameters
        ----------
        a : array_like
            Input array, masked array or object that can be converted to an array.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        dtype : dtype, optional
            Type of the returned array and of the accumulator in which the
            elements are summed. If `dtype` is not specified, it defaults to the
            dtype of `a`, unless `a` has an integer `dtype` with a precision less
            than that of the default platform integer. In that case, the default
            platform integer is used.
        weights : array_like, optional
            The weights array can either be 1-D (in which case its length must be
            the size of `a` along the given `axis`) or of the same shape as `a`.
            Default is None, which gives each value a weight of 1.0.

            .. versionadded:: 1.9
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        hmean : ndarray
            See `dtype` parameter above.

        See Also
        --------

        :func:`numpy.mean`
            Arithmetic average
        :func:`numpy.average`
            Weighted average
        :func:`gmean`
            Geometric mean


        Notes
        -----
        The harmonic mean is computed over a single dimension of the input
        array, axis=0 by default, or all values in the array if axis=None.
        float64 intermediate and return values are used for integer inputs.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] "Weighted Harmonic Mean", *Wikipedia*,
               https://en.wikipedia.org/wiki/Harmonic_mean#Weighted_harmonic_mean
        .. [2] Ferger, F., "The nature and use of the harmonic mean", Journal of
               the American Statistical Association, vol. 26, pp. 36-40, 1931

        Examples
        --------
        >>> from scipy.stats import hmean
        >>> hmean([1, 4])
        1.6000000000000001
        >>> hmean([1, 2, 3, 4, 5, 6, 7])
        2.6997245179063363
        >>> hmean([1, 4, 7], weights=[3, 1, 3])
        1.9029126213592233

    iqr(x, axis=None, rng=(25, 75), scale=1.0, nan_policy='propagate', interpolation='linear', keepdims=False)
        Compute the interquartile range of the data along the specified axis.

        The interquartile range (IQR) is the difference between the 75th and
        25th percentile of the data. It is a measure of the dispersion
        similar to standard deviation or variance, but is much more robust
        against outliers [2]_.

        The ``rng`` parameter allows this function to compute other
        percentile ranges than the actual IQR. For example, setting
        ``rng=(0, 100)`` is equivalent to `numpy.ptp`.

        The IQR of an empty array is `np.nan`.

        .. versionadded:: 0.18.0

        Parameters
        ----------
        x : array_like
            Input array or object that can be converted to an array.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        rng : Two-element sequence containing floats in range of [0,100] optional
            Percentiles over which to compute the range. Each must be
            between 0 and 100, inclusive. The default is the true IQR:
            ``(25, 75)``. The order of the elements is not important.
        scale : scalar or str or array_like of reals, optional
            The numerical value of scale will be divided out of the final
            result. The following string value is also recognized:

              * 'normal' : Scale by
                :math:`2 \sqrt{2} erf^{-1}(\frac{1}{2}) \approx 1.349`.

            The default is 1.0.
            Array-like `scale` of real dtype is also allowed, as long
            as it broadcasts correctly to the output such that
            ``out / scale`` is a valid operation. The output dimensions
            depend on the input array, `x`, the `axis` argument, and the
            `keepdims` flag.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        interpolation : str, optional
            Specifies the interpolation method to use when the percentile
            boundaries lie between two data points ``i`` and ``j``.
            The following options are available (default is 'linear'):

              * 'linear': ``i + (j - i)*fraction``, where ``fraction`` is the
                fractional part of the index surrounded by ``i`` and ``j``.
              * 'lower': ``i``.
              * 'higher': ``j``.
              * 'nearest': ``i`` or ``j`` whichever is nearest.
              * 'midpoint': ``(i + j)/2``.

            For NumPy >= 1.22.0, the additional options provided by the ``method``
            keyword of `numpy.percentile` are also valid.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        iqr : scalar or ndarray
            If ``axis=None``, a scalar is returned. If the input contains
            integers or floats of smaller precision than ``np.float64``, then the
            output data-type is ``np.float64``. Otherwise, the output data-type is
            the same as that of the input.

        See Also
        --------

        :func:`numpy.std`, :func:`numpy.var`
            ..

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] "Interquartile range" https://en.wikipedia.org/wiki/Interquartile_range
        .. [2] "Robust measures of scale" https://en.wikipedia.org/wiki/Robust_measures_of_scale
        .. [3] "Quantile" https://en.wikipedia.org/wiki/Quantile

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import iqr
        >>> x = np.array([[10, 7, 4], [3, 2, 1]])
        >>> x
        array([[10,  7,  4],
               [ 3,  2,  1]])
        >>> iqr(x)
        4.0
        >>> iqr(x, axis=0)
        array([ 3.5,  2.5,  1.5])
        >>> iqr(x, axis=1)
        array([ 3.,  1.])
        >>> iqr(x, axis=1, keepdims=True)
        array([[ 3.],
               [ 1.]])

    jarque_bera(x, *, axis=None, nan_policy='propagate', keepdims=False)
        Perform the Jarque-Bera goodness of fit test on sample data.

        The Jarque-Bera test tests whether the sample data has the skewness and
        kurtosis matching a normal distribution.

        Note that this test only works for a large enough number of data samples
        (>2000) as the test statistic asymptotically has a Chi-squared distribution
        with 2 degrees of freedom.

        Parameters
        ----------
        x : array_like
            Observations of a random variable.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        result : SignificanceResult
            An object with the following attributes:

            statistic : float
                The test statistic.
            pvalue : float
                The p-value for the hypothesis test.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Jarque, C. and Bera, A. (1980) "Efficient tests for normality,
               homoscedasticity and serial independence of regression residuals",
               6 Econometric Letters 255-259.
        .. [2] Shapiro, S. S., & Wilk, M. B. (1965). An analysis of variance test
               for normality (complete samples). Biometrika, 52(3/4), 591-611.
        .. [3] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [4] Panagiotakos, D. B. (2008). The value of p-value in biomedical
               research. The open cardiovascular medicine journal, 2, 97.

        Examples
        --------
        Suppose we wish to infer from measurements whether the weights of adult
        human males in a medical study are not normally distributed [2]_.
        The weights (lbs) are recorded in the array ``x`` below.

        >>> import numpy as np
        >>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

        The Jarque-Bera test begins by computing a statistic based on the sample
        skewness and kurtosis.

        >>> from scipy import stats
        >>> res = stats.jarque_bera(x)
        >>> res.statistic
        6.982848237344646

        Because the normal distribution has zero skewness and zero
        ("excess" or "Fisher") kurtosis, the value of this statistic tends to be
        low for samples drawn from a normal distribution.

        The test is performed by comparing the observed value of the statistic
        against the null distribution: the distribution of statistic values derived
        under the null hypothesis that the weights were drawn from a normal
        distribution.
        For the Jarque-Bera test, the null distribution for very large samples is
        the chi-squared distribution with two degrees of freedom.

        >>> import matplotlib.pyplot as plt
        >>> dist = stats.chi2(df=2)
        >>> jb_val = np.linspace(0, 11, 100)
        >>> pdf = dist.pdf(jb_val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def jb_plot(ax):  # we'll reuse this
        ...     ax.plot(jb_val, pdf)
        ...     ax.set_title("Jarque-Bera Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> jb_plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution greater than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> jb_plot(ax)
        >>> pvalue = dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (7.5, 0.01), (8, 0.05), arrowprops=props)
        >>> i = jb_val >= res.statistic  # indices of more extreme statistic values
        >>> ax.fill_between(jb_val[i], y1=0, y2=pdf[i])
        >>> ax.set_xlim(0, 11)
        >>> ax.set_ylim(0, 0.3)
        >>> plt.show()
        >>> res.pvalue
        0.03045746622458189

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from a normally distributed population that produces such an
        extreme value of the statistic - this may be taken as evidence against
        the null hypothesis in favor of the alternative: the weights were not
        drawn from a normal distribution. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [3]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).

        Note that the chi-squared distribution provides an asymptotic approximation
        of the null distribution; it is only accurate for samples with many
        observations. For small samples like ours, `scipy.stats.monte_carlo_test`
        may provide a more accurate, albeit stochastic, approximation of the
        exact p-value.

        >>> def statistic(x, axis):
        ...     # underlying calculation of the Jarque Bera statistic
        ...     s = stats.skew(x, axis=axis)
        ...     k = stats.kurtosis(x, axis=axis)
        ...     return x.shape[axis]/6 * (s**2 + k**2/4)
        >>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
        ...                              alternative='greater')
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> jb_plot(ax)
        >>> ax.hist(res.null_distribution, np.linspace(0, 10, 50),
        ...         density=True)
        >>> ax.legend(['aymptotic approximation (many observations)',
        ...            'Monte Carlo approximation (11 observations)'])
        >>> plt.show()
        >>> res.pvalue
        0.0097  # may vary

        Furthermore, despite their stochastic nature, p-values computed in this way
        can be used to exactly control the rate of false rejections of the null
        hypothesis [4]_.

    kendalltau(x, y, *, nan_policy='propagate', method='auto', variant='b', alternative='two-sided')
        Calculate Kendall's tau, a correlation measure for ordinal data.

        Kendall's tau is a measure of the correspondence between two rankings.
        Values close to 1 indicate strong agreement, and values close to -1
        indicate strong disagreement. This implements two variants of Kendall's
        tau: tau-b (the default) and tau-c (also known as Stuart's tau-c). These
        differ only in how they are normalized to lie within the range -1 to 1;
        the hypothesis tests (their p-values) are identical. Kendall's original
        tau-a is not implemented separately because both tau-b and tau-c reduce
        to tau-a in the absence of ties.

        Parameters
        ----------
        x, y : array_like
            Arrays of rankings, of the same shape. If arrays are not 1-D, they
            will be flattened to 1-D.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is 'propagate'):

              * 'propagate': returns nan
              * 'raise': throws an error
              * 'omit': performs the calculations ignoring nan values

        method : {'auto', 'asymptotic', 'exact'}, optional
            Defines which method is used to calculate the p-value [5]_.
            The following options are available (default is 'auto'):

              * 'auto': selects the appropriate method based on a trade-off
                between speed and accuracy
              * 'asymptotic': uses a normal approximation valid for large samples
              * 'exact': computes the exact p-value, but can only be used if no ties
                are present. As the sample size increases, the 'exact' computation
                time may grow and the result may lose some precision.
        variant : {'b', 'c'}, optional
            Defines which variant of Kendall's tau is returned. Default is 'b'.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the rank correlation is nonzero
            * 'less': the rank correlation is negative (less than zero)
            * 'greater':  the rank correlation is positive (greater than zero)

        Returns
        -------
        res : SignificanceResult
            An object containing attributes:

            statistic : float
               The tau statistic.
            pvalue : float
               The p-value for a hypothesis test whose null hypothesis is
               an absence of association, tau = 0.

        See Also
        --------
        spearmanr : Calculates a Spearman rank-order correlation coefficient.
        theilslopes : Computes the Theil-Sen estimator for a set of points (x, y).
        weightedtau : Computes a weighted version of Kendall's tau.

        Notes
        -----
        The definition of Kendall's tau that is used is [2]_::

          tau_b = (P - Q) / sqrt((P + Q + T) * (P + Q + U))

          tau_c = 2 (P - Q) / (n**2 * (m - 1) / m)

        where P is the number of concordant pairs, Q the number of discordant
        pairs, T the number of ties only in `x`, and U the number of ties only in
        `y`.  If a tie occurs for the same pair in both `x` and `y`, it is not
        added to either T or U. n is the total number of samples, and m is the
        number of unique values in either `x` or `y`, whichever is smaller.

        References
        ----------
        .. [1] Maurice G. Kendall, "A New Measure of Rank Correlation", Biometrika
               Vol. 30, No. 1/2, pp. 81-93, 1938.
        .. [2] Maurice G. Kendall, "The treatment of ties in ranking problems",
               Biometrika Vol. 33, No. 3, pp. 239-251. 1945.
        .. [3] Gottfried E. Noether, "Elements of Nonparametric Statistics", John
               Wiley & Sons, 1967.
        .. [4] Peter M. Fenwick, "A new data structure for cumulative frequency
               tables", Software: Practice and Experience, Vol. 24, No. 3,
               pp. 327-336, 1994.
        .. [5] Maurice G. Kendall, "Rank Correlation Methods" (4th Edition),
               Charles Griffin & Co., 1970.
        .. [6] Kershenobich, D., Fierro, F. J., & Rojkind, M. (1970). The
               relationship between the free pool of proline and collagen content
               in human liver cirrhosis. The Journal of Clinical Investigation,
               49(12), 2246-2249.
        .. [7] Hollander, M., Wolfe, D. A., & Chicken, E. (2013). Nonparametric
               statistical methods. John Wiley & Sons.
        .. [8] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).

        Examples
        --------
        Consider the following data from [6]_, which studied the relationship
        between free proline (an amino acid) and total collagen (a protein often
        found in connective tissue) in unhealthy human livers.

        The ``x`` and ``y`` arrays below record measurements of the two compounds.
        The observations are paired: each free proline measurement was taken from
        the same liver as the total collagen measurement at the same index.

        >>> import numpy as np
        >>> # total collagen (mg/g dry weight of liver)
        >>> x = np.array([7.1, 7.1, 7.2, 8.3, 9.4, 10.5, 11.4])
        >>> # free proline (μ mole/g dry weight of liver)
        >>> y = np.array([2.8, 2.9, 2.8, 2.6, 3.5, 4.6, 5.0])

        These data were analyzed in [7]_ using Spearman's correlation coefficient,
        a statistic similar to Kendall's tau in that it is also sensitive to
        ordinal correlation between the samples. Let's perform an analogous study
        using Kendall's tau.

        >>> from scipy import stats
        >>> res = stats.kendalltau(x, y)
        >>> res.statistic
        0.5499999999999999

        The value of this statistic tends to be high (close to 1) for samples with
        a strongly positive ordinal correlation, low (close to -1) for samples with
        a strongly negative ordinal correlation, and small in magnitude (close to
        zero) for samples with weak ordinal correlation.

        The test is performed by comparing the observed value of the
        statistic against the null distribution: the distribution of statistic
        values derived under the null hypothesis that total collagen and free
        proline measurements are independent.

        For this test, the null distribution for large samples without ties is
        approximated as the normal distribution with variance
        ``(2*(2*n + 5))/(9*n*(n - 1))``, where ``n = len(x)``.

        >>> import matplotlib.pyplot as plt
        >>> n = len(x)  # len(x) == len(y)
        >>> var = (2*(2*n + 5))/(9*n*(n - 1))
        >>> dist = stats.norm(scale=np.sqrt(var))
        >>> z_vals = np.linspace(-1.25, 1.25, 100)
        >>> pdf = dist.pdf(z_vals)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(z_vals, pdf)
        ...     ax.set_title("Kendall Tau Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution as extreme or more extreme than the observed
        value of the statistic. In a two-sided test in which the statistic is
        positive, elements of the null distribution greater than the transformed
        statistic and elements of the null distribution less than the negative of
        the observed statistic are both considered "more extreme".

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.cdf(-res.statistic) + dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.4f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (0.65, 0.15), (0.8, 0.3), arrowprops=props)
        >>> i = z_vals >= res.statistic
        >>> ax.fill_between(z_vals[i], y1=0, y2=pdf[i], color='C0')
        >>> i = z_vals <= -res.statistic
        >>> ax.fill_between(z_vals[i], y1=0, y2=pdf[i], color='C0')
        >>> ax.set_xlim(-1.25, 1.25)
        >>> ax.set_ylim(0, 0.5)
        >>> plt.show()
        >>> res.pvalue
        0.09108705741631495  # approximate p-value

        Note that there is slight disagreement between the shaded area of the curve
        and the p-value returned by `kendalltau`. This is because our data has
        ties, and we have neglected a tie correction to the null distribution
        variance that `kendalltau` performs. For samples without ties, the shaded
        areas of our plot and p-value returned by `kendalltau` would match exactly.

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from independent distributions that produces such an extreme
        value of the statistic - this may be taken as evidence against the null
        hypothesis in favor of the alternative: the distribution of total collagen
        and free proline are *not* independent. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [8]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).
        - Small p-values are not evidence for a *large* effect; rather, they can
          only provide evidence for a "significant" effect, meaning that they are
          unlikely to have occurred under the null hypothesis.

        For samples without ties of moderate size, `kendalltau` can compute the
        p-value exactly. However, in the presence of ties, `kendalltau` resorts
        to an asymptotic approximation. Nonetheles, we can use a permutation test
        to compute the null distribution exactly: Under the null hypothesis that
        total collagen and free proline are independent, each of the free proline
        measurements were equally likely to have been observed with any of the
        total collagen measurements. Therefore, we can form an *exact* null
        distribution by calculating the statistic under each possible pairing of
        elements between ``x`` and ``y``.

        >>> def statistic(x):  # explore all possible pairings by permuting `x`
        ...     return stats.kendalltau(x, y).statistic  # ignore pvalue
        >>> ref = stats.permutation_test((x,), statistic,
        ...                              permutation_type='pairings')
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> bins = np.linspace(-1.25, 1.25, 25)
        >>> ax.hist(ref.null_distribution, bins=bins, density=True)
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'exact null distribution'])
        >>> plot(ax)
        >>> plt.show()
        >>> ref.pvalue
        0.12222222222222222  # exact p-value

        Note that there is significant disagreement between the exact p-value
        calculated here and the approximation returned by `kendalltau` above. For
        small samples with ties, consider performing a permutation test for more
        accurate results.

    kruskal(*samples, nan_policy='propagate', axis=0, keepdims=False)
        Compute the Kruskal-Wallis H-test for independent samples.

        The Kruskal-Wallis H-test tests the null hypothesis that the population
        median of all of the groups are equal.  It is a non-parametric version of
        ANOVA.  The test works on 2 or more independent samples, which may have
        different sizes.  Note that rejecting the null hypothesis does not
        indicate which of the groups differs.  Post hoc comparisons between
        groups are required to determine which groups are different.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            Two or more arrays with the sample measurements can be given as
            arguments. Samples must be one-dimensional.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The Kruskal-Wallis H statistic, corrected for ties.
        pvalue : float
            The p-value for the test using the assumption that H has a chi
            square distribution. The p-value returned is the survival function of
            the chi square distribution evaluated at H.

        See Also
        --------

        :func:`f_oneway`
            1-way ANOVA.
        :func:`mannwhitneyu`
            Mann-Whitney rank test on two samples.
        :func:`friedmanchisquare`
            Friedman test for repeated measurements.


        Notes
        -----
        Due to the assumption that H has a chi square distribution, the number
        of samples in each group must not be too small.  A typical rule is
        that each sample must have at least 5 measurements.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] W. H. Kruskal & W. W. Wallis, "Use of Ranks in
           One-Criterion Variance Analysis", Journal of the American Statistical
           Association, Vol. 47, Issue 260, pp. 583-621, 1952.
        .. [2] https://en.wikipedia.org/wiki/Kruskal-Wallis_one-way_analysis_of_variance

        Examples
        --------
        >>> from scipy import stats
        >>> x = [1, 3, 5, 7, 9]
        >>> y = [2, 4, 6, 8, 10]
        >>> stats.kruskal(x, y)
        KruskalResult(statistic=0.2727272727272734, pvalue=0.6015081344405895)

        >>> x = [1, 1, 1]
        >>> y = [2, 2, 2]
        >>> z = [2, 2]
        >>> stats.kruskal(x, y, z)
        KruskalResult(statistic=7.0, pvalue=0.0301973834223185)

    ks_1samp(x, cdf, args=(), alternative='two-sided', method='auto', *, axis=0, nan_policy='propagate', keepdims=False)
        Performs the one-sample Kolmogorov-Smirnov test for goodness of fit.

        This test compares the underlying distribution F(x) of a sample
        against a given continuous distribution G(x). See Notes for a description
        of the available null and alternative hypotheses.

        Parameters
        ----------
        x : array_like
            a 1-D array of observations of iid random variables.
        cdf : callable
            callable used to calculate the cdf.
        args : tuple, sequence, optional
            Distribution parameters, used with `cdf`.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the null and alternative hypotheses. Default is 'two-sided'.
            Please see explanations in the Notes below.
        method : {'auto', 'exact', 'approx', 'asymp'}, optional
            Defines the distribution used for calculating the p-value.
            The following options are available (default is 'auto'):

              * 'auto' : selects one of the other options.
              * 'exact' : uses the exact distribution of test statistic.
              * 'approx' : approximates the two-sided probability with twice
                the one-sided probability
              * 'asymp': uses asymptotic distribution of test statistic
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res: KstestResult
            An object containing attributes:

            statistic : float
                KS test statistic, either D+, D-, or D (the maximum of the two)
            pvalue : float
                One-tailed or two-tailed p-value.
            statistic_location : float
                Value of `x` corresponding with the KS statistic; i.e., the
                distance between the empirical distribution function and the
                hypothesized cumulative distribution function is measured at this
                observation.
            statistic_sign : int
                +1 if the KS statistic is the maximum positive difference between
                the empirical distribution function and the hypothesized cumulative
                distribution function (D+); -1 if the KS statistic is the maximum
                negative difference (D-).

        See Also
        --------

        :func:`ks_2samp`, :func:`kstest`
            ..

        Notes
        -----
        There are three options for the null and corresponding alternative
        hypothesis that can be selected using the `alternative` parameter.

        - `two-sided`: The null hypothesis is that the two distributions are
          identical, F(x)=G(x) for all x; the alternative is that they are not
          identical.

        - `less`: The null hypothesis is that F(x) >= G(x) for all x; the
          alternative is that F(x) < G(x) for at least one x.

        - `greater`: The null hypothesis is that F(x) <= G(x) for all x; the
          alternative is that F(x) > G(x) for at least one x.

        Note that the alternative hypotheses describe the *CDFs* of the
        underlying distributions, not the observed values. For example,
        suppose x1 ~ F and x2 ~ G. If F(x) > G(x) for all x, the values in
        x1 tend to be less than those in x2.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        Suppose we wish to test the null hypothesis that a sample is distributed
        according to the standard normal.
        We choose a confidence level of 95%; that is, we will reject the null
        hypothesis in favor of the alternative if the p-value is less than 0.05.

        When testing uniformly distributed data, we would expect the
        null hypothesis to be rejected.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> stats.ks_1samp(stats.uniform.rvs(size=100, random_state=rng),
        ...                stats.norm.cdf)
        KstestResult(statistic=0.5001899973268688,
                     pvalue=1.1616392184763533e-23,
                     statistic_location=0.00047625268963724654,
                     statistic_sign=-1)

        Indeed, the p-value is lower than our threshold of 0.05, so we reject the
        null hypothesis in favor of the default "two-sided" alternative: the data
        are *not* distributed according to the standard normal.

        When testing random variates from the standard normal distribution, we
        expect the data to be consistent with the null hypothesis most of the time.

        >>> x = stats.norm.rvs(size=100, random_state=rng)
        >>> stats.ks_1samp(x, stats.norm.cdf)
        KstestResult(statistic=0.05345882212970396,
                     pvalue=0.9227159037744717,
                     statistic_location=-1.2451343873745018,
                     statistic_sign=1)

        As expected, the p-value of 0.92 is not below our threshold of 0.05, so
        we cannot reject the null hypothesis.

        Suppose, however, that the random variates are distributed according to
        a normal distribution that is shifted toward greater values. In this case,
        the cumulative density function (CDF) of the underlying distribution tends
        to be *less* than the CDF of the standard normal. Therefore, we would
        expect the null hypothesis to be rejected with ``alternative='less'``:

        >>> x = stats.norm.rvs(size=100, loc=0.5, random_state=rng)
        >>> stats.ks_1samp(x, stats.norm.cdf, alternative='less')
        KstestResult(statistic=0.17482387821055168,
                     pvalue=0.001913921057766743,
                     statistic_location=0.3713830565352756,
                     statistic_sign=-1)

        and indeed, with p-value smaller than our threshold, we reject the null
        hypothesis in favor of the alternative.

    ks_2samp(data1, data2, alternative='two-sided', method='auto', *, axis=0, nan_policy='propagate', keepdims=False)
        Performs the two-sample Kolmogorov-Smirnov test for goodness of fit.

        This test compares the underlying continuous distributions F(x) and G(x)
        of two independent samples.  See Notes for a description of the available
        null and alternative hypotheses.

        Parameters
        ----------
        data1, data2 : array_like, 1-Dimensional
            Two arrays of sample observations assumed to be drawn from a continuous
            distribution, sample sizes can be different.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the null and alternative hypotheses. Default is 'two-sided'.
            Please see explanations in the Notes below.
        method : {'auto', 'exact', 'asymp'}, optional
            Defines the method used for calculating the p-value.
            The following options are available (default is 'auto'):

              * 'auto' : use 'exact' for small size arrays, 'asymp' for large
              * 'exact' : use exact distribution of test statistic
              * 'asymp' : use asymptotic distribution of test statistic
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res: KstestResult
            An object containing attributes:

            statistic : float
                KS test statistic.
            pvalue : float
                One-tailed or two-tailed p-value.
            statistic_location : float
                Value from `data1` or `data2` corresponding with the KS statistic;
                i.e., the distance between the empirical distribution functions is
                measured at this observation.
            statistic_sign : int
                +1 if the empirical distribution function of `data1` exceeds
                the empirical distribution function of `data2` at
                `statistic_location`, otherwise -1.

        See Also
        --------

        :func:`kstest`, :func:`ks_1samp`, :func:`epps_singleton_2samp`, :func:`anderson_ksamp`
            ..

        Notes
        -----
        There are three options for the null and corresponding alternative
        hypothesis that can be selected using the `alternative` parameter.

        - `less`: The null hypothesis is that F(x) >= G(x) for all x; the
          alternative is that F(x) < G(x) for at least one x. The statistic
          is the magnitude of the minimum (most negative) difference between the
          empirical distribution functions of the samples.

        - `greater`: The null hypothesis is that F(x) <= G(x) for all x; the
          alternative is that F(x) > G(x) for at least one x. The statistic
          is the maximum (most positive) difference between the empirical
          distribution functions of the samples.

        - `two-sided`: The null hypothesis is that the two distributions are
          identical, F(x)=G(x) for all x; the alternative is that they are not
          identical. The statistic is the maximum absolute difference between the
          empirical distribution functions of the samples.

        Note that the alternative hypotheses describe the *CDFs* of the
        underlying distributions, not the observed values of the data. For example,
        suppose x1 ~ F and x2 ~ G. If F(x) > G(x) for all x, the values in
        x1 tend to be less than those in x2.

        If the KS statistic is large, then the p-value will be small, and this may
        be taken as evidence against the null hypothesis in favor of the
        alternative.

        If ``method='exact'``, `ks_2samp` attempts to compute an exact p-value,
        that is, the probability under the null hypothesis of obtaining a test
        statistic value as extreme as the value computed from the data.
        If ``method='asymp'``, the asymptotic Kolmogorov-Smirnov distribution is
        used to compute an approximate p-value.
        If ``method='auto'``, an exact p-value computation is attempted if both
        sample sizes are less than 10000; otherwise, the asymptotic method is used.
        In any case, if an exact p-value calculation is attempted and fails, a
        warning will be emitted, and the asymptotic p-value will be returned.

        The 'two-sided' 'exact' computation computes the complementary probability
        and then subtracts from 1.  As such, the minimum probability it can return
        is about 1e-16.  While the algorithm itself is exact, numerical
        errors may accumulate for large sample sizes.   It is most suited to
        situations in which one of the sample sizes is only a few thousand.

        We generally follow Hodges' treatment of Drion/Gnedenko/Korolyuk [1]_.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Hodges, J.L. Jr.,  "The Significance Probability of the Smirnov
               Two-Sample Test," Arkiv fiur Matematik, 3, No. 43 (1958), 469-486.

        Examples
        --------
        Suppose we wish to test the null hypothesis that two samples were drawn
        from the same distribution.
        We choose a confidence level of 95%; that is, we will reject the null
        hypothesis in favor of the alternative if the p-value is less than 0.05.

        If the first sample were drawn from a uniform distribution and the second
        were drawn from the standard normal, we would expect the null hypothesis
        to be rejected.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> sample1 = stats.uniform.rvs(size=100, random_state=rng)
        >>> sample2 = stats.norm.rvs(size=110, random_state=rng)
        >>> stats.ks_2samp(sample1, sample2)
        KstestResult(statistic=0.5454545454545454,
                     pvalue=7.37417839555191e-15,
                     statistic_location=-0.014071496412861274,
                     statistic_sign=-1)

        Indeed, the p-value is lower than our threshold of 0.05, so we reject the
        null hypothesis in favor of the default "two-sided" alternative: the data
        were *not* drawn from the same distribution.

        When both samples are drawn from the same distribution, we expect the data
        to be consistent with the null hypothesis most of the time.

        >>> sample1 = stats.norm.rvs(size=105, random_state=rng)
        >>> sample2 = stats.norm.rvs(size=95, random_state=rng)
        >>> stats.ks_2samp(sample1, sample2)
        KstestResult(statistic=0.10927318295739348,
                     pvalue=0.5438289009927495,
                     statistic_location=-0.1670157701848795,
                     statistic_sign=-1)

        As expected, the p-value of 0.54 is not below our threshold of 0.05, so
        we cannot reject the null hypothesis.

        Suppose, however, that the first sample were drawn from
        a normal distribution shifted toward greater values. In this case,
        the cumulative density function (CDF) of the underlying distribution tends
        to be *less* than the CDF underlying the second sample. Therefore, we would
        expect the null hypothesis to be rejected with ``alternative='less'``:

        >>> sample1 = stats.norm.rvs(size=105, loc=0.5, random_state=rng)
        >>> stats.ks_2samp(sample1, sample2, alternative='less')
        KstestResult(statistic=0.4055137844611529,
                     pvalue=3.5474563068855554e-08,
                     statistic_location=-0.13249370614972575,
                     statistic_sign=-1)

        and indeed, with p-value smaller than our threshold, we reject the null
        hypothesis in favor of the alternative.

    kstat(data, n=2, *, axis=None, nan_policy='propagate', keepdims=False)
        Return the `n` th k-statistic ( ``1<=n<=4`` so far).

        The `n` th k-statistic ``k_n`` is the unique symmetric unbiased estimator of the
        `n` th cumulant :math:`\kappa_n` [1]_ [2]_.

        Parameters
        ----------
        data : array_like
            Input array.
        n : int, {1, 2, 3, 4}, optional
            Default is equal to 2.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        kstat : float
            The `n` th k-statistic.

        See Also
        --------

        :func:`kstatvar`
            Returns an unbiased estimator of the variance of the k-statistic
        :func:`moment`
            Returns the n-th central moment about the mean for a sample.


        Notes
        -----
        For a sample size :math:`n`, the first few k-statistics are given by

        .. math::

            k_1 &= \frac{S_1}{n}, \\
            k_2 &= \frac{nS_2 - S_1^2}{n(n-1)}, \\
            k_3 &= \frac{2S_1^3 - 3nS_1S_2 + n^2S_3}{n(n-1)(n-2)}, \\
            k_4 &= \frac{-6S_1^4 + 12nS_1^2S_2 - 3n(n-1)S_2^2 - 4n(n+1)S_1S_3
            + n^2(n+1)S_4}{n (n-1)(n-2)(n-3)},

        where

        .. math::

            S_r \equiv \sum_{i=1}^n X_i^r,

        and :math:`X_i` is the :math:`i` th data point.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] http://mathworld.wolfram.com/k-Statistic.html

        .. [2] http://mathworld.wolfram.com/Cumulant.html

        Examples
        --------
        >>> from scipy import stats
        >>> from numpy.random import default_rng
        >>> rng = default_rng()

        As sample size increases, `n`-th moment and `n`-th k-statistic converge to the
        same number (although they aren't identical). In the case of the normal
        distribution, they converge to zero.

        >>> for i in range(2,8):
        ...     x = rng.normal(size=10**i)
        ...     m, k = stats.moment(x, 3), stats.kstat(x, 3)
        ...     print(f"{i=}: {m=:.3g}, {k=:.3g}, {(m-k)=:.3g}")
        i=2: m=-0.631, k=-0.651, (m-k)=0.0194  # random
        i=3: m=0.0282, k=0.0283, (m-k)=-8.49e-05
        i=4: m=-0.0454, k=-0.0454, (m-k)=1.36e-05
        i=6: m=7.53e-05, k=7.53e-05, (m-k)=-2.26e-09
        i=7: m=0.00166, k=0.00166, (m-k)=-4.99e-09
        i=8: m=-2.88e-06 k=-2.88e-06, (m-k)=8.63e-13

    kstatvar(data, n=2, *, axis=None, nan_policy='propagate', keepdims=False)
        Return an unbiased estimator of the variance of the k-statistic.

        See `kstat` and [1]_ for more details about the k-statistic.

        Parameters
        ----------
        data : array_like
            Input array.
        n : int, {1, 2}, optional
            Default is equal to 2.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        kstatvar : float
            The `n` th k-statistic variance.

        See Also
        --------

        :func:`kstat`
            Returns the n-th k-statistic.
        :func:`moment`
            Returns the n-th central moment about the mean for a sample.


        Notes
        -----
        Unbiased estimators of the variances of the first two k-statistics are given by

        .. math::

            \mathrm{var}(k_1) &= \frac{k_2}{n}, \\
            \mathrm{var}(k_2) &= \frac{2k_2^2n + (n-1)k_4}{n(n - 1)}.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] http://mathworld.wolfram.com/k-Statistic.html

    kstest(rvs, cdf, args=(), N=20, alternative='two-sided', method='auto', *, axis=0, nan_policy='propagate', keepdims=False)
        Performs the (one-sample or two-sample) Kolmogorov-Smirnov test for
        goodness of fit.

        The one-sample test compares the underlying distribution F(x) of a sample
        against a given distribution G(x). The two-sample test compares the
        underlying distributions of two independent samples. Both tests are valid
        only for continuous distributions.

        Parameters
        ----------
        rvs : str, array_like, or callable
            If an array, it should be a 1-D array of observations of random
            variables.
            If a callable, it should be a function to generate random variables;
            it is required to have a keyword argument `size`.
            If a string, it should be the name of a distribution in `scipy.stats`,
            which will be used to generate random variables.
        cdf : str, array_like or callable
            If array_like, it should be a 1-D array of observations of random
            variables, and the two-sample test is performed
            (and rvs must be array_like).
            If a callable, that callable is used to calculate the cdf.
            If a string, it should be the name of a distribution in `scipy.stats`,
            which will be used as the cdf function.
        args : tuple, sequence, optional
            Distribution parameters, used if `rvs` or `cdf` are strings or
            callables.
        N : int, optional
            Sample size if `rvs` is string or callable.  Default is 20.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the null and alternative hypotheses. Default is 'two-sided'.
            Please see explanations in the Notes below.
        method : {'auto', 'exact', 'approx', 'asymp'}, optional
            Defines the distribution used for calculating the p-value.
            The following options are available (default is 'auto'):

              * 'auto' : selects one of the other options.
              * 'exact' : uses the exact distribution of test statistic.
              * 'approx' : approximates the two-sided probability with twice the
                one-sided probability
              * 'asymp': uses asymptotic distribution of test statistic
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res: KstestResult
            An object containing attributes:

            statistic : float
                KS test statistic, either D+, D-, or D (the maximum of the two)
            pvalue : float
                One-tailed or two-tailed p-value.
            statistic_location : float
                In a one-sample test, this is the value of `rvs`
                corresponding with the KS statistic; i.e., the distance between
                the empirical distribution function and the hypothesized cumulative
                distribution function is measured at this observation.

                In a two-sample test, this is the value from `rvs` or `cdf`
                corresponding with the KS statistic; i.e., the distance between
                the empirical distribution functions is measured at this
                observation.
            statistic_sign : int
                In a one-sample test, this is +1 if the KS statistic is the
                maximum positive difference between the empirical distribution
                function and the hypothesized cumulative distribution function
                (D+); it is -1 if the KS statistic is the maximum negative
                difference (D-).

                In a two-sample test, this is +1 if the empirical distribution
                function of `rvs` exceeds the empirical distribution
                function of `cdf` at `statistic_location`, otherwise -1.

        See Also
        --------

        :func:`ks_1samp`, :func:`ks_2samp`
            ..

        Notes
        -----
        There are three options for the null and corresponding alternative
        hypothesis that can be selected using the `alternative` parameter.

        - `two-sided`: The null hypothesis is that the two distributions are
          identical, F(x)=G(x) for all x; the alternative is that they are not
          identical.

        - `less`: The null hypothesis is that F(x) >= G(x) for all x; the
          alternative is that F(x) < G(x) for at least one x.

        - `greater`: The null hypothesis is that F(x) <= G(x) for all x; the
          alternative is that F(x) > G(x) for at least one x.

        Note that the alternative hypotheses describe the *CDFs* of the
        underlying distributions, not the observed values. For example,
        suppose x1 ~ F and x2 ~ G. If F(x) > G(x) for all x, the values in
        x1 tend to be less than those in x2.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        Suppose we wish to test the null hypothesis that a sample is distributed
        according to the standard normal.
        We choose a confidence level of 95%; that is, we will reject the null
        hypothesis in favor of the alternative if the p-value is less than 0.05.

        When testing uniformly distributed data, we would expect the
        null hypothesis to be rejected.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> stats.kstest(stats.uniform.rvs(size=100, random_state=rng),
        ...              stats.norm.cdf)
        KstestResult(statistic=0.5001899973268688,
                     pvalue=1.1616392184763533e-23,
                     statistic_location=0.00047625268963724654,
                     statistic_sign=-1)

        Indeed, the p-value is lower than our threshold of 0.05, so we reject the
        null hypothesis in favor of the default "two-sided" alternative: the data
        are *not* distributed according to the standard normal.

        When testing random variates from the standard normal distribution, we
        expect the data to be consistent with the null hypothesis most of the time.

        >>> x = stats.norm.rvs(size=100, random_state=rng)
        >>> stats.kstest(x, stats.norm.cdf)
        KstestResult(statistic=0.05345882212970396,
                     pvalue=0.9227159037744717,
                     statistic_location=-1.2451343873745018,
                     statistic_sign=1)

        As expected, the p-value of 0.92 is not below our threshold of 0.05, so
        we cannot reject the null hypothesis.

        Suppose, however, that the random variates are distributed according to
        a normal distribution that is shifted toward greater values. In this case,
        the cumulative density function (CDF) of the underlying distribution tends
        to be *less* than the CDF of the standard normal. Therefore, we would
        expect the null hypothesis to be rejected with ``alternative='less'``:

        >>> x = stats.norm.rvs(size=100, loc=0.5, random_state=rng)
        >>> stats.kstest(x, stats.norm.cdf, alternative='less')
        KstestResult(statistic=0.17482387821055168,
                     pvalue=0.001913921057766743,
                     statistic_location=0.3713830565352756,
                     statistic_sign=-1)

        and indeed, with p-value smaller than our threshold, we reject the null
        hypothesis in favor of the alternative.

        For convenience, the previous test can be performed using the name of the
        distribution as the second argument.

        >>> stats.kstest(x, "norm", alternative='less')
        KstestResult(statistic=0.17482387821055168,
                     pvalue=0.001913921057766743,
                     statistic_location=0.3713830565352756,
                     statistic_sign=-1)

        The examples above have all been one-sample tests identical to those
        performed by `ks_1samp`. Note that `kstest` can also perform two-sample
        tests identical to those performed by `ks_2samp`. For example, when two
        samples are drawn from the same distribution, we expect the data to be
        consistent with the null hypothesis most of the time.

        >>> sample1 = stats.laplace.rvs(size=105, random_state=rng)
        >>> sample2 = stats.laplace.rvs(size=95, random_state=rng)
        >>> stats.kstest(sample1, sample2)
        KstestResult(statistic=0.11779448621553884,
                     pvalue=0.4494256912629795,
                     statistic_location=0.6138814275424155,
                     statistic_sign=1)

        As expected, the p-value of 0.45 is not below our threshold of 0.05, so
        we cannot reject the null hypothesis.

    kurtosis(a, axis=0, fisher=True, bias=True, nan_policy='propagate', *, keepdims=False)
        Compute the kurtosis (Fisher or Pearson) of a dataset.

        Kurtosis is the fourth central moment divided by the square of the
        variance. If Fisher's definition is used, then 3.0 is subtracted from
        the result to give 0.0 for a normal distribution.

        If bias is False then the kurtosis is calculated using k statistics to
        eliminate bias coming from biased moment estimators

        Use `kurtosistest` to see if result is close enough to normal.

        Parameters
        ----------
        a : array
            Data for which the kurtosis is calculated.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        fisher : bool, optional
            If True, Fisher's definition is used (normal ==> 0.0). If False,
            Pearson's definition is used (normal ==> 3.0).
        bias : bool, optional
            If False, then the calculations are corrected for statistical bias.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        kurtosis : array
            The kurtosis of values along an axis, returning NaN where all values
            are equal.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Zwillinger, D. and Kokoska, S. (2000). CRC Standard
           Probability and Statistics Tables and Formulae. Chapman & Hall: New
           York. 2000.

        Examples
        --------
        In Fisher's definition, the kurtosis of the normal distribution is zero.
        In the following example, the kurtosis is close to zero, because it was
        calculated from the dataset, not from the continuous distribution.

        >>> import numpy as np
        >>> from scipy.stats import norm, kurtosis
        >>> data = norm.rvs(size=1000, random_state=3)
        >>> kurtosis(data)
        -0.06928694200380558

        The distribution with a higher kurtosis has a heavier tail.
        The zero valued kurtosis of the normal distribution in Fisher's definition
        can serve as a reference point.

        >>> import matplotlib.pyplot as plt
        >>> import scipy.stats as stats
        >>> from scipy.stats import kurtosis

        >>> x = np.linspace(-5, 5, 100)
        >>> ax = plt.subplot()
        >>> distnames = ['laplace', 'norm', 'uniform']

        >>> for distname in distnames:
        ...     if distname == 'uniform':
        ...         dist = getattr(stats, distname)(loc=-2, scale=4)
        ...     else:
        ...         dist = getattr(stats, distname)
        ...     data = dist.rvs(size=1000)
        ...     kur = kurtosis(data, fisher=True)
        ...     y = dist.pdf(x)
        ...     ax.plot(x, y, label="{}, {}".format(distname, round(kur, 3)))
        ...     ax.legend()

        The Laplace distribution has a heavier tail than the normal distribution.
        The uniform distribution (which has negative kurtosis) has the thinnest
        tail.

    kurtosistest(a, axis=0, nan_policy='propagate', alternative='two-sided', *, keepdims=False)
        Test whether a dataset has normal kurtosis.

        This function tests the null hypothesis that the kurtosis
        of the population from which the sample was drawn is that
        of the normal distribution.

        Parameters
        ----------
        a : array
            Array of the sample data. Must contain at least five observations.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the kurtosis of the distribution underlying the sample
              is different from that of the normal distribution
            * 'less': the kurtosis of the distribution underlying the sample
              is less than that of the normal distribution
            * 'greater': the kurtosis of the distribution underlying the sample
              is greater than that of the normal distribution

            .. versionadded:: 1.7.0
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The computed z-score for this test.
        pvalue : float
            The p-value for the hypothesis test.

        Notes
        -----
        Valid only for n>20. This function uses the method described in [1]_.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] see e.g. F. J. Anscombe, W. J. Glynn, "Distribution of the kurtosis
           statistic b2 for normal samples", Biometrika, vol. 70, pp. 227-234, 1983.
        .. [2] Shapiro, S. S., & Wilk, M. B. (1965). An analysis of variance test
               for normality (complete samples). Biometrika, 52(3/4), 591-611.
        .. [3] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [4] Panagiotakos, D. B. (2008). The value of p-value in biomedical
               research. The open cardiovascular medicine journal, 2, 97.

        Examples
        --------
        Suppose we wish to infer from measurements whether the weights of adult
        human males in a medical study are not normally distributed [2]_.
        The weights (lbs) are recorded in the array ``x`` below.

        >>> import numpy as np
        >>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

        The kurtosis test from [1]_ begins by computing a statistic based on the
        sample (excess/Fisher) kurtosis.

        >>> from scipy import stats
        >>> res = stats.kurtosistest(x)
        >>> res.statistic
        2.3048235214240873

        (The test warns that our sample has too few observations to perform the
        test. We'll return to this at the end of the example.)
        Because normal distributions have zero excess kurtosis (by definition),
        the magnitude of this statistic tends to be low for samples drawn from a
        normal distribution.

        The test is performed by comparing the observed value of the
        statistic against the null distribution: the distribution of statistic
        values derived under the null hypothesis that the weights were drawn from
        a normal distribution.

        For this test, the null distribution of the statistic for very large
        samples is the standard normal distribution.

        >>> import matplotlib.pyplot as plt
        >>> dist = stats.norm()
        >>> kt_val = np.linspace(-5, 5, 100)
        >>> pdf = dist.pdf(kt_val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def kt_plot(ax):  # we'll reuse this
        ...     ax.plot(kt_val, pdf)
        ...     ax.set_title("Kurtosis Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> kt_plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution as extreme or more extreme than the observed
        value of the statistic. In a two-sided test in which the statistic is
        positive, elements of the null distribution greater than the observed
        statistic and elements of the null distribution less than the negative of
        the observed statistic are both considered "more extreme".

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> kt_plot(ax)
        >>> pvalue = dist.cdf(-res.statistic) + dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (3, 0.005), (3.25, 0.02), arrowprops=props)
        >>> i = kt_val >= res.statistic
        >>> ax.fill_between(kt_val[i], y1=0, y2=pdf[i], color='C0')
        >>> i = kt_val <= -res.statistic
        >>> ax.fill_between(kt_val[i], y1=0, y2=pdf[i], color='C0')
        >>> ax.set_xlim(-5, 5)
        >>> ax.set_ylim(0, 0.1)
        >>> plt.show()
        >>> res.pvalue
        0.0211764592113868

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from a normally distributed population that produces such an
        extreme value of the statistic - this may be taken as evidence against
        the null hypothesis in favor of the alternative: the weights were not
        drawn from a normal distribution. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [3]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).

        Note that the standard normal distribution provides an asymptotic
        approximation of the null distribution; it is only accurate for samples
        with many observations. This is the reason we received a warning at the
        beginning of the example; our sample is quite small. In this case,
        `scipy.stats.monte_carlo_test` may provide a more accurate, albeit
        stochastic, approximation of the exact p-value.

        >>> def statistic(x, axis):
        ...     # get just the skewtest statistic; ignore the p-value
        ...     return stats.kurtosistest(x, axis=axis).statistic
        >>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> kt_plot(ax)
        >>> ax.hist(res.null_distribution, np.linspace(-5, 5, 50),
        ...         density=True)
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'Monte Carlo approximation\n(11 observations)'])
        >>> plt.show()
        >>> res.pvalue
        0.0272  # may vary

        Furthermore, despite their stochastic nature, p-values computed in this way
        can be used to exactly control the rate of false rejections of the null
        hypothesis [4]_.

    levene(*samples, center='median', proportiontocut=0.05, axis=0, nan_policy='propagate', keepdims=False)
        Perform Levene test for equal variances.

        The Levene test tests the null hypothesis that all input samples
        are from populations with equal variances.  Levene's test is an
        alternative to Bartlett's test `bartlett` in the case where
        there are significant deviations from normality.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            The sample data, possibly with different lengths. Only one-dimensional
            samples are accepted.
        center : {'mean', 'median', 'trimmed'}, optional
            Which function of the data to use in the test.  The default
            is 'median'.
        proportiontocut : float, optional
            When `center` is 'trimmed', this gives the proportion of data points
            to cut from each end. (See `scipy.stats.trim_mean`.)
            Default is 0.05.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic.
        pvalue : float
            The p-value for the test.

        See Also
        --------

        :func:`fligner`
            A non-parametric test for the equality of k variances
        :func:`bartlett`
            A parametric test for equality of k variances in normal samples


        Notes
        -----
        Three variations of Levene's test are possible.  The possibilities
        and their recommended usages are:

          * 'median' : Recommended for skewed (non-normal) distributions>
          * 'mean' : Recommended for symmetric, moderate-tailed distributions.
          * 'trimmed' : Recommended for heavy-tailed distributions.

        The test version using the mean was proposed in the original article
        of Levene ([2]_) while the median and trimmed mean have been studied by
        Brown and Forsythe ([3]_), sometimes also referred to as Brown-Forsythe
        test.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://www.itl.nist.gov/div898/handbook/eda/section3/eda35a.htm
        .. [2] Levene, H. (1960). In Contributions to Probability and Statistics:
               Essays in Honor of Harold Hotelling, I. Olkin et al. eds.,
               Stanford University Press, pp. 278-292.
        .. [3] Brown, M. B. and Forsythe, A. B. (1974), Journal of the American
               Statistical Association, 69, 364-367
        .. [4] C.I. BLISS (1952), The Statistics of Bioassay: With Special
               Reference to the Vitamins, pp 499-503,
               :doi:`10.1016/C2013-0-12584-6`.
        .. [5] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [6] Ludbrook, J., & Dudley, H. (1998). Why permutation tests are
               superior to t and F tests in biomedical research. The American
               Statistician, 52(2), 127-132.

        Examples
        --------
        In [4]_, the influence of vitamin C on the tooth growth of guinea pigs
        was investigated. In a control study, 60 subjects were divided into
        small dose, medium dose, and large dose groups that received
        daily doses of 0.5, 1.0 and 2.0 mg of vitamin C, respectively.
        After 42 days, the tooth growth was measured.

        The ``small_dose``, ``medium_dose``, and ``large_dose`` arrays below record
        tooth growth measurements of the three groups in microns.

        >>> import numpy as np
        >>> small_dose = np.array([
        ...     4.2, 11.5, 7.3, 5.8, 6.4, 10, 11.2, 11.2, 5.2, 7,
        ...     15.2, 21.5, 17.6, 9.7, 14.5, 10, 8.2, 9.4, 16.5, 9.7
        ... ])
        >>> medium_dose = np.array([
        ...     16.5, 16.5, 15.2, 17.3, 22.5, 17.3, 13.6, 14.5, 18.8, 15.5,
        ...     19.7, 23.3, 23.6, 26.4, 20, 25.2, 25.8, 21.2, 14.5, 27.3
        ... ])
        >>> large_dose = np.array([
        ...     23.6, 18.5, 33.9, 25.5, 26.4, 32.5, 26.7, 21.5, 23.3, 29.5,
        ...     25.5, 26.4, 22.4, 24.5, 24.8, 30.9, 26.4, 27.3, 29.4, 23
        ... ])

        The `levene` statistic is sensitive to differences in variances
        between the samples.

        >>> from scipy import stats
        >>> res = stats.levene(small_dose, medium_dose, large_dose)
        >>> res.statistic
        0.6457341109631506

        The value of the statistic tends to be high when there is a large
        difference in variances.

        We can test for inequality of variance among the groups by comparing the
        observed value of the statistic against the null distribution: the
        distribution of statistic values derived under the null hypothesis that
        the population variances of the three groups are equal.

        For this test, the null distribution follows the F distribution as shown
        below.

        >>> import matplotlib.pyplot as plt
        >>> k, n = 3, 60   # number of samples, total number of observations
        >>> dist = stats.f(dfn=k-1, dfd=n-k)
        >>> val = np.linspace(0, 5, 100)
        >>> pdf = dist.pdf(val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(val, pdf, color='C0')
        ...     ax.set_title("Levene Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        ...     ax.set_xlim(0, 5)
        ...     ax.set_ylim(0, 1)
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution greater than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (1.5, 0.22), (2.25, 0.3), arrowprops=props)
        >>> i = val >= res.statistic
        >>> ax.fill_between(val[i], y1=0, y2=pdf[i], color='C0')
        >>> plt.show()

        >>> res.pvalue
        0.5280694573759905

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from distributions with identical variances that produces
        such an extreme value of the statistic - this may be taken as evidence
        against the null hypothesis in favor of the alternative: the variances of
        the groups are not equal. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [5]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).
        - Small p-values are not evidence for a *large* effect; rather, they can
          only provide evidence for a "significant" effect, meaning that they are
          unlikely to have occurred under the null hypothesis.

        Note that the F distribution provides an asymptotic approximation of the
        null distribution.
        For small samples, it may be more appropriate to perform a permutation
        test: Under the null hypothesis that all three samples were drawn from
        the same population, each of the measurements is equally likely to have
        been observed in any of the three samples. Therefore, we can form a
        randomized null distribution by calculating the statistic under many
        randomly-generated partitionings of the observations into the three
        samples.

        >>> def statistic(*samples):
        ...     return stats.levene(*samples).statistic
        >>> ref = stats.permutation_test(
        ...     (small_dose, medium_dose, large_dose), statistic,
        ...     permutation_type='independent', alternative='greater'
        ... )
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> bins = np.linspace(0, 5, 25)
        >>> ax.hist(
        ...     ref.null_distribution, bins=bins, density=True, facecolor="C1"
        ... )
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'randomized null distribution'])
        >>> plot(ax)
        >>> plt.show()

        >>> ref.pvalue  # randomized test p-value
        0.4559  # may vary

        Note that there is significant disagreement between the p-value calculated
        here and the asymptotic approximation returned by `levene` above.
        The statistical inferences that can be drawn rigorously from a permutation
        test are limited; nonetheless, they may be the preferred approach in many
        circumstances [6]_.

        Following is another generic example where the null hypothesis would be
        rejected.

        Test whether the lists `a`, `b` and `c` come from populations
        with equal variances.

        >>> a = [8.88, 9.12, 9.04, 8.98, 9.00, 9.08, 9.01, 8.85, 9.06, 8.99]
        >>> b = [8.88, 8.95, 9.29, 9.44, 9.15, 9.58, 8.36, 9.18, 8.67, 9.05]
        >>> c = [8.95, 9.12, 8.95, 8.85, 9.03, 8.84, 9.07, 8.98, 8.86, 8.98]
        >>> stat, p = stats.levene(a, b, c)
        >>> p
        0.002431505967249681

        The small p-value suggests that the populations do not have equal
        variances.

        This is not surprising, given that the sample variance of `b` is much
        larger than that of `a` and `c`:

        >>> [np.var(x, ddof=1) for x in [a, b, c]]
        [0.007054444444444413, 0.13073888888888888, 0.008890000000000002]

    linregress(x, y=None, alternative='two-sided')
        Calculate a linear least-squares regression for two sets of measurements.

        Parameters
        ----------
        x, y : array_like
            Two sets of measurements.  Both arrays should have the same length N.  If
            only `x` is given (and ``y=None``), then it must be a two-dimensional
            array where one dimension has length 2.  The two sets of measurements
            are then found by splitting the array along the length-2 dimension. In
            the case where ``y=None`` and `x` is a 2xN array, ``linregress(x)`` is
            equivalent to ``linregress(x[0], x[1])``.

            .. deprecated:: 1.14.0
                Inference of the two sets of measurements from a single argument `x`
                is deprecated will result in an error in SciPy 1.16.0; the sets
                must be specified separately as `x` and `y`.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the slope of the regression line is nonzero
            * 'less': the slope of the regression line is less than zero
            * 'greater':  the slope of the regression line is greater than zero

            .. versionadded:: 1.7.0

        Returns
        -------
        result : ``LinregressResult`` instance
            The return value is an object with the following attributes:

            slope : float
                Slope of the regression line.
            intercept : float
                Intercept of the regression line.
            rvalue : float
                The Pearson correlation coefficient. The square of ``rvalue``
                is equal to the coefficient of determination.
            pvalue : float
                The p-value for a hypothesis test whose null hypothesis is
                that the slope is zero, using Wald Test with t-distribution of
                the test statistic. See `alternative` above for alternative
                hypotheses.
            stderr : float
                Standard error of the estimated slope (gradient), under the
                assumption of residual normality.
            intercept_stderr : float
                Standard error of the estimated intercept, under the assumption
                of residual normality.

        See Also
        --------
        scipy.optimize.curve_fit :
            Use non-linear least squares to fit a function to data.
        scipy.optimize.leastsq :
            Minimize the sum of squares of a set of equations.

        Notes
        -----
        For compatibility with older versions of SciPy, the return value acts
        like a ``namedtuple`` of length 5, with fields ``slope``, ``intercept``,
        ``rvalue``, ``pvalue`` and ``stderr``, so one can continue to write::

            slope, intercept, r, p, se = linregress(x, y)

        With that style, however, the standard error of the intercept is not
        available.  To have access to all the computed values, including the
        standard error of the intercept, use the return value as an object
        with attributes, e.g.::

            result = linregress(x, y)
            print(result.intercept, result.intercept_stderr)

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import stats
        >>> rng = np.random.default_rng()

        Generate some data:

        >>> x = rng.random(10)
        >>> y = 1.6*x + rng.random(10)

        Perform the linear regression:

        >>> res = stats.linregress(x, y)

        Coefficient of determination (R-squared):

        >>> print(f"R-squared: {res.rvalue**2:.6f}")
        R-squared: 0.717533

        Plot the data along with the fitted line:

        >>> plt.plot(x, y, 'o', label='original data')
        >>> plt.plot(x, res.intercept + res.slope*x, 'r', label='fitted line')
        >>> plt.legend()
        >>> plt.show()

        Calculate 95% confidence interval on slope and intercept:

        >>> # Two-sided inverse Students t-distribution
        >>> # p - probability, df - degrees of freedom
        >>> from scipy.stats import t
        >>> tinv = lambda p, df: abs(t.ppf(p/2, df))

        >>> ts = tinv(0.05, len(x)-2)
        >>> print(f"slope (95%): {res.slope:.6f} +/- {ts*res.stderr:.6f}")
        slope (95%): 1.453392 +/- 0.743465
        >>> print(f"intercept (95%): {res.intercept:.6f}"
        ...       f" +/- {ts*res.intercept_stderr:.6f}")
        intercept (95%): 0.616950 +/- 0.544475

    logrank(x: 'npt.ArrayLike | CensoredData', y: 'npt.ArrayLike | CensoredData', alternative: "Literal['two-sided', 'less', 'greater']" = 'two-sided') -> 'LogRankResult'
        Compare the survival distributions of two samples via the logrank test.

        Parameters
        ----------
        x, y : array_like or CensoredData
            Samples to compare based on their empirical survival functions.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.

            The null hypothesis is that the survival distributions of the two
            groups, say *X* and *Y*, are identical.

            The following alternative hypotheses [4]_ are available (default is
            'two-sided'):

            * 'two-sided': the survival distributions of the two groups are not
              identical.
            * 'less': survival of group *X* is favored: the group *X* failure rate
              function is less than the group *Y* failure rate function at some
              times.
            * 'greater': survival of group *Y* is favored: the group *X* failure
              rate function is greater than the group *Y* failure rate function at
              some times.

        Returns
        -------
        res : `~scipy.stats._result_classes.LogRankResult`
            An object containing attributes:

            statistic : float ndarray
                The computed statistic (defined below). Its magnitude is the
                square root of the magnitude returned by most other logrank test
                implementations.
            pvalue : float ndarray
                The computed p-value of the test.

        See Also
        --------
        scipy.stats.ecdf

        Notes
        -----
        The logrank test [1]_ compares the observed number of events to
        the expected number of events under the null hypothesis that the two
        samples were drawn from the same distribution. The statistic is

        .. math::

            Z_i = \frac{\sum_{j=1}^J(O_{i,j}-E_{i,j})}{\sqrt{\sum_{j=1}^J V_{i,j}}}
            \rightarrow \mathcal{N}(0,1)

        where

        .. math::

            E_{i,j} = O_j \frac{N_{i,j}}{N_j},
            \qquad
            V_{i,j} = E_{i,j} \left(\frac{N_j-O_j}{N_j}\right)
            \left(\frac{N_j-N_{i,j}}{N_j-1}\right),

        :math:`i` denotes the group (i.e. it may assume values :math:`x` or
        :math:`y`, or it may be omitted to refer to the combined sample)
        :math:`j` denotes the time (at which an event occurred),
        :math:`N` is the number of subjects at risk just before an event occurred,
        and :math:`O` is the observed number of events at that time.

        The ``statistic`` :math:`Z_x` returned by `logrank` is the (signed) square
        root of the statistic returned by many other implementations. Under the
        null hypothesis, :math:`Z_x**2` is asymptotically distributed according to
        the chi-squared distribution with one degree of freedom. Consequently,
        :math:`Z_x` is asymptotically distributed according to the standard normal
        distribution. The advantage of using :math:`Z_x` is that the sign
        information (i.e. whether the observed number of events tends to be less
        than or greater than the number expected under the null hypothesis) is
        preserved, allowing `scipy.stats.logrank` to offer one-sided alternative
        hypotheses.

        References
        ----------
        .. [1] Mantel N. "Evaluation of survival data and two new rank order
               statistics arising in its consideration."
               Cancer Chemotherapy Reports, 50(3):163-170, PMID: 5910392, 1966
        .. [2] Bland, Altman, "The logrank test", BMJ, 328:1073,
               :doi:`10.1136/bmj.328.7447.1073`, 2004
        .. [3] "Logrank test", Wikipedia,
               https://en.wikipedia.org/wiki/Logrank_test
        .. [4] Brown, Mark. "On the choice of variance for the log rank test."
               Biometrika 71.1 (1984): 65-74.
        .. [5] Klein, John P., and Melvin L. Moeschberger. Survival analysis:
               techniques for censored and truncated data. Vol. 1230. New York:
               Springer, 2003.

        Examples
        --------
        Reference [2]_ compared the survival times of patients with two different
        types of recurrent malignant gliomas. The samples below record the time
        (number of weeks) for which each patient participated in the study. The
        `scipy.stats.CensoredData` class is used because the data is
        right-censored: the uncensored observations correspond with observed deaths
        whereas the censored observations correspond with the patient leaving the
        study for another reason.

        >>> from scipy import stats
        >>> x = stats.CensoredData(
        ...     uncensored=[6, 13, 21, 30, 37, 38, 49, 50,
        ...                 63, 79, 86, 98, 202, 219],
        ...     right=[31, 47, 80, 82, 82, 149]
        ... )
        >>> y = stats.CensoredData(
        ...     uncensored=[10, 10, 12, 13, 14, 15, 16, 17, 18, 20, 24, 24,
        ...                 25, 28,30, 33, 35, 37, 40, 40, 46, 48, 76, 81,
        ...                 82, 91, 112, 181],
        ...     right=[34, 40, 70]
        ... )

        We can calculate and visualize the empirical survival functions
        of both groups as follows.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> ax = plt.subplot()
        >>> ecdf_x = stats.ecdf(x)
        >>> ecdf_x.sf.plot(ax, label='Astrocytoma')
        >>> ecdf_y = stats.ecdf(y)
        >>> ecdf_y.sf.plot(ax, label='Glioblastoma')
        >>> ax.set_xlabel('Time to death (weeks)')
        >>> ax.set_ylabel('Empirical SF')
        >>> plt.legend()
        >>> plt.show()

        Visual inspection of the empirical survival functions suggests that the
        survival times tend to be different between the two groups. To formally
        assess whether the difference is significant at the 1% level, we use the
        logrank test.

        >>> res = stats.logrank(x=x, y=y)
        >>> res.statistic
        -2.73799
        >>> res.pvalue
        0.00618

        The p-value is less than 1%, so we can consider the data to be evidence
        against the null hypothesis in favor of the alternative that there is a
        difference between the two survival functions.

    mannwhitneyu(x, y, use_continuity=True, alternative='two-sided', axis=0, method='auto', *, nan_policy='propagate', keepdims=False)
        Perform the Mann-Whitney U rank test on two independent samples.

        The Mann-Whitney U test is a nonparametric test of the null hypothesis
        that the distribution underlying sample `x` is the same as the
        distribution underlying sample `y`. It is often used as a test of
        difference in location between distributions.

        Parameters
        ----------
        x, y : array-like
            N-d arrays of samples. The arrays must be broadcastable except along
            the dimension given by `axis`.
        use_continuity : bool, optional
            Whether a continuity correction (1/2) should be applied.
            Default is True when `method` is ``'asymptotic'``; has no effect
            otherwise.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            Let *F(u)* and *G(u)* be the cumulative distribution functions of the
            distributions underlying `x` and `y`, respectively. Then the following
            alternative hypotheses are available:

            * 'two-sided': the distributions are not equal, i.e. *F(u) ≠ G(u)* for
              at least one *u*.
            * 'less': the distribution underlying `x` is stochastically less
              than the distribution underlying `y`, i.e. *F(u) > G(u)* for all *u*.
            * 'greater': the distribution underlying `x` is stochastically greater
              than the distribution underlying `y`, i.e. *F(u) < G(u)* for all *u*.

            Note that the mathematical expressions in the alternative hypotheses
            above describe the CDFs of the underlying distributions. The directions
            of the inequalities appear inconsistent with the natural language
            description at first glance, but they are not. For example, suppose
            *X* and *Y* are random variables that follow distributions with CDFs
            *F* and *G*, respectively. If *F(u) > G(u)* for all *u*, samples drawn
            from *X* tend to be less than those drawn from *Y*.

            Under a more restrictive set of assumptions, the alternative hypotheses
            can be expressed in terms of the locations of the distributions;
            see [5] section 5.1.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        method : {'auto', 'asymptotic', 'exact'} or `PermutationMethod` instance, optional
            Selects the method used to calculate the *p*-value.
            Default is 'auto'. The following options are available.

            * ``'asymptotic'``: compares the standardized test statistic
              against the normal distribution, correcting for ties.
            * ``'exact'``: computes the exact *p*-value by comparing the observed
              :math:`U` statistic against the exact distribution of the :math:`U`
              statistic under the null hypothesis. No correction is made for ties.
            * ``'auto'``: chooses ``'exact'`` when the size of one of the samples
              is less than or equal to 8 and there are no ties;
              chooses ``'asymptotic'`` otherwise.
            * `PermutationMethod` instance. In this case, the p-value
              is computed using `permutation_test` with the provided
              configuration options and other appropriate settings.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : MannwhitneyuResult
            An object containing attributes:

            statistic : float
                The Mann-Whitney U statistic corresponding with sample `x`. See
                Notes for the test statistic corresponding with sample `y`.
            pvalue : float
                The associated *p*-value for the chosen `alternative`.

        See Also
        --------

        :func:`scipy.stats.wilcoxon`, :func:`scipy.stats.ranksums`, :func:`scipy.stats.ttest_ind`
            ..

        Notes
        -----
        If ``U1`` is the statistic corresponding with sample `x`, then the
        statistic corresponding with sample `y` is
        ``U2 = x.shape[axis] * y.shape[axis] - U1``.

        `mannwhitneyu` is for independent samples. For related / paired samples,
        consider `scipy.stats.wilcoxon`.

        `method` ``'exact'`` is recommended when there are no ties and when either
        sample size is less than 8 [1]_. The implementation follows the algorithm
        reported in [3]_.
        Note that the exact method is *not* corrected for ties, but
        `mannwhitneyu` will not raise errors or warnings if there are ties in the
        data. If there are ties and either samples is small (fewer than ~10
        observations), consider passing an instance of `PermutationMethod`
        as the `method` to perform a permutation test.

        The Mann-Whitney U test is a non-parametric version of the t-test for
        independent samples. When the means of samples from the populations
        are normally distributed, consider `scipy.stats.ttest_ind`.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] H.B. Mann and D.R. Whitney, "On a test of whether one of two random
               variables is stochastically larger than the other", The Annals of
               Mathematical Statistics, Vol. 18, pp. 50-60, 1947.
        .. [2] Mann-Whitney U Test, Wikipedia,
               http://en.wikipedia.org/wiki/Mann-Whitney_U_test
        .. [3] Andreas Löffler,
               "Über eine Partition der nat. Zahlen und ihr Anwendung beim U-Test",
               Wiss. Z. Univ. Halle, XXXII'83 pp. 87-89.
        .. [4] Rosie Shier, "Statistics: 2.3 The Mann-Whitney U Test", Mathematics
               Learning Support Centre, 2004.
        .. [5] Michael P. Fay and Michael A. Proschan. "Wilcoxon-Mann-Whitney
               or t-test? On assumptions for hypothesis tests and multiple \
               interpretations of decision rules." Statistics surveys, Vol. 4, pp.
               1-39, 2010. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2857732/

        Examples
        --------
        We follow the example from [4]_: nine randomly sampled young adults were
        diagnosed with type II diabetes at the ages below.

        >>> males = [19, 22, 16, 29, 24]
        >>> females = [20, 11, 17, 12]

        We use the Mann-Whitney U test to assess whether there is a statistically
        significant difference in the diagnosis age of males and females.
        The null hypothesis is that the distribution of male diagnosis ages is
        the same as the distribution of female diagnosis ages. We decide
        that a confidence level of 95% is required to reject the null hypothesis
        in favor of the alternative that the distributions are different.
        Since the number of samples is very small and there are no ties in the
        data, we can compare the observed test statistic against the *exact*
        distribution of the test statistic under the null hypothesis.

        >>> from scipy.stats import mannwhitneyu
        >>> U1, p = mannwhitneyu(males, females, method="exact")
        >>> print(U1)
        17.0

        `mannwhitneyu` always reports the statistic associated with the first
        sample, which, in this case, is males. This agrees with :math:`U_M = 17`
        reported in [4]_. The statistic associated with the second statistic
        can be calculated:

        >>> nx, ny = len(males), len(females)
        >>> U2 = nx*ny - U1
        >>> print(U2)
        3.0

        This agrees with :math:`U_F = 3` reported in [4]_. The two-sided
        *p*-value can be calculated from either statistic, and the value produced
        by `mannwhitneyu` agrees with :math:`p = 0.11` reported in [4]_.

        >>> print(p)
        0.1111111111111111

        The exact distribution of the test statistic is asymptotically normal, so
        the example continues by comparing the exact *p*-value against the
        *p*-value produced using the normal approximation.

        >>> _, pnorm = mannwhitneyu(males, females, method="asymptotic")
        >>> print(pnorm)
        0.11134688653314041

        Here `mannwhitneyu`'s reported *p*-value appears to conflict with the
        value :math:`p = 0.09` given in [4]_. The reason is that [4]_
        does not apply the continuity correction performed by `mannwhitneyu`;
        `mannwhitneyu` reduces the distance between the test statistic and the
        mean :math:`\mu = n_x n_y / 2` by 0.5 to correct for the fact that the
        discrete statistic is being compared against a continuous distribution.
        Here, the :math:`U` statistic used is less than the mean, so we reduce
        the distance by adding 0.5 in the numerator.

        >>> import numpy as np
        >>> from scipy.stats import norm
        >>> U = min(U1, U2)
        >>> N = nx + ny
        >>> z = (U - nx*ny/2 + 0.5) / np.sqrt(nx*ny * (N + 1)/ 12)
        >>> p = 2 * norm.cdf(z)  # use CDF to get p-value from smaller statistic
        >>> print(p)
        0.11134688653314041

        If desired, we can disable the continuity correction to get a result
        that agrees with that reported in [4]_.

        >>> _, pnorm = mannwhitneyu(males, females, use_continuity=False,
        ...                         method="asymptotic")
        >>> print(pnorm)
        0.0864107329737

        Regardless of whether we perform an exact or asymptotic test, the
        probability of the test statistic being as extreme or more extreme by
        chance exceeds 5%, so we do not consider the results statistically
        significant.

        Suppose that, before seeing the data, we had hypothesized that females
        would tend to be diagnosed at a younger age than males.
        In that case, it would be natural to provide the female ages as the
        first input, and we would have performed a one-sided test using
        ``alternative = 'less'``: females are diagnosed at an age that is
        stochastically less than that of males.

        >>> res = mannwhitneyu(females, males, alternative="less", method="exact")
        >>> print(res)
        MannwhitneyuResult(statistic=3.0, pvalue=0.05555555555555555)

        Again, the probability of getting a sufficiently low value of the
        test statistic by chance under the null hypothesis is greater than 5%,
        so we do not reject the null hypothesis in favor of our alternative.

        If it is reasonable to assume that the means of samples from the
        populations are normally distributed, we could have used a t-test to
        perform the analysis.

        >>> from scipy.stats import ttest_ind
        >>> res = ttest_ind(females, males, alternative="less")
        >>> print(res)
        TtestResult(statistic=-2.239334696520584,
                    pvalue=0.030068441095757924,
                    df=7.0)

        Under this assumption, the *p*-value would be low enough to reject the
        null hypothesis in favor of the alternative.

    median_abs_deviation(x, axis=0, center=<function median at 0x000001D8E6BAA030>, scale=1.0, nan_policy='propagate')
        Compute the median absolute deviation of the data along the given axis.

        The median absolute deviation (MAD, [1]_) computes the median over the
        absolute deviations from the median. It is a measure of dispersion
        similar to the standard deviation but more robust to outliers [2]_.

        The MAD of an empty array is ``np.nan``.

        .. versionadded:: 1.5.0

        Parameters
        ----------
        x : array_like
            Input array or object that can be converted to an array.
        axis : int or None, optional
            Axis along which the range is computed. Default is 0. If None, compute
            the MAD over the entire array.
        center : callable, optional
            A function that will return the central value. The default is to use
            np.median. Any user defined function used will need to have the
            function signature ``func(arr, axis)``.
        scale : scalar or str, optional
            The numerical value of scale will be divided out of the final
            result. The default is 1.0. The string "normal" is also accepted,
            and results in `scale` being the inverse of the standard normal
            quantile function at 0.75, which is approximately 0.67449.
            Array-like scale is also allowed, as long as it broadcasts correctly
            to the output such that ``out / scale`` is a valid operation. The
            output dimensions depend on the input array, `x`, and the `axis`
            argument.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is 'propagate'):

            * 'propagate': returns nan
            * 'raise': throws an error
            * 'omit': performs the calculations ignoring nan values

        Returns
        -------
        mad : scalar or ndarray
            If ``axis=None``, a scalar is returned. If the input contains
            integers or floats of smaller precision than ``np.float64``, then the
            output data-type is ``np.float64``. Otherwise, the output data-type is
            the same as that of the input.

        See Also
        --------
        numpy.std, numpy.var, numpy.median, scipy.stats.iqr, scipy.stats.tmean,
        scipy.stats.tstd, scipy.stats.tvar

        Notes
        -----
        The `center` argument only affects the calculation of the central value
        around which the MAD is calculated. That is, passing in ``center=np.mean``
        will calculate the MAD around the mean - it will not calculate the *mean*
        absolute deviation.

        The input array may contain `inf`, but if `center` returns `inf`, the
        corresponding MAD for that data will be `nan`.

        References
        ----------
        .. [1] "Median absolute deviation",
               https://en.wikipedia.org/wiki/Median_absolute_deviation
        .. [2] "Robust measures of scale",
               https://en.wikipedia.org/wiki/Robust_measures_of_scale

        Examples
        --------
        When comparing the behavior of `median_abs_deviation` with ``np.std``,
        the latter is affected when we change a single value of an array to have an
        outlier value while the MAD hardly changes:

        >>> import numpy as np
        >>> from scipy import stats
        >>> x = stats.norm.rvs(size=100, scale=1, random_state=123456)
        >>> x.std()
        0.9973906394005013
        >>> stats.median_abs_deviation(x)
        0.82832610097857
        >>> x[0] = 345.6
        >>> x.std()
        34.42304872314415
        >>> stats.median_abs_deviation(x)
        0.8323442311590675

        Axis handling example:

        >>> x = np.array([[10, 7, 4], [3, 2, 1]])
        >>> x
        array([[10,  7,  4],
               [ 3,  2,  1]])
        >>> stats.median_abs_deviation(x)
        array([3.5, 2.5, 1.5])
        >>> stats.median_abs_deviation(x, axis=None)
        2.0

        Scale normal example:

        >>> x = stats.norm.rvs(size=1000000, scale=2, random_state=123456)
        >>> stats.median_abs_deviation(x)
        1.3487398527041636
        >>> stats.median_abs_deviation(x, scale='normal')
        1.9996446978061115

    median_test(*samples, ties='below', correction=True, lambda_=1, nan_policy='propagate')
        Perform a Mood's median test.

        Test that two or more samples come from populations with the same median.

        Let ``n = len(samples)`` be the number of samples.  The "grand median" of
        all the data is computed, and a contingency table is formed by
        classifying the values in each sample as being above or below the grand
        median.  The contingency table, along with `correction` and `lambda_`,
        are passed to `scipy.stats.chi2_contingency` to compute the test statistic
        and p-value.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            The set of samples.  There must be at least two samples.
            Each sample must be a one-dimensional sequence containing at least
            one value.  The samples are not required to have the same length.
        ties : str, optional
            Determines how values equal to the grand median are classified in
            the contingency table.  The string must be one of::

                "below":
                    Values equal to the grand median are counted as "below".
                "above":
                    Values equal to the grand median are counted as "above".
                "ignore":
                    Values equal to the grand median are not counted.

            The default is "below".
        correction : bool, optional
            If True, *and* there are just two samples, apply Yates' correction
            for continuity when computing the test statistic associated with
            the contingency table.  Default is True.
        lambda_ : float or str, optional
            By default, the statistic computed in this test is Pearson's
            chi-squared statistic.  `lambda_` allows a statistic from the
            Cressie-Read power divergence family to be used instead.  See
            `power_divergence` for details.
            Default is 1 (Pearson's chi-squared statistic).
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan. 'propagate' returns nan,
            'raise' throws an error, 'omit' performs the calculations ignoring nan
            values. Default is 'propagate'.

        Returns
        -------
        res : MedianTestResult
            An object containing attributes:

            statistic : float
                The test statistic.  The statistic that is returned is determined
                by `lambda_`.  The default is Pearson's chi-squared statistic.
            pvalue : float
                The p-value of the test.
            median : float
                The grand median.
            table : ndarray
                The contingency table.  The shape of the table is (2, n), where
                n is the number of samples.  The first row holds the counts of the
                values above the grand median, and the second row holds the counts
                of the values below the grand median.  The table allows further
                analysis with, for example, `scipy.stats.chi2_contingency`, or with
                `scipy.stats.fisher_exact` if there are two samples, without having
                to recompute the table.  If ``nan_policy`` is "propagate" and there
                are nans in the input, the return value for ``table`` is ``None``.

        See Also
        --------
        kruskal : Compute the Kruskal-Wallis H-test for independent samples.
        mannwhitneyu : Computes the Mann-Whitney rank test on samples x and y.

        Notes
        -----
        .. versionadded:: 0.15.0

        References
        ----------
        .. [1] Mood, A. M., Introduction to the Theory of Statistics. McGraw-Hill
            (1950), pp. 394-399.
        .. [2] Zar, J. H., Biostatistical Analysis, 5th ed. Prentice Hall (2010).
            See Sections 8.12 and 10.15.

        Examples
        --------
        A biologist runs an experiment in which there are three groups of plants.
        Group 1 has 16 plants, group 2 has 15 plants, and group 3 has 17 plants.
        Each plant produces a number of seeds.  The seed counts for each group
        are::

            Group 1: 10 14 14 18 20 22 24 25 31 31 32 39 43 43 48 49
            Group 2: 28 30 31 33 34 35 36 40 44 55 57 61 91 92 99
            Group 3:  0  3  9 22 23 25 25 33 34 34 40 45 46 48 62 67 84

        The following code applies Mood's median test to these samples.

        >>> g1 = [10, 14, 14, 18, 20, 22, 24, 25, 31, 31, 32, 39, 43, 43, 48, 49]
        >>> g2 = [28, 30, 31, 33, 34, 35, 36, 40, 44, 55, 57, 61, 91, 92, 99]
        >>> g3 = [0, 3, 9, 22, 23, 25, 25, 33, 34, 34, 40, 45, 46, 48, 62, 67, 84]
        >>> from scipy.stats import median_test
        >>> res = median_test(g1, g2, g3)

        The median is

        >>> res.median
        34.0

        and the contingency table is

        >>> res.table
        array([[ 5, 10,  7],
               [11,  5, 10]])

        `p` is too large to conclude that the medians are not the same:

        >>> res.pvalue
        0.12609082774093244

        The "G-test" can be performed by passing ``lambda_="log-likelihood"`` to
        `median_test`.

        >>> res = median_test(g1, g2, g3, lambda_="log-likelihood")
        >>> res.pvalue
        0.12224779737117837

        The median occurs several times in the data, so we'll get a different
        result if, for example, ``ties="above"`` is used:

        >>> res = median_test(g1, g2, g3, ties="above")
        >>> res.pvalue
        0.063873276069553273

        >>> res.table
        array([[ 5, 11,  9],
               [11,  4,  8]])

        This example demonstrates that if the data set is not large and there
        are values equal to the median, the p-value can be sensitive to the
        choice of `ties`.

    mode(a, axis=0, nan_policy='propagate', keepdims=False)
        Return an array of the modal (most common) value in the passed array.

        If there is more than one such value, only one is returned.
        The bin-count for the modal bins is also returned.

        Parameters
        ----------
        a : array_like
            Numeric, n-dimensional array of which to find mode(s).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        mode : ndarray
            Array of modal values.
        count : ndarray
            Array of counts for each mode.

        Notes
        -----
        The mode  is calculated using `numpy.unique`.
        In NumPy versions 1.21 and after, all NaNs - even those with different
        binary representations - are treated as equivalent and counted as separate
        instances of the same value.

        By convention, the mode of an empty array is NaN, and the associated count
        is zero.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([[3, 0, 3, 7],
        ...               [3, 2, 6, 2],
        ...               [1, 7, 2, 8],
        ...               [3, 0, 6, 1],
        ...               [3, 2, 5, 5]])
        >>> from scipy import stats
        >>> stats.mode(a, keepdims=True)
        ModeResult(mode=array([[3, 0, 6, 1]]), count=array([[4, 2, 2, 1]]))

        To get mode of whole array, specify ``axis=None``:

        >>> stats.mode(a, axis=None, keepdims=True)
        ModeResult(mode=[[3]], count=[[5]])
        >>> stats.mode(a, axis=None, keepdims=False)
        ModeResult(mode=3, count=5)

    moment(a, order=1, axis=0, nan_policy='propagate', *, center=None, keepdims=False)
        Calculate the nth moment about the mean for a sample.

        A moment is a specific quantitative measure of the shape of a set of
        points. It is often used to calculate coefficients of skewness and kurtosis
        due to its close relationship with them.

        Parameters
        ----------
        a : array_like
            Input array.
        order : int or 1-D array_like of ints, optional
            Order of central moment that is returned. Default is 1.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        center : float or None, optional
            The point about which moments are taken. This can be the sample mean,
            the origin, or any other be point. If `None` (default) compute the
            center as the sample mean.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        n-th moment about the `center` : ndarray or float
            The appropriate moment along the given axis or over all values if axis
            is None. The denominator for the moment calculation is the number of
            observations, no degrees of freedom correction is done.

        See Also
        --------

        :func:`kurtosis`, :func:`skew`, :func:`describe`
            ..

        Notes
        -----
        The k-th moment of a data sample is:

        .. math::

            m_k = \frac{1}{n} \sum_{i = 1}^n (x_i - c)^k

        Where `n` is the number of samples, and `c` is the center around which the
        moment is calculated. This function uses exponentiation by squares [1]_ for
        efficiency.

        Note that, if `a` is an empty array (``a.size == 0``), array `moment` with
        one element (`moment.size == 1`) is treated the same as scalar `moment`
        (``np.isscalar(moment)``). This might produce arrays of unexpected shape.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://eli.thegreenplace.net/2009/03/21/efficient-integer-exponentiation-algorithms

        Examples
        --------
        >>> from scipy.stats import moment
        >>> moment([1, 2, 3, 4, 5], order=1)
        0.0
        >>> moment([1, 2, 3, 4, 5], order=2)
        2.0

    monte_carlo_test(data, rvs, statistic, *, vectorized=None, n_resamples=9999, batch=None, alternative='two-sided', axis=0)
        Perform a Monte Carlo hypothesis test.

        `data` contains a sample or a sequence of one or more samples. `rvs`
        specifies the distribution(s) of the sample(s) in `data` under the null
        hypothesis. The value of `statistic` for the given `data` is compared
        against a Monte Carlo null distribution: the value of the statistic for
        each of `n_resamples` sets of samples generated using `rvs`. This gives
        the p-value, the probability of observing such an extreme value of the
        test statistic under the null hypothesis.

        Parameters
        ----------
        data : array-like or sequence of array-like
            An array or sequence of arrays of observations.
        rvs : callable or tuple of callables
            A callable or sequence of callables that generates random variates
            under the null hypothesis. Each element of `rvs` must be a callable
            that accepts keyword argument ``size`` (e.g. ``rvs(size=(m, n))``) and
            returns an N-d array sample of that shape. If `rvs` is a sequence, the
            number of callables in `rvs` must match the number of samples in
            `data`, i.e. ``len(rvs) == len(data)``. If `rvs` is a single callable,
            `data` is treated as a single sample.
        statistic : callable
            Statistic for which the p-value of the hypothesis test is to be
            calculated. `statistic` must be a callable that accepts a sample
            (e.g. ``statistic(sample)``) or ``len(rvs)`` separate samples (e.g.
            ``statistic(samples1, sample2)`` if `rvs` contains two callables and
            `data` contains two samples) and returns the resulting statistic.
            If `vectorized` is set ``True``, `statistic` must also accept a keyword
            argument `axis` and be vectorized to compute the statistic along the
            provided `axis` of the samples in `data`.
        vectorized : bool, optional
            If `vectorized` is set ``False``, `statistic` will not be passed
            keyword argument `axis` and is expected to calculate the statistic
            only for 1D samples. If ``True``, `statistic` will be passed keyword
            argument `axis` and is expected to calculate the statistic along `axis`
            when passed ND sample arrays. If ``None`` (default), `vectorized`
            will be set ``True`` if ``axis`` is a parameter of `statistic`. Use of
            a vectorized statistic typically reduces computation time.
        n_resamples : int, default: 9999
            Number of samples drawn from each of the callables of `rvs`.
            Equivalently, the number statistic values under the null hypothesis
            used as the Monte Carlo null distribution.
        batch : int, optional
            The number of Monte Carlo samples to process in each call to
            `statistic`. Memory usage is O( `batch` * ``sample.size[axis]`` ). Default
            is ``None``, in which case `batch` equals `n_resamples`.
        alternative : {'two-sided', 'less', 'greater'}
            The alternative hypothesis for which the p-value is calculated.
            For each alternative, the p-value is defined as follows.

            - ``'greater'`` : the percentage of the null distribution that is
              greater than or equal to the observed value of the test statistic.
            - ``'less'`` : the percentage of the null distribution that is
              less than or equal to the observed value of the test statistic.
            - ``'two-sided'`` : twice the smaller of the p-values above.

        axis : int, default: 0
            The axis of `data` (or each sample within `data`) over which to
            calculate the statistic.

        Returns
        -------
        res : MonteCarloTestResult
            An object with attributes:

            statistic : float or ndarray
                The test statistic of the observed `data`.
            pvalue : float or ndarray
                The p-value for the given alternative.
            null_distribution : ndarray
                The values of the test statistic generated under the null
                hypothesis.

        .. warning::
            The p-value is calculated by counting the elements of the null
            distribution that are as extreme or more extreme than the observed
            value of the statistic. Due to the use of finite precision arithmetic,
            some statistic functions return numerically distinct values when the
            theoretical values would be exactly equal. In some cases, this could
            lead to a large error in the calculated p-value. `monte_carlo_test`
            guards against this by considering elements in the null distribution
            that are "close" (within a relative tolerance of 100 times the
            floating point epsilon of inexact dtypes) to the observed
            value of the test statistic as equal to the observed value of the
            test statistic. However, the user is advised to inspect the null
            distribution to assess whether this method of comparison is
            appropriate, and if not, calculate the p-value manually.

        References
        ----------

        .. [1] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
           Zero: Calculating Exact P-values When Permutations Are Randomly Drawn."
           Statistical Applications in Genetics and Molecular Biology 9.1 (2010).

        Examples
        --------

        Suppose we wish to test whether a small sample has been drawn from a normal
        distribution. We decide that we will use the skew of the sample as a
        test statistic, and we will consider a p-value of 0.05 to be statistically
        significant.

        >>> import numpy as np
        >>> from scipy import stats
        >>> def statistic(x, axis):
        ...     return stats.skew(x, axis)

        After collecting our data, we calculate the observed value of the test
        statistic.

        >>> rng = np.random.default_rng()
        >>> x = stats.skewnorm.rvs(a=1, size=50, random_state=rng)
        >>> statistic(x, axis=0)
        0.12457412450240658

        To determine the probability of observing such an extreme value of the
        skewness by chance if the sample were drawn from the normal distribution,
        we can perform a Monte Carlo hypothesis test. The test will draw many
        samples at random from their normal distribution, calculate the skewness
        of each sample, and compare our original skewness against this
        distribution to determine an approximate p-value.

        >>> from scipy.stats import monte_carlo_test
        >>> # because our statistic is vectorized, we pass `vectorized=True`
        >>> rvs = lambda size: stats.norm.rvs(size=size, random_state=rng)
        >>> res = monte_carlo_test(x, rvs, statistic, vectorized=True)
        >>> print(res.statistic)
        0.12457412450240658
        >>> print(res.pvalue)
        0.7012

        The probability of obtaining a test statistic less than or equal to the
        observed value under the null hypothesis is ~70%. This is greater than
        our chosen threshold of 5%, so we cannot consider this to be significant
        evidence against the null hypothesis.

        Note that this p-value essentially matches that of
        `scipy.stats.skewtest`, which relies on an asymptotic distribution of a
        test statistic based on the sample skewness.

        >>> stats.skewtest(x).pvalue
        0.6892046027110614

        This asymptotic approximation is not valid for small sample sizes, but
        `monte_carlo_test` can be used with samples of any size.

        >>> x = stats.skewnorm.rvs(a=1, size=7, random_state=rng)
        >>> # stats.skewtest(x) would produce an error due to small sample
        >>> res = monte_carlo_test(x, rvs, statistic, vectorized=True)

        The Monte Carlo distribution of the test statistic is provided for
        further investigation.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots()
        >>> ax.hist(res.null_distribution, bins=50)
        >>> ax.set_title("Monte Carlo distribution of test statistic")
        >>> ax.set_xlabel("Value of Statistic")
        >>> ax.set_ylabel("Frequency")
        >>> plt.show()

    mood(x, y, axis=0, alternative='two-sided', *, nan_policy='propagate', keepdims=False)
        Perform Mood's test for equal scale parameters.

        Mood's two-sample test for scale parameters is a non-parametric
        test for the null hypothesis that two samples are drawn from the
        same distribution with the same scale parameter.

        Parameters
        ----------
        x, y : array_like
            Arrays of sample data. There must be at least three observations
            total.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the scales of the distributions underlying `x` and `y`
              are different.
            * 'less': the scale of the distribution underlying `x` is less than
              the scale of the distribution underlying `y`.
            * 'greater': the scale of the distribution underlying `x` is greater
              than the scale of the distribution underlying `y`.

            .. versionadded:: 1.7.0
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        res : SignificanceResult
            An object containing attributes:

            statistic : scalar or ndarray
                The z-score for the hypothesis test.  For 1-D inputs a scalar is
                returned.
            pvalue : scalar ndarray
                The p-value for the hypothesis test.

        See Also
        --------

        :func:`fligner`
            A non-parametric test for the equality of k variances
        :func:`ansari`
            A non-parametric test for the equality of 2 variances
        :func:`bartlett`
            A parametric test for equality of k variances in normal samples
        :func:`levene`
            A parametric test for equality of k variances


        Notes
        -----
        The data are assumed to be drawn from probability distributions ``f(x)``
        and ``f(x/s) / s`` respectively, for some probability density function f.
        The null hypothesis is that ``s == 1``.

        For multi-dimensional arrays, if the inputs are of shapes
        ``(n0, n1, n2, n3)``  and ``(n0, m1, n2, n3)``, then if ``axis=1``, the
        resulting z and p values will have shape ``(n0, n2, n3)``.  Note that
        ``n1`` and ``m1`` don't have to be equal, but the other dimensions do.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        [1] Mielke, Paul W. "Note on Some Squared Rank Tests with Existing Ties."
            Technometrics, vol. 9, no. 2, 1967, pp. 312-14. JSTOR,
            https://doi.org/10.2307/1266427. Accessed 18 May 2022.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> x2 = rng.standard_normal((2, 45, 6, 7))
        >>> x1 = rng.standard_normal((2, 30, 6, 7))
        >>> res = stats.mood(x1, x2, axis=1)
        >>> res.pvalue.shape
        (2, 6, 7)

        Find the number of points where the difference in scale is not significant:

        >>> (res.pvalue > 0.1).sum()
        78

        Perform the test with different scales:

        >>> x1 = rng.standard_normal((2, 30))
        >>> x2 = rng.standard_normal((2, 35)) * 10.0
        >>> stats.mood(x1, x2, axis=1)
        SignificanceResult(statistic=array([-5.76174136, -6.12650783]),
                           pvalue=array([8.32505043e-09, 8.98287869e-10]))

    multiscale_graphcorr(x, y, compute_distance=<function _euclidean_dist at 0x000001D8F3250E00>, reps=1000, workers=1, is_twosamp=False, random_state=None)
        Computes the Multiscale Graph Correlation (MGC) test statistic.

        Specifically, for each point, MGC finds the :math:`k`-nearest neighbors for
        one property (e.g. cloud density), and the :math:`l`-nearest neighbors for
        the other property (e.g. grass wetness) [1]_. This pair :math:`(k, l)` is
        called the "scale". A priori, however, it is not know which scales will be
        most informative. So, MGC computes all distance pairs, and then efficiently
        computes the distance correlations for all scales. The local correlations
        illustrate which scales are relatively informative about the relationship.
        The key, therefore, to successfully discover and decipher relationships
        between disparate data modalities is to adaptively determine which scales
        are the most informative, and the geometric implication for the most
        informative scales. Doing so not only provides an estimate of whether the
        modalities are related, but also provides insight into how the
        determination was made. This is especially important in high-dimensional
        data, where simple visualizations do not reveal relationships to the
        unaided human eye. Characterizations of this implementation in particular
        have been derived from and benchmarked within in [2]_.

        Parameters
        ----------
        x, y : ndarray
            If ``x`` and ``y`` have shapes ``(n, p)`` and ``(n, q)`` where `n` is
            the number of samples and `p` and `q` are the number of dimensions,
            then the MGC independence test will be run.  Alternatively, ``x`` and
            ``y`` can have shapes ``(n, n)`` if they are distance or similarity
            matrices, and ``compute_distance`` must be sent to ``None``. If ``x``
            and ``y`` have shapes ``(n, p)`` and ``(m, p)``, an unpaired
            two-sample MGC test will be run.
        compute_distance : callable, optional
            A function that computes the distance or similarity among the samples
            within each data matrix. Set to ``None`` if ``x`` and ``y`` are
            already distance matrices. The default uses the euclidean norm metric.
            If you are calling a custom function, either create the distance
            matrix before-hand or create a function of the form
            ``compute_distance(x)`` where `x` is the data matrix for which
            pairwise distances are calculated.
        reps : int, optional
            The number of replications used to estimate the null when using the
            permutation test. The default is ``1000``.
        workers : int or map-like callable, optional
            If ``workers`` is an int the population is subdivided into ``workers``
            sections and evaluated in parallel (uses ``multiprocessing.Pool
            <multiprocessing>``). Supply ``-1`` to use all cores available to the
            Process. Alternatively supply a map-like callable, such as
            ``multiprocessing.Pool.map`` for evaluating the p-value in parallel.
            This evaluation is carried out as ``workers(func, iterable)``.
            Requires that `func` be pickleable. The default is ``1``.
        is_twosamp : bool, optional
            If `True`, a two sample test will be run. If ``x`` and ``y`` have
            shapes ``(n, p)`` and ``(m, p)``, this optional will be overridden and
            set to ``True``. Set to ``True`` if ``x`` and ``y`` both have shapes
            ``(n, p)`` and a two sample test is desired. The default is ``False``.
            Note that this will not run if inputs are distance matrices.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

        Returns
        -------
        res : MGCResult
            An object containing attributes:

            statistic : float
                The sample MGC test statistic within `[-1, 1]`.
            pvalue : float
                The p-value obtained via permutation.
            mgc_dict : dict
                Contains additional useful results:

                    - mgc_map : ndarray
                        A 2D representation of the latent geometry of the
                        relationship.
                    - opt_scale : (int, int)
                        The estimated optimal scale as a `(x, y)` pair.
                    - null_dist : list
                        The null distribution derived from the permuted matrices.

        See Also
        --------
        pearsonr : Pearson correlation coefficient and p-value for testing
                   non-correlation.
        kendalltau : Calculates Kendall's tau.
        spearmanr : Calculates a Spearman rank-order correlation coefficient.

        Notes
        -----
        A description of the process of MGC and applications on neuroscience data
        can be found in [1]_. It is performed using the following steps:

        #. Two distance matrices :math:`D^X` and :math:`D^Y` are computed and
           modified to be mean zero columnwise. This results in two
           :math:`n \times n` distance matrices :math:`A` and :math:`B` (the
           centering and unbiased modification) [3]_.

        #. For all values :math:`k` and :math:`l` from :math:`1, ..., n`,

           * The :math:`k`-nearest neighbor and :math:`l`-nearest neighbor graphs
             are calculated for each property. Here, :math:`G_k (i, j)` indicates
             the :math:`k`-smallest values of the :math:`i`-th row of :math:`A`
             and :math:`H_l (i, j)` indicates the :math:`l` smallested values of
             the :math:`i`-th row of :math:`B`

           * Let :math:`\circ` denotes the entry-wise matrix product, then local
             correlations are summed and normalized using the following statistic:

        .. math::

            c^{kl} = \frac{\sum_{ij} A G_k B H_l}
                          {\sqrt{\sum_{ij} A^2 G_k \times \sum_{ij} B^2 H_l}}

        #. The MGC test statistic is the smoothed optimal local correlation of
           :math:`\{ c^{kl} \}`. Denote the smoothing operation as :math:`R(\cdot)`
           (which essentially set all isolated large correlations) as 0 and
           connected large correlations the same as before, see [3]_.) MGC is,

        .. math::

            MGC_n (x, y) = \max_{(k, l)} R \left(c^{kl} \left( x_n, y_n \right)
                                                        \right)

        The test statistic returns a value between :math:`(-1, 1)` since it is
        normalized.

        The p-value returned is calculated using a permutation test. This process
        is completed by first randomly permuting :math:`y` to estimate the null
        distribution and then calculating the probability of observing a test
        statistic, under the null, at least as extreme as the observed test
        statistic.

        MGC requires at least 5 samples to run with reliable results. It can also
        handle high-dimensional data sets.
        In addition, by manipulating the input data matrices, the two-sample
        testing problem can be reduced to the independence testing problem [4]_.
        Given sample data :math:`U` and :math:`V` of sizes :math:`p \times n`
        :math:`p \times m`, data matrix :math:`X` and :math:`Y` can be created as
        follows:

        .. math::

            X = [U | V] \in \mathcal{R}^{p \times (n + m)}
            Y = [0_{1 \times n} | 1_{1 \times m}] \in \mathcal{R}^{(n + m)}

        Then, the MGC statistic can be calculated as normal. This methodology can
        be extended to similar tests such as distance correlation [4]_.

        .. versionadded:: 1.4.0

        References
        ----------
        .. [1] Vogelstein, J. T., Bridgeford, E. W., Wang, Q., Priebe, C. E.,
               Maggioni, M., & Shen, C. (2019). Discovering and deciphering
               relationships across disparate data modalities. ELife.
        .. [2] Panda, S., Palaniappan, S., Xiong, J., Swaminathan, A.,
               Ramachandran, S., Bridgeford, E. W., ... Vogelstein, J. T. (2019).
               mgcpy: A Comprehensive High Dimensional Independence Testing Python
               Package. :arXiv:`1907.02088`
        .. [3] Shen, C., Priebe, C.E., & Vogelstein, J. T. (2019). From distance
               correlation to multiscale graph correlation. Journal of the American
               Statistical Association.
        .. [4] Shen, C. & Vogelstein, J. T. (2018). The Exact Equivalence of
               Distance and Kernel Methods for Hypothesis Testing.
               :arXiv:`1806.05514`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import multiscale_graphcorr
        >>> x = np.arange(100)
        >>> y = x
        >>> res = multiscale_graphcorr(x, y)
        >>> res.statistic, res.pvalue
        (1.0, 0.001)

        To run an unpaired two-sample test,

        >>> x = np.arange(100)
        >>> y = np.arange(79)
        >>> res = multiscale_graphcorr(x, y)
        >>> res.statistic, res.pvalue  # doctest: +SKIP
        (0.033258146255703246, 0.023)

        or, if shape of the inputs are the same,

        >>> x = np.arange(100)
        >>> y = x
        >>> res = multiscale_graphcorr(x, y, is_twosamp=True)
        >>> res.statistic, res.pvalue  # doctest: +SKIP
        (-0.008021809890200488, 1.0)

    mvsdist(data)
        'Frozen' distributions for mean, variance, and standard deviation of data.

        Parameters
        ----------
        data : array_like
            Input array. Converted to 1-D using ravel.
            Requires 2 or more data-points.

        Returns
        -------
        mdist : "frozen" distribution object
            Distribution object representing the mean of the data.
        vdist : "frozen" distribution object
            Distribution object representing the variance of the data.
        sdist : "frozen" distribution object
            Distribution object representing the standard deviation of the data.

        See Also
        --------
        bayes_mvs

        Notes
        -----
        The return values from ``bayes_mvs(data)`` is equivalent to
        ``tuple((x.mean(), x.interval(0.90)) for x in mvsdist(data))``.

        In other words, calling ``<dist>.mean()`` and ``<dist>.interval(0.90)``
        on the three distribution objects returned from this function will give
        the same results that are returned from `bayes_mvs`.

        References
        ----------
        T.E. Oliphant, "A Bayesian perspective on estimating mean, variance, and
        standard-deviation from data", https://scholarsarchive.byu.edu/facpub/278,
        2006.

        Examples
        --------
        >>> from scipy import stats
        >>> data = [6, 9, 12, 7, 8, 8, 13]
        >>> mean, var, std = stats.mvsdist(data)

        We now have frozen distribution objects "mean", "var" and "std" that we can
        examine:

        >>> mean.mean()
        9.0
        >>> mean.interval(0.95)
        (6.6120585482655692, 11.387941451734431)
        >>> mean.std()
        1.1952286093343936

    normaltest(a, axis=0, nan_policy='propagate', *, keepdims=False)
        Test whether a sample differs from a normal distribution.

        This function tests the null hypothesis that a sample comes
        from a normal distribution.  It is based on D'Agostino and
        Pearson's [1]_, [2]_ test that combines skew and kurtosis to
        produce an omnibus test of normality.

        Parameters
        ----------
        a : array_like
            The array containing the sample to be tested. Must contain
            at least eight observations.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float or array
            ``s^2 + k^2``, where ``s`` is the z-score returned by `skewtest` and
            ``k`` is the z-score returned by `kurtosistest`.
        pvalue : float or array
            A 2-sided chi squared probability for the hypothesis test.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] D'Agostino, R. B. (1971), "An omnibus test of normality for
               moderate and large sample size", Biometrika, 58, 341-348
        .. [2] D'Agostino, R. and Pearson, E. S. (1973), "Tests for departure from
               normality", Biometrika, 60, 613-622
        .. [3] Shapiro, S. S., & Wilk, M. B. (1965). An analysis of variance test
               for normality (complete samples). Biometrika, 52(3/4), 591-611.
        .. [4] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).
        .. [5] Panagiotakos, D. B. (2008). The value of p-value in biomedical
               research. The open cardiovascular medicine journal, 2, 97.

        Examples
        --------
        Suppose we wish to infer from measurements whether the weights of adult
        human males in a medical study are not normally distributed [3]_.
        The weights (lbs) are recorded in the array ``x`` below.

        >>> import numpy as np
        >>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

        The normality test of [1]_ and [2]_ begins by computing a statistic based
        on the sample skewness and kurtosis.

        >>> from scipy import stats
        >>> res = stats.normaltest(x)
        >>> res.statistic
        13.034263121192582

        (The test warns that our sample has too few observations to perform the
        test. We'll return to this at the end of the example.)
        Because the normal distribution has zero skewness and zero
        ("excess" or "Fisher") kurtosis, the value of this statistic tends to be
        low for samples drawn from a normal distribution.

        The test is performed by comparing the observed value of the statistic
        against the null distribution: the distribution of statistic values derived
        under the null hypothesis that the weights were drawn from a normal
        distribution.
        For this normality test, the null distribution for very large samples is
        the chi-squared distribution with two degrees of freedom.

        >>> import matplotlib.pyplot as plt
        >>> dist = stats.chi2(df=2)
        >>> stat_vals = np.linspace(0, 16, 100)
        >>> pdf = dist.pdf(stat_vals)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(stat_vals, pdf)
        ...     ax.set_title("Normality Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution greater than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (13.5, 5e-4), (14, 5e-3), arrowprops=props)
        >>> i = stat_vals >= res.statistic  # index more extreme statistic values
        >>> ax.fill_between(stat_vals[i], y1=0, y2=pdf[i])
        >>> ax.set_xlim(8, 16)
        >>> ax.set_ylim(0, 0.01)
        >>> plt.show()
        >>> res.pvalue
        0.0014779023013100172

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from a normally distributed population that produces such an
        extreme value of the statistic - this may be taken as evidence against
        the null hypothesis in favor of the alternative: the weights were not
        drawn from a normal distribution. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [4]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).

        Note that the chi-squared distribution provides an asymptotic
        approximation of the null distribution; it is only accurate for samples
        with many observations. This is the reason we received a warning at the
        beginning of the example; our sample is quite small. In this case,
        `scipy.stats.monte_carlo_test` may provide a more accurate, albeit
        stochastic, approximation of the exact p-value.

        >>> def statistic(x, axis):
        ...     # Get only the `normaltest` statistic; ignore approximate p-value
        ...     return stats.normaltest(x, axis=axis).statistic
        >>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
        ...                              alternative='greater')
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> ax.hist(res.null_distribution, np.linspace(0, 25, 50),
        ...         density=True)
        >>> ax.legend(['aymptotic approximation (many observations)',
        ...            'Monte Carlo approximation (11 observations)'])
        >>> ax.set_xlim(0, 14)
        >>> plt.show()
        >>> res.pvalue
        0.0082  # may vary

        Furthermore, despite their stochastic nature, p-values computed in this way
        can be used to exactly control the rate of false rejections of the null
        hypothesis [5]_.

    obrientransform(*samples)
        Compute the O'Brien transform on input data (any number of arrays).

        Used to test for homogeneity of variance prior to running one-way stats.
        Each array in ``*samples`` is one level of a factor.
        If `f_oneway` is run on the transformed data and found significant,
        the variances are unequal.  From Maxwell and Delaney [1]_, p.112.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            Any number of arrays.

        Returns
        -------
        obrientransform : ndarray
            Transformed data for use in an ANOVA.  The first dimension
            of the result corresponds to the sequence of transformed
            arrays.  If the arrays given are all 1-D of the same length,
            the return value is a 2-D array; otherwise it is a 1-D array
            of type object, with each element being an ndarray.

        References
        ----------
        .. [1] S. E. Maxwell and H. D. Delaney, "Designing Experiments and
               Analyzing Data: A Model Comparison Perspective", Wadsworth, 1990.

        Examples
        --------
        We'll test the following data sets for differences in their variance.

        >>> x = [10, 11, 13, 9, 7, 12, 12, 9, 10]
        >>> y = [13, 21, 5, 10, 8, 14, 10, 12, 7, 15]

        Apply the O'Brien transform to the data.

        >>> from scipy.stats import obrientransform
        >>> tx, ty = obrientransform(x, y)

        Use `scipy.stats.f_oneway` to apply a one-way ANOVA test to the
        transformed data.

        >>> from scipy.stats import f_oneway
        >>> F, p = f_oneway(tx, ty)
        >>> p
        0.1314139477040335

        If we require that ``p < 0.05`` for significance, we cannot conclude
        that the variances are different.

    page_trend_test(data, ranked=False, predicted_ranks=None, method='auto')
        Perform Page's Test, a measure of trend in observations between treatments.

        Page's Test (also known as Page's :math:`L` test) is useful when:

        * there are :math:`n \geq 3` treatments,
        * :math:`m \geq 2` subjects are observed for each treatment, and
        * the observations are hypothesized to have a particular order.

        Specifically, the test considers the null hypothesis that

        .. math::

            m_1 = m_2 = m_3 \cdots = m_n,

        where :math:`m_j` is the mean of the observed quantity under treatment
        :math:`j`, against the alternative hypothesis that

        .. math::

            m_1 \leq m_2 \leq m_3 \leq \cdots \leq m_n,

        where at least one inequality is strict.

        As noted by [4]_, Page's :math:`L` test has greater statistical power than
        the Friedman test against the alternative that there is a difference in
        trend, as Friedman's test only considers a difference in the means of the
        observations without considering their order. Whereas Spearman :math:`\rho`
        considers the correlation between the ranked observations of two variables
        (e.g. the airspeed velocity of a swallow vs. the weight of the coconut it
        carries), Page's :math:`L` is concerned with a trend in an observation
        (e.g. the airspeed velocity of a swallow) across several distinct
        treatments (e.g. carrying each of five coconuts of different weight) even
        as the observation is repeated with multiple subjects (e.g. one European
        swallow and one African swallow).

        Parameters
        ----------
        data : array-like
            A :math:`m \times n` array; the element in row :math:`i` and
            column :math:`j` is the observation corresponding with subject
            :math:`i` and treatment :math:`j`. By default, the columns are
            assumed to be arranged in order of increasing predicted mean.

        ranked : boolean, optional
            By default, `data` is assumed to be observations rather than ranks;
            it will be ranked with `scipy.stats.rankdata` along ``axis=1``. If
            `data` is provided in the form of ranks, pass argument ``True``.

        predicted_ranks : array-like, optional
            The predicted ranks of the column means. If not specified,
            the columns are assumed to be arranged in order of increasing
            predicted mean, so the default `predicted_ranks` are
            :math:`[1, 2, \dots, n-1, n]`.

        method : {'auto', 'asymptotic', 'exact'}, optional
            Selects the method used to calculate the *p*-value. The following
            options are available.

            * 'auto': selects between 'exact' and 'asymptotic' to
              achieve reasonably accurate results in reasonable time (default)
            * 'asymptotic': compares the standardized test statistic against
              the normal distribution
            * 'exact': computes the exact *p*-value by comparing the observed
              :math:`L` statistic against those realized by all possible
              permutations of ranks (under the null hypothesis that each
              permutation is equally likely)

        Returns
        -------
        res : PageTrendTestResult
            An object containing attributes:

            statistic : float
                Page's :math:`L` test statistic.
            pvalue : float
                The associated *p*-value
            method : {'asymptotic', 'exact'}
                The method used to compute the *p*-value

        See Also
        --------
        rankdata, friedmanchisquare, spearmanr

        Notes
        -----
        As noted in [1]_, "the :math:`n` 'treatments' could just as well represent
        :math:`n` objects or events or performances or persons or trials ranked."
        Similarly, the :math:`m` 'subjects' could equally stand for :math:`m`
        "groupings by ability or some other control variable, or judges doing
        the ranking, or random replications of some other sort."

        The procedure for calculating the :math:`L` statistic, adapted from
        [1]_, is:

        1. "Predetermine with careful logic the appropriate hypotheses
           concerning the predicted ordering of the experimental results.
           If no reasonable basis for ordering any treatments is known, the
           :math:`L` test is not appropriate."
        2. "As in other experiments, determine at what level of confidence
           you will reject the null hypothesis that there is no agreement of
           experimental results with the monotonic hypothesis."
        3. "Cast the experimental material into a two-way table of :math:`n`
           columns (treatments, objects ranked, conditions) and :math:`m`
           rows (subjects, replication groups, levels of control variables)."
        4. "When experimental observations are recorded, rank them across each
           row", e.g. ``ranks = scipy.stats.rankdata(data, axis=1)``.
        5. "Add the ranks in each column", e.g.
           ``colsums = np.sum(ranks, axis=0)``.
        6. "Multiply each sum of ranks by the predicted rank for that same
           column", e.g. ``products = predicted_ranks * colsums``.
        7. "Sum all such products", e.g. ``L = products.sum()``.

        [1]_ continues by suggesting use of the standardized statistic

        .. math::

            \chi_L^2 = \frac{\left[12L-3mn(n+1)^2\right]^2}{mn^2(n^2-1)(n+1)}

        "which is distributed approximately as chi-square with 1 degree of
        freedom. The ordinary use of :math:`\chi^2` tables would be
        equivalent to a two-sided test of agreement. If a one-sided test
        is desired, *as will almost always be the case*, the probability
        discovered in the chi-square table should be *halved*."

        However, this standardized statistic does not distinguish between the
        observed values being well correlated with the predicted ranks and being
        _anti_-correlated with the predicted ranks. Instead, we follow [2]_
        and calculate the standardized statistic

        .. math::

            \Lambda = \frac{L - E_0}{\sqrt{V_0}},

        where :math:`E_0 = \frac{1}{4} mn(n+1)^2` and
        :math:`V_0 = \frac{1}{144} mn^2(n+1)(n^2-1)`, "which is asymptotically
        normal under the null hypothesis".

        The *p*-value for ``method='exact'`` is generated by comparing the observed
        value of :math:`L` against the :math:`L` values generated for all
        :math:`(n!)^m` possible permutations of ranks. The calculation is performed
        using the recursive method of [5].

        The *p*-values are not adjusted for the possibility of ties. When
        ties are present, the reported  ``'exact'`` *p*-values may be somewhat
        larger (i.e. more conservative) than the true *p*-value [2]_. The
        ``'asymptotic'``` *p*-values, however, tend to be smaller (i.e. less
        conservative) than the ``'exact'`` *p*-values.

        References
        ----------
        .. [1] Ellis Batten Page, "Ordered hypotheses for multiple treatments:
           a significant test for linear ranks", *Journal of the American
           Statistical Association* 58(301), p. 216--230, 1963.

        .. [2] Markus Neuhauser, *Nonparametric Statistical Test: A computational
           approach*, CRC Press, p. 150--152, 2012.

        .. [3] Statext LLC, "Page's L Trend Test - Easy Statistics", *Statext -
           Statistics Study*, https://www.statext.com/practice/PageTrendTest03.php,
           Accessed July 12, 2020.

        .. [4] "Page's Trend Test", *Wikipedia*, WikimediaFoundation,
           https://en.wikipedia.org/wiki/Page%27s_trend_test,
           Accessed July 12, 2020.

        .. [5] Robert E. Odeh, "The exact distribution of Page's L-statistic in
           the two-way layout", *Communications in Statistics - Simulation and
           Computation*,  6(1), p. 49--61, 1977.

        Examples
        --------
        We use the example from [3]_: 10 students are asked to rate three
        teaching methods - tutorial, lecture, and seminar - on a scale of 1-5,
        with 1 being the lowest and 5 being the highest. We have decided that
        a confidence level of 99% is required to reject the null hypothesis in
        favor of our alternative: that the seminar will have the highest ratings
        and the tutorial will have the lowest. Initially, the data have been
        tabulated with each row representing an individual student's ratings of
        the three methods in the following order: tutorial, lecture, seminar.

        >>> table = [[3, 4, 3],
        ...          [2, 2, 4],
        ...          [3, 3, 5],
        ...          [1, 3, 2],
        ...          [2, 3, 2],
        ...          [2, 4, 5],
        ...          [1, 2, 4],
        ...          [3, 4, 4],
        ...          [2, 4, 5],
        ...          [1, 3, 4]]

        Because the tutorial is hypothesized to have the lowest ratings, the
        column corresponding with tutorial rankings should be first; the seminar
        is hypothesized to have the highest ratings, so its column should be last.
        Since the columns are already arranged in this order of increasing
        predicted mean, we can pass the table directly into `page_trend_test`.

        >>> from scipy.stats import page_trend_test
        >>> res = page_trend_test(table)
        >>> res
        PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                            method='exact')

        This *p*-value indicates that there is a 0.1819% chance that
        the :math:`L` statistic would reach such an extreme value under the null
        hypothesis. Because 0.1819% is less than 1%, we have evidence to reject
        the null hypothesis in favor of our alternative at a 99% confidence level.

        The value of the :math:`L` statistic is 133.5. To check this manually,
        we rank the data such that high scores correspond with high ranks, settling
        ties with an average rank:

        >>> from scipy.stats import rankdata
        >>> ranks = rankdata(table, axis=1)
        >>> ranks
        array([[1.5, 3. , 1.5],
               [1.5, 1.5, 3. ],
               [1.5, 1.5, 3. ],
               [1. , 3. , 2. ],
               [1.5, 3. , 1.5],
               [1. , 2. , 3. ],
               [1. , 2. , 3. ],
               [1. , 2.5, 2.5],
               [1. , 2. , 3. ],
               [1. , 2. , 3. ]])

        We add the ranks within each column, multiply the sums by the
        predicted ranks, and sum the products.

        >>> import numpy as np
        >>> m, n = ranks.shape
        >>> predicted_ranks = np.arange(1, n+1)
        >>> L = (predicted_ranks * np.sum(ranks, axis=0)).sum()
        >>> res.statistic == L
        True

        As presented in [3]_, the asymptotic approximation of the *p*-value is the
        survival function of the normal distribution evaluated at the standardized
        test statistic:

        >>> from scipy.stats import norm
        >>> E0 = (m*n*(n+1)**2)/4
        >>> V0 = (m*n**2*(n+1)*(n**2-1))/144
        >>> Lambda = (L-E0)/np.sqrt(V0)
        >>> p = norm.sf(Lambda)
        >>> p
        0.0012693433690751756

        This does not precisely match the *p*-value reported by `page_trend_test`
        above. The asymptotic distribution is not very accurate, nor conservative,
        for :math:`m \leq 12` and :math:`n \leq 8`, so `page_trend_test` chose to
        use ``method='exact'`` based on the dimensions of the table and the
        recommendations in Page's original paper [1]_. To override
        `page_trend_test`'s choice, provide the `method` argument.

        >>> res = page_trend_test(table, method="asymptotic")
        >>> res
        PageTrendTestResult(statistic=133.5, pvalue=0.0012693433690751756,
                            method='asymptotic')

        If the data are already ranked, we can pass in the ``ranks`` instead of
        the ``table`` to save computation time.

        >>> res = page_trend_test(ranks,             # ranks of data
        ...                       ranked=True,       # data is already ranked
        ...                       )
        >>> res
        PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                            method='exact')

        Suppose the raw data had been tabulated in an order different from the
        order of predicted means, say lecture, seminar, tutorial.

        >>> table = np.asarray(table)[:, [1, 2, 0]]

        Since the arrangement of this table is not consistent with the assumed
        ordering, we can either rearrange the table or provide the
        `predicted_ranks`. Remembering that the lecture is predicted
        to have the middle rank, the seminar the highest, and tutorial the lowest,
        we pass:

        >>> res = page_trend_test(table,             # data as originally tabulated
        ...                       predicted_ranks=[2, 3, 1],  # our predicted order
        ...                       )
        >>> res
        PageTrendTestResult(statistic=133.5, pvalue=0.0018191161948127822,
                            method='exact')

    pearsonr(x, y, *, alternative='two-sided', method=None, axis=0)
        Pearson correlation coefficient and p-value for testing non-correlation.

        The Pearson correlation coefficient [1]_ measures the linear relationship
        between two datasets. Like other correlation
        coefficients, this one varies between -1 and +1 with 0 implying no
        correlation. Correlations of -1 or +1 imply an exact linear relationship.
        Positive correlations imply that as x increases, so does y. Negative
        correlations imply that as x increases, y decreases.

        This function also performs a test of the null hypothesis that the
        distributions underlying the samples are uncorrelated and normally
        distributed. (See Kowalski [3]_
        for a discussion of the effects of non-normality of the input on the
        distribution of the correlation coefficient.)
        The p-value roughly indicates the probability of an uncorrelated system
        producing datasets that have a Pearson correlation at least as extreme
        as the one computed from these datasets.

        Parameters
        ----------
        x : array_like
            Input array.
        y : array_like
            Input array.
        axis : int or None, default
            Axis along which to perform the calculation. Default is 0.
            If None, ravel both arrays before performing the calculation.

            .. versionadded:: 1.13.0
        alternative : {'two-sided', 'greater', 'less'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the correlation is nonzero
            * 'less': the correlation is negative (less than zero)
            * 'greater':  the correlation is positive (greater than zero)

            .. versionadded:: 1.9.0
        method : ResamplingMethod, optional
            Defines the method used to compute the p-value. If `method` is an
            instance of `PermutationMethod`/`MonteCarloMethod`, the p-value is
            computed using
            `scipy.stats.permutation_test`/`scipy.stats.monte_carlo_test` with the
            provided configuration options and other appropriate settings.
            Otherwise, the p-value is computed as documented in the notes.

            .. versionadded:: 1.11.0

        Returns
        -------
        result : `~scipy.stats._result_classes.PearsonRResult`
            An object with the following attributes:

            statistic : float
                Pearson product-moment correlation coefficient.
            pvalue : float
                The p-value associated with the chosen alternative.

            The object has the following method:

            confidence_interval(confidence_level, method)
                This computes the confidence interval of the correlation
                coefficient `statistic` for the given confidence level.
                The confidence interval is returned in a ``namedtuple`` with
                fields `low` and `high`. If `method` is not provided, the
                confidence interval is computed using the Fisher transformation
                [1]_. If `method` is an instance of `BootstrapMethod`, the
                confidence interval is computed using `scipy.stats.bootstrap` with
                the provided configuration options and other appropriate settings.
                In some cases, confidence limits may be NaN due to a degenerate
                resample, and this is typical for very small samples (~6
                observations).

        Warns
        -----
        `~scipy.stats.ConstantInputWarning`
            Raised if an input is a constant array.  The correlation coefficient
            is not defined in this case, so ``np.nan`` is returned.

        `~scipy.stats.NearConstantInputWarning`
            Raised if an input is "nearly" constant.  The array ``x`` is considered
            nearly constant if ``norm(x - mean(x)) < 1e-13 * abs(mean(x))``.
            Numerical errors in the calculation ``x - mean(x)`` in this case might
            result in an inaccurate calculation of r.

        See Also
        --------
        spearmanr : Spearman rank-order correlation coefficient.
        kendalltau : Kendall's tau, a correlation measure for ordinal data.

        Notes
        -----
        The correlation coefficient is calculated as follows:

        .. math::

            r = \frac{\sum (x - m_x) (y - m_y)}
                     {\sqrt{\sum (x - m_x)^2 \sum (y - m_y)^2}}

        where :math:`m_x` is the mean of the vector x and :math:`m_y` is
        the mean of the vector y.

        Under the assumption that x and y are drawn from
        independent normal distributions (so the population correlation coefficient
        is 0), the probability density function of the sample correlation
        coefficient r is ([1]_, [2]_):

        .. math::
            f(r) = \frac{{(1-r^2)}^{n/2-2}}{\mathrm{B}(\frac{1}{2},\frac{n}{2}-1)}

        where n is the number of samples, and B is the beta function.  This
        is sometimes referred to as the exact distribution of r.  This is
        the distribution that is used in `pearsonr` to compute the p-value when
        the `method` parameter is left at its default value (None).
        The distribution is a beta distribution on the interval [-1, 1],
        with equal shape parameters a = b = n/2 - 1.  In terms of SciPy's
        implementation of the beta distribution, the distribution of r is::

            dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)

        The default p-value returned by `pearsonr` is a two-sided p-value. For a
        given sample with correlation coefficient r, the p-value is
        the probability that abs(r') of a random sample x' and y' drawn from
        the population with zero correlation would be greater than or equal
        to abs(r). In terms of the object ``dist`` shown above, the p-value
        for a given r and length n can be computed as::

            p = 2*dist.cdf(-abs(r))

        When n is 2, the above continuous distribution is not well-defined.
        One can interpret the limit of the beta distribution as the shape
        parameters a and b approach a = b = 0 as a discrete distribution with
        equal probability masses at r = 1 and r = -1.  More directly, one
        can observe that, given the data x = [x1, x2] and y = [y1, y2], and
        assuming x1 != x2 and y1 != y2, the only possible values for r are 1
        and -1.  Because abs(r') for any sample x' and y' with length 2 will
        be 1, the two-sided p-value for a sample of length 2 is always 1.

        For backwards compatibility, the object that is returned also behaves
        like a tuple of length two that holds the statistic and the p-value.

        References
        ----------
        .. [1] "Pearson correlation coefficient", Wikipedia,
               https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
        .. [2] Student, "Probable error of a correlation coefficient",
               Biometrika, Volume 6, Issue 2-3, 1 September 1908, pp. 302-310.
        .. [3] C. J. Kowalski, "On the Effects of Non-Normality on the Distribution
               of the Sample Product-Moment Correlation Coefficient"
               Journal of the Royal Statistical Society. Series C (Applied
               Statistics), Vol. 21, No. 1 (1972), pp. 1-12.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x, y = [1, 2, 3, 4, 5, 6, 7], [10, 9, 2.5, 6, 4, 3, 2]
        >>> res = stats.pearsonr(x, y)
        >>> res
        PearsonRResult(statistic=-0.828503883588428, pvalue=0.021280260007523286)

        To perform an exact permutation version of the test:

        >>> rng = np.random.default_rng(7796654889291491997)
        >>> method = stats.PermutationMethod(n_resamples=np.inf, random_state=rng)
        >>> stats.pearsonr(x, y, method=method)
        PearsonRResult(statistic=-0.828503883588428, pvalue=0.028174603174603175)

        To perform the test under the null hypothesis that the data were drawn from
        *uniform* distributions:

        >>> method = stats.MonteCarloMethod(rvs=(rng.uniform, rng.uniform))
        >>> stats.pearsonr(x, y, method=method)
        PearsonRResult(statistic=-0.828503883588428, pvalue=0.0188)

        To produce an asymptotic 90% confidence interval:

        >>> res.confidence_interval(confidence_level=0.9)
        ConfidenceInterval(low=-0.9644331982722841, high=-0.3460237473272273)

        And for a bootstrap confidence interval:

        >>> method = stats.BootstrapMethod(method='BCa', random_state=rng)
        >>> res.confidence_interval(confidence_level=0.9, method=method)
        ConfidenceInterval(low=-0.9983163756488651, high=-0.22771001702132443)  # may vary

        If N-dimensional arrays are provided, multiple tests are performed in a
        single call according to the same conventions as most `scipy.stats` functions:

        >>> rng = np.random.default_rng(2348246935601934321)
        >>> x = rng.standard_normal((8, 15))
        >>> y = rng.standard_normal((8, 15))
        >>> stats.pearsonr(x, y, axis=0).statistic.shape  # between corresponding columns
        (15,)
        >>> stats.pearsonr(x, y, axis=1).statistic.shape  # between corresponding rows
        (8,)

        To perform all pairwise comparisons between slices of the arrays,
        use standard NumPy broadcasting techniques. For instance, to compute the
        correlation between all pairs of rows:

        >>> stats.pearsonr(x[:, np.newaxis, :], y, axis=-1).statistic.shape
        (8, 8)

        There is a linear dependence between x and y if y = a + b*x + e, where
        a,b are constants and e is a random error term, assumed to be independent
        of x. For simplicity, assume that x is standard normal, a=0, b=1 and let
        e follow a normal distribution with mean zero and standard deviation s>0.

        >>> rng = np.random.default_rng()
        >>> s = 0.5
        >>> x = stats.norm.rvs(size=500, random_state=rng)
        >>> e = stats.norm.rvs(scale=s, size=500, random_state=rng)
        >>> y = x + e
        >>> stats.pearsonr(x, y).statistic
        0.9001942438244763

        This should be close to the exact value given by

        >>> 1/np.sqrt(1 + s**2)
        0.8944271909999159

        For s=0.5, we observe a high level of correlation. In general, a large
        variance of the noise reduces the correlation, while the correlation
        approaches one as the variance of the error goes to zero.

        It is important to keep in mind that no correlation does not imply
        independence unless (x, y) is jointly normal. Correlation can even be zero
        when there is a very simple dependence structure: if X follows a
        standard normal distribution, let y = abs(x). Note that the correlation
        between x and y is zero. Indeed, since the expectation of x is zero,
        cov(x, y) = E[x*y]. By definition, this equals E[x*abs(x)] which is zero
        by symmetry. The following lines of code illustrate this observation:

        >>> y = np.abs(x)
        >>> stats.pearsonr(x, y)
        PearsonRResult(statistic=-0.05444919272687482, pvalue=0.22422294836207743)

        A non-zero correlation coefficient can be misleading. For example, if X has
        a standard normal distribution, define y = x if x < 0 and y = 0 otherwise.
        A simple calculation shows that corr(x, y) = sqrt(2/Pi) = 0.797...,
        implying a high level of correlation:

        >>> y = np.where(x < 0, x, 0)
        >>> stats.pearsonr(x, y)
        PearsonRResult(statistic=0.861985781588, pvalue=4.813432002751103e-149)

        This is unintuitive since there is no dependence of x and y if x is larger
        than zero which happens in about half of the cases if we sample x and y.

    percentileofscore(a, score, kind='rank', nan_policy='propagate')
        Compute the percentile rank of a score relative to a list of scores.

        A `percentileofscore` of, for example, 80% means that 80% of the
        scores in `a` are below the given score. In the case of gaps or
        ties, the exact definition depends on the optional keyword, `kind`.

        Parameters
        ----------
        a : array_like
            A 1-D array to which `score` is compared.
        score : array_like
            Scores to compute percentiles for.
        kind : {'rank', 'weak', 'strict', 'mean'}, optional
            Specifies the interpretation of the resulting score.
            The following options are available (default is 'rank'):

              * 'rank': Average percentage ranking of score.  In case of multiple
                matches, average the percentage rankings of all matching scores.
              * 'weak': This kind corresponds to the definition of a cumulative
                distribution function.  A percentileofscore of 80% means that 80%
                of values are less than or equal to the provided score.
              * 'strict': Similar to "weak", except that only values that are
                strictly less than the given score are counted.
              * 'mean': The average of the "weak" and "strict" scores, often used
                in testing.  See https://en.wikipedia.org/wiki/Percentile_rank
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Specifies how to treat `nan` values in `a`.
            The following options are available (default is 'propagate'):

              * 'propagate': returns nan (for each value in `score`).
              * 'raise': throws an error
              * 'omit': performs the calculations ignoring nan values

        Returns
        -------
        pcos : float
            Percentile-position of score (0-100) relative to `a`.

        See Also
        --------
        numpy.percentile
        scipy.stats.scoreatpercentile, scipy.stats.rankdata

        Examples
        --------
        Three-quarters of the given values lie below a given score:

        >>> import numpy as np
        >>> from scipy import stats
        >>> stats.percentileofscore([1, 2, 3, 4], 3)
        75.0

        With multiple matches, note how the scores of the two matches, 0.6
        and 0.8 respectively, are averaged:

        >>> stats.percentileofscore([1, 2, 3, 3, 4], 3)
        70.0

        Only 2/5 values are strictly less than 3:

        >>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='strict')
        40.0

        But 4/5 values are less than or equal to 3:

        >>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='weak')
        80.0

        The average between the weak and the strict scores is:

        >>> stats.percentileofscore([1, 2, 3, 3, 4], 3, kind='mean')
        60.0

        Score arrays (of any dimensionality) are supported:

        >>> stats.percentileofscore([1, 2, 3, 3, 4], [2, 3])
        array([40., 70.])

        The inputs can be infinite:

        >>> stats.percentileofscore([-np.inf, 0, 1, np.inf], [1, 2, np.inf])
        array([75., 75., 100.])

        If `a` is empty, then the resulting percentiles are all `nan`:

        >>> stats.percentileofscore([], [1, 2])
        array([nan, nan])

    permutation_test(data, statistic, *, permutation_type='independent', vectorized=None, n_resamples=9999, batch=None, alternative='two-sided', axis=0, random_state=None)
        Performs a permutation test of a given statistic on provided data.

        For independent sample statistics, the null hypothesis is that the data are
        randomly sampled from the same distribution.
        For paired sample statistics, two null hypothesis can be tested:
        that the data are paired at random or that the data are assigned to samples
        at random.

        Parameters
        ----------
        data : iterable of array-like
            Contains the samples, each of which is an array of observations.
            Dimensions of sample arrays must be compatible for broadcasting except
            along `axis`.
        statistic : callable
            Statistic for which the p-value of the hypothesis test is to be
            calculated. `statistic` must be a callable that accepts samples
            as separate arguments (e.g. ``statistic(*data)``) and returns the
            resulting statistic.
            If `vectorized` is set ``True``, `statistic` must also accept a keyword
            argument `axis` and be vectorized to compute the statistic along the
            provided `axis` of the sample arrays.
        permutation_type : {'independent', 'samples', 'pairings'}, optional
            The type of permutations to be performed, in accordance with the
            null hypothesis. The first two permutation types are for paired sample
            statistics, in which all samples contain the same number of
            observations and observations with corresponding indices along `axis`
            are considered to be paired; the third is for independent sample
            statistics.

            - ``'samples'`` : observations are assigned to different samples
              but remain paired with the same observations from other samples.
              This permutation type is appropriate for paired sample hypothesis
              tests such as the Wilcoxon signed-rank test and the paired t-test.
            - ``'pairings'`` : observations are paired with different observations,
              but they remain within the same sample. This permutation type is
              appropriate for association/correlation tests with statistics such
              as Spearman's :math:`\rho`, Kendall's :math:`\tau`, and Pearson's
              :math:`r`.
            - ``'independent'`` (default) : observations are assigned to different
              samples. Samples may contain different numbers of observations. This
              permutation type is appropriate for independent sample hypothesis
              tests such as the Mann-Whitney :math:`U` test and the independent
              sample t-test.

              Please see the Notes section below for more detailed descriptions
              of the permutation types.

        vectorized : bool, optional
            If `vectorized` is set ``False``, `statistic` will not be passed
            keyword argument `axis` and is expected to calculate the statistic
            only for 1D samples. If ``True``, `statistic` will be passed keyword
            argument `axis` and is expected to calculate the statistic along `axis`
            when passed an ND sample array. If ``None`` (default), `vectorized`
            will be set ``True`` if ``axis`` is a parameter of `statistic`. Use
            of a vectorized statistic typically reduces computation time.
        n_resamples : int or np.inf, default: 9999
            Number of random permutations (resamples) used to approximate the null
            distribution. If greater than or equal to the number of distinct
            permutations, the exact null distribution will be computed.
            Note that the number of distinct permutations grows very rapidly with
            the sizes of samples, so exact tests are feasible only for very small
            data sets.
        batch : int, optional
            The number of permutations to process in each call to `statistic`.
            Memory usage is O( `batch` * ``n`` ), where ``n`` is the total size
            of all samples, regardless of the value of `vectorized`. Default is
            ``None``, in which case ``batch`` is the number of permutations.
        alternative : {'two-sided', 'less', 'greater'}, optional
            The alternative hypothesis for which the p-value is calculated.
            For each alternative, the p-value is defined for exact tests as
            follows.

            - ``'greater'`` : the percentage of the null distribution that is
              greater than or equal to the observed value of the test statistic.
            - ``'less'`` : the percentage of the null distribution that is
              less than or equal to the observed value of the test statistic.
            - ``'two-sided'`` (default) : twice the smaller of the p-values above.

            Note that p-values for randomized tests are calculated according to the
            conservative (over-estimated) approximation suggested in [2]_ and [3]_
            rather than the unbiased estimator suggested in [4]_. That is, when
            calculating the proportion of the randomized null distribution that is
            as extreme as the observed value of the test statistic, the values in
            the numerator and denominator are both increased by one. An
            interpretation of this adjustment is that the observed value of the
            test statistic is always included as an element of the randomized
            null distribution.
            The convention used for two-sided p-values is not universal;
            the observed test statistic and null distribution are returned in
            case a different definition is preferred.

        axis : int, default: 0
            The axis of the (broadcasted) samples over which to calculate the
            statistic. If samples have a different number of dimensions,
            singleton dimensions are prepended to samples with fewer dimensions
            before `axis` is considered.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            Pseudorandom number generator state used to generate permutations.

            If `random_state` is ``None`` (default), the
            `numpy.random.RandomState` singleton is used.
            If `random_state` is an int, a new ``RandomState`` instance is used,
            seeded with `random_state`.
            If `random_state` is already a ``Generator`` or ``RandomState``
            instance then that instance is used.

        Returns
        -------
        res : PermutationTestResult
            An object with attributes:

            statistic : float or ndarray
                The observed test statistic of the data.
            pvalue : float or ndarray
                The p-value for the given alternative.
            null_distribution : ndarray
                The values of the test statistic generated under the null
                hypothesis.

        Notes
        -----

        The three types of permutation tests supported by this function are
        described below.

        **Unpaired statistics** (``permutation_type='independent'``):

        The null hypothesis associated with this permutation type is that all
        observations are sampled from the same underlying distribution and that
        they have been assigned to one of the samples at random.

        Suppose ``data`` contains two samples; e.g. ``a, b = data``.
        When ``1 < n_resamples < binom(n, k)``, where

        * ``k`` is the number of observations in ``a``,
        * ``n`` is the total number of observations in ``a`` and ``b``, and
        * ``binom(n, k)`` is the binomial coefficient (``n`` choose ``k``),

        the data are pooled (concatenated), randomly assigned to either the first
        or second sample, and the statistic is calculated. This process is
        performed repeatedly, `permutation` times, generating a distribution of the
        statistic under the null hypothesis. The statistic of the original
        data is compared to this distribution to determine the p-value.

        When ``n_resamples >= binom(n, k)``, an exact test is performed: the data
        are *partitioned* between the samples in each distinct way exactly once,
        and the exact null distribution is formed.
        Note that for a given partitioning of the data between the samples,
        only one ordering/permutation of the data *within* each sample is
        considered. For statistics that do not depend on the order of the data
        within samples, this dramatically reduces computational cost without
        affecting the shape of the null distribution (because the frequency/count
        of each value is affected by the same factor).

        For ``a = [a1, a2, a3, a4]`` and ``b = [b1, b2, b3]``, an example of this
        permutation type is ``x = [b3, a1, a2, b2]`` and ``y = [a4, b1, a3]``.
        Because only one ordering/permutation of the data *within* each sample
        is considered in an exact test, a resampling like ``x = [b3, a1, b2, a2]``
        and ``y = [a4, a3, b1]`` would *not* be considered distinct from the
        example above.

        ``permutation_type='independent'`` does not support one-sample statistics,
        but it can be applied to statistics with more than two samples. In this
        case, if ``n`` is an array of the number of observations within each
        sample, the number of distinct partitions is::

            np.prod([binom(sum(n[i:]), sum(n[i+1:])) for i in range(len(n)-1)])

        **Paired statistics, permute pairings** (``permutation_type='pairings'``):

        The null hypothesis associated with this permutation type is that
        observations within each sample are drawn from the same underlying
        distribution and that pairings with elements of other samples are
        assigned at random.

        Suppose ``data`` contains only one sample; e.g. ``a, = data``, and we
        wish to consider all possible pairings of elements of ``a`` with elements
        of a second sample, ``b``. Let ``n`` be the number of observations in
        ``a``, which must also equal the number of observations in ``b``.

        When ``1 < n_resamples < factorial(n)``, the elements of ``a`` are
        randomly permuted. The user-supplied statistic accepts one data argument,
        say ``a_perm``, and calculates the statistic considering ``a_perm`` and
        ``b``. This process is performed repeatedly, `permutation` times,
        generating a distribution of the statistic under the null hypothesis.
        The statistic of the original data is compared to this distribution to
        determine the p-value.

        When ``n_resamples >= factorial(n)``, an exact test is performed:
        ``a`` is permuted in each distinct way exactly once. Therefore, the
        `statistic` is computed for each unique pairing of samples between ``a``
        and ``b`` exactly once.

        For ``a = [a1, a2, a3]`` and ``b = [b1, b2, b3]``, an example of this
        permutation type is ``a_perm = [a3, a1, a2]`` while ``b`` is left
        in its original order.

        ``permutation_type='pairings'`` supports ``data`` containing any number
        of samples, each of which must contain the same number of observations.
        All samples provided in ``data`` are permuted *independently*. Therefore,
        if ``m`` is the number of samples and ``n`` is the number of observations
        within each sample, then the number of permutations in an exact test is::

            factorial(n)**m

        Note that if a two-sample statistic, for example, does not inherently
        depend on the order in which observations are provided - only on the
        *pairings* of observations - then only one of the two samples should be
        provided in ``data``. This dramatically reduces computational cost without
        affecting the shape of the null distribution (because the frequency/count
        of each value is affected by the same factor).

        **Paired statistics, permute samples** (``permutation_type='samples'``):

        The null hypothesis associated with this permutation type is that
        observations within each pair are drawn from the same underlying
        distribution and that the sample to which they are assigned is random.

        Suppose ``data`` contains two samples; e.g. ``a, b = data``.
        Let ``n`` be the number of observations in ``a``, which must also equal
        the number of observations in ``b``.

        When ``1 < n_resamples < 2**n``, the elements of ``a`` are ``b`` are
        randomly swapped between samples (maintaining their pairings) and the
        statistic is calculated. This process is performed repeatedly,
        `permutation` times,  generating a distribution of the statistic under the
        null hypothesis. The statistic of the original data is compared to this
        distribution to determine the p-value.

        When ``n_resamples >= 2**n``, an exact test is performed: the observations
        are assigned to the two samples in each distinct way (while maintaining
        pairings) exactly once.

        For ``a = [a1, a2, a3]`` and ``b = [b1, b2, b3]``, an example of this
        permutation type is ``x = [b1, a2, b3]`` and ``y = [a1, b2, a3]``.

        ``permutation_type='samples'`` supports ``data`` containing any number
        of samples, each of which must contain the same number of observations.
        If ``data`` contains more than one sample, paired observations within
        ``data`` are exchanged between samples *independently*. Therefore, if ``m``
        is the number of samples and ``n`` is the number of observations within
        each sample, then the number of permutations in an exact test is::

            factorial(m)**n

        Several paired-sample statistical tests, such as the Wilcoxon signed rank
        test and paired-sample t-test, can be performed considering only the
        *difference* between two paired elements. Accordingly, if ``data`` contains
        only one sample, then the null distribution is formed by independently
        changing the *sign* of each observation.

        .. warning::
            The p-value is calculated by counting the elements of the null
            distribution that are as extreme or more extreme than the observed
            value of the statistic. Due to the use of finite precision arithmetic,
            some statistic functions return numerically distinct values when the
            theoretical values would be exactly equal. In some cases, this could
            lead to a large error in the calculated p-value. `permutation_test`
            guards against this by considering elements in the null distribution
            that are "close" (within a relative tolerance of 100 times the
            floating point epsilon of inexact dtypes) to the observed
            value of the test statistic as equal to the observed value of the
            test statistic. However, the user is advised to inspect the null
            distribution to assess whether this method of comparison is
            appropriate, and if not, calculate the p-value manually. See example
            below.

        References
        ----------

        .. [1] R. A. Fisher. The Design of Experiments, 6th Ed (1951).
        .. [2] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
           Zero: Calculating Exact P-values When Permutations Are Randomly Drawn."
           Statistical Applications in Genetics and Molecular Biology 9.1 (2010).
        .. [3] M. D. Ernst. "Permutation Methods: A Basis for Exact Inference".
           Statistical Science (2004).
        .. [4] B. Efron and R. J. Tibshirani. An Introduction to the Bootstrap
           (1993).

        Examples
        --------

        Suppose we wish to test whether two samples are drawn from the same
        distribution. Assume that the underlying distributions are unknown to us,
        and that before observing the data, we hypothesized that the mean of the
        first sample would be less than that of the second sample. We decide that
        we will use the difference between the sample means as a test statistic,
        and we will consider a p-value of 0.05 to be statistically significant.

        For efficiency, we write the function defining the test statistic in a
        vectorized fashion: the samples ``x`` and ``y`` can be ND arrays, and the
        statistic will be calculated for each axis-slice along `axis`.

        >>> import numpy as np
        >>> def statistic(x, y, axis):
        ...     return np.mean(x, axis=axis) - np.mean(y, axis=axis)

        After collecting our data, we calculate the observed value of the test
        statistic.

        >>> from scipy.stats import norm
        >>> rng = np.random.default_rng()
        >>> x = norm.rvs(size=5, random_state=rng)
        >>> y = norm.rvs(size=6, loc = 3, random_state=rng)
        >>> statistic(x, y, 0)
        -3.5411688580987266

        Indeed, the test statistic is negative, suggesting that the true mean of
        the distribution underlying ``x`` is less than that of the distribution
        underlying ``y``. To determine the probability of this occurring by chance
        if the two samples were drawn from the same distribution, we perform
        a permutation test.

        >>> from scipy.stats import permutation_test
        >>> # because our statistic is vectorized, we pass `vectorized=True`
        >>> # `n_resamples=np.inf` indicates that an exact test is to be performed
        >>> res = permutation_test((x, y), statistic, vectorized=True,
        ...                        n_resamples=np.inf, alternative='less')
        >>> print(res.statistic)
        -3.5411688580987266
        >>> print(res.pvalue)
        0.004329004329004329

        The probability of obtaining a test statistic less than or equal to the
        observed value under the null hypothesis is 0.4329%. This is less than our
        chosen threshold of 5%, so we consider this to be significant evidence
        against the null hypothesis in favor of the alternative.

        Because the size of the samples above was small, `permutation_test` could
        perform an exact test. For larger samples, we resort to a randomized
        permutation test.

        >>> x = norm.rvs(size=100, random_state=rng)
        >>> y = norm.rvs(size=120, loc=0.2, random_state=rng)
        >>> res = permutation_test((x, y), statistic, n_resamples=9999,
        ...                        vectorized=True, alternative='less',
        ...                        random_state=rng)
        >>> print(res.statistic)
        -0.4230459671240913
        >>> print(res.pvalue)
        0.0015

        The approximate probability of obtaining a test statistic less than or
        equal to the observed value under the null hypothesis is 0.0225%. This is
        again less than our chosen threshold of 5%, so again we have significant
        evidence to reject the null hypothesis in favor of the alternative.

        For large samples and number of permutations, the result is comparable to
        that of the corresponding asymptotic test, the independent sample t-test.

        >>> from scipy.stats import ttest_ind
        >>> res_asymptotic = ttest_ind(x, y, alternative='less')
        >>> print(res_asymptotic.pvalue)
        0.0014669545224902675

        The permutation distribution of the test statistic is provided for
        further investigation.

        >>> import matplotlib.pyplot as plt
        >>> plt.hist(res.null_distribution, bins=50)
        >>> plt.title("Permutation distribution of test statistic")
        >>> plt.xlabel("Value of Statistic")
        >>> plt.ylabel("Frequency")
        >>> plt.show()

        Inspection of the null distribution is essential if the statistic suffers
        from inaccuracy due to limited machine precision. Consider the following
        case:

        >>> from scipy.stats import pearsonr
        >>> x = [1, 2, 4, 3]
        >>> y = [2, 4, 6, 8]
        >>> def statistic(x, y, axis=-1):
        ...     return pearsonr(x, y, axis=axis).statistic
        >>> res = permutation_test((x, y), statistic, vectorized=True,
        ...                        permutation_type='pairings',
        ...                        alternative='greater')
        >>> r, pvalue, null = res.statistic, res.pvalue, res.null_distribution

        In this case, some elements of the null distribution differ from the
        observed value of the correlation coefficient ``r`` due to numerical noise.
        We manually inspect the elements of the null distribution that are nearly
        the same as the observed value of the test statistic.

        >>> r
        0.7999999999999999
        >>> unique = np.unique(null)
        >>> unique
        array([-1. , -1. , -0.8, -0.8, -0.8, -0.6, -0.4, -0.4, -0.2, -0.2, -0.2,
            0. ,  0.2,  0.2,  0.2,  0.4,  0.4,  0.6,  0.8,  0.8,  0.8,  1. ,
            1. ])  # may vary
        >>> unique[np.isclose(r, unique)].tolist()
        [0.7999999999999998, 0.7999999999999999, 0.8]  # may vary

        If `permutation_test` were to perform the comparison naively, the
        elements of the null distribution with value ``0.7999999999999998`` would
        not be considered as extreme or more extreme as the observed value of the
        statistic, so the calculated p-value would be too small.

        >>> incorrect_pvalue = np.count_nonzero(null >= r) / len(null)
        >>> incorrect_pvalue
        0.14583333333333334  # may vary

        Instead, `permutation_test` treats elements of the null distribution that
        are within ``max(1e-14, abs(r)*1e-14)`` of the observed value of the
        statistic ``r`` to be equal to ``r``.

        >>> correct_pvalue = np.count_nonzero(null >= r - 1e-14) / len(null)
        >>> correct_pvalue
        0.16666666666666666
        >>> res.pvalue == correct_pvalue
        True

        This method of comparison is expected to be accurate in most practical
        situations, but the user is advised to assess this by inspecting the
        elements of the null distribution that are close to the observed value
        of the statistic. Also, consider the use of statistics that can be
        calculated using exact arithmetic (e.g. integer statistics).

    pmean(a, p, *, axis=0, dtype=None, weights=None, nan_policy='propagate', keepdims=False)
        Calculate the weighted power mean along the specified axis.

        The weighted power mean of the array :math:`a_i` associated to weights
        :math:`w_i` is:

        .. math::

            \left( \frac{ \sum_{i=1}^n w_i a_i^p }{ \sum_{i=1}^n w_i }
                  \right)^{ 1 / p } \, ,

        and, with equal weights, it gives:

        .. math::

            \left( \frac{ 1 }{ n } \sum_{i=1}^n a_i^p \right)^{ 1 / p }  \, .

        When ``p=0``, it returns the geometric mean.

        This mean is also called generalized mean or Hölder mean, and must not be
        confused with the Kolmogorov generalized mean, also called
        quasi-arithmetic mean or generalized f-mean [3]_.

        Parameters
        ----------
        a : array_like
            Input array, masked array or object that can be converted to an array.
        p : int or float
            Exponent.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        dtype : dtype, optional
            Type of the returned array and of the accumulator in which the
            elements are summed. If `dtype` is not specified, it defaults to the
            dtype of `a`, unless `a` has an integer `dtype` with a precision less
            than that of the default platform integer. In that case, the default
            platform integer is used.
        weights : array_like, optional
            The weights array can either be 1-D (in which case its length must be
            the size of `a` along the given `axis`) or of the same shape as `a`.
            Default is None, which gives each value a weight of 1.0.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        pmean : ndarray, see `dtype` parameter above.
            Output array containing the power mean values.

        See Also
        --------

        :func:`numpy.average`
            Weighted average
        :func:`gmean`
            Geometric mean
        :func:`hmean`
            Harmonic mean


        Notes
        -----
        The power mean is computed over a single dimension of the input
        array, ``axis=0`` by default, or all values in the array if ``axis=None``.
        float64 intermediate and return values are used for integer inputs.

        .. versionadded:: 1.9

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] "Generalized Mean", *Wikipedia*,
               https://en.wikipedia.org/wiki/Generalized_mean
        .. [2] Norris, N., "Convexity properties of generalized mean value
               functions", The Annals of Mathematical Statistics, vol. 8,
               pp. 118-120, 1937
        .. [3] Bullen, P.S., Handbook of Means and Their Inequalities, 2003

        Examples
        --------
        >>> from scipy.stats import pmean, hmean, gmean
        >>> pmean([1, 4], 1.3)
        2.639372938300652
        >>> pmean([1, 2, 3, 4, 5, 6, 7], 1.3)
        4.157111214492084
        >>> pmean([1, 4, 7], -2, weights=[3, 1, 3])
        1.4969684896631954

        For p=-1, power mean is equal to harmonic mean:

        >>> pmean([1, 4, 7], -1, weights=[3, 1, 3])
        1.9029126213592233
        >>> hmean([1, 4, 7], weights=[3, 1, 3])
        1.9029126213592233

        For p=0, power mean is defined as the geometric mean:

        >>> pmean([1, 4, 7], 0, weights=[3, 1, 3])
        2.80668351922014
        >>> gmean([1, 4, 7], weights=[3, 1, 3])
        2.80668351922014

    pointbiserialr(x, y)
        Calculate a point biserial correlation coefficient and its p-value.

        The point biserial correlation is used to measure the relationship
        between a binary variable, x, and a continuous variable, y. Like other
        correlation coefficients, this one varies between -1 and +1 with 0
        implying no correlation. Correlations of -1 or +1 imply a determinative
        relationship.

        This function may be computed using a shortcut formula but produces the
        same result as `pearsonr`.

        Parameters
        ----------
        x : array_like of bools
            Input array.
        y : array_like
            Input array.

        Returns
        -------
        res: SignificanceResult
            An object containing attributes:

            statistic : float
                The R value.
            pvalue : float
                The two-sided p-value.

        Notes
        -----
        `pointbiserialr` uses a t-test with ``n-1`` degrees of freedom.
        It is equivalent to `pearsonr`.

        The value of the point-biserial correlation can be calculated from:

        .. math::

            r_{pb} = \frac{\overline{Y_1} - \overline{Y_0}}
                          {s_y}
                     \sqrt{\frac{N_0 N_1}
                                {N (N - 1)}}

        Where :math:`\overline{Y_{0}}` and :math:`\overline{Y_{1}}` are means
        of the metric observations coded 0 and 1 respectively; :math:`N_{0}` and
        :math:`N_{1}` are number of observations coded 0 and 1 respectively;
        :math:`N` is the total number of observations and :math:`s_{y}` is the
        standard deviation of all the metric observations.

        A value of :math:`r_{pb}` that is significantly different from zero is
        completely equivalent to a significant difference in means between the two
        groups. Thus, an independent groups t Test with :math:`N-2` degrees of
        freedom may be used to test whether :math:`r_{pb}` is nonzero. The
        relation between the t-statistic for comparing two independent groups and
        :math:`r_{pb}` is given by:

        .. math::

            t = \sqrt{N - 2}\frac{r_{pb}}{\sqrt{1 - r^{2}_{pb}}}

        References
        ----------
        .. [1] J. Lev, "The Point Biserial Coefficient of Correlation", Ann. Math.
               Statist., Vol. 20, no.1, pp. 125-126, 1949.

        .. [2] R.F. Tate, "Correlation Between a Discrete and a Continuous
               Variable. Point-Biserial Correlation.", Ann. Math. Statist., Vol. 25,
               np. 3, pp. 603-607, 1954.

        .. [3] D. Kornbrot "Point Biserial Correlation", In Wiley StatsRef:
               Statistics Reference Online (eds N. Balakrishnan, et al.), 2014.
               :doi:`10.1002/9781118445112.stat06227`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> a = np.array([0, 0, 0, 1, 1, 1, 1])
        >>> b = np.arange(7)
        >>> stats.pointbiserialr(a, b)
        (0.8660254037844386, 0.011724811003954652)
        >>> stats.pearsonr(a, b)
        (0.86602540378443871, 0.011724811003954626)
        >>> np.corrcoef(a, b)
        array([[ 1.       ,  0.8660254],
               [ 0.8660254,  1.       ]])

    poisson_means_test(k1, n1, k2, n2, *, diff=0, alternative='two-sided')
        Performs the Poisson means test, AKA the "E-test".

        This is a test of the null hypothesis that the difference between means of
        two Poisson distributions is `diff`. The samples are provided as the
        number of events `k1` and `k2` observed within measurement intervals
        (e.g. of time, space, number of observations) of sizes `n1` and `n2`.

        Parameters
        ----------
        k1 : int
            Number of events observed from distribution 1.
        n1: float
            Size of sample from distribution 1.
        k2 : int
            Number of events observed from distribution 2.
        n2 : float
            Size of sample from distribution 2.
        diff : float, default=0
            The hypothesized difference in means between the distributions
            underlying the samples.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

              * 'two-sided': the difference between distribution means is not
                equal to `diff`
              * 'less': the difference between distribution means is less than
                `diff`
              * 'greater': the difference between distribution means is greater
                than `diff`

        Returns
        -------
        statistic : float
            The test statistic (see [1]_ equation 3.3).
        pvalue : float
            The probability of achieving such an extreme value of the test
            statistic under the null hypothesis.

        Notes
        -----

        Let:

        .. math:: X_1 \sim \mbox{Poisson}(\mathtt{n1}\lambda_1)

        be a random variable independent of

        .. math:: X_2  \sim \mbox{Poisson}(\mathtt{n2}\lambda_2)

        and let ``k1`` and ``k2`` be the observed values of :math:`X_1`
        and :math:`X_2`, respectively. Then `poisson_means_test` uses the number
        of observed events ``k1`` and ``k2`` from samples of size ``n1`` and
        ``n2``, respectively, to test the null hypothesis that

        .. math::
           H_0: \lambda_1 - \lambda_2 = \mathtt{diff}

        A benefit of the E-test is that it has good power for small sample sizes,
        which can reduce sampling costs [1]_. It has been evaluated and determined
        to be more powerful than the comparable C-test, sometimes referred to as
        the Poisson exact test.

        References
        ----------
        .. [1]  Krishnamoorthy, K., & Thomson, J. (2004). A more powerful test for
           comparing two Poisson means. Journal of Statistical Planning and
           Inference, 119(1), 23-35.

        .. [2]  Przyborowski, J., & Wilenski, H. (1940). Homogeneity of results in
           testing samples from Poisson series: With an application to testing
           clover seed for dodder. Biometrika, 31(3/4), 313-323.

        Examples
        --------

        Suppose that a gardener wishes to test the number of dodder (weed) seeds
        in a sack of clover seeds that they buy from a seed company. It has
        previously been established that the number of dodder seeds in clover
        follows the Poisson distribution.

        A 100 gram sample is drawn from the sack before being shipped to the
        gardener. The sample is analyzed, and it is found to contain no dodder
        seeds; that is, `k1` is 0. However, upon arrival, the gardener draws
        another 100 gram sample from the sack. This time, three dodder seeds are
        found in the sample; that is, `k2` is 3. The gardener would like to
        know if the difference is significant and not due to chance. The
        null hypothesis is that the difference between the two samples is merely
        due to chance, or that :math:`\lambda_1 - \lambda_2 = \mathtt{diff}`
        where :math:`\mathtt{diff} = 0`. The alternative hypothesis is that the
        difference is not due to chance, or :math:`\lambda_1 - \lambda_2 \ne 0`.
        The gardener selects a significance level of 5% to reject the null
        hypothesis in favor of the alternative [2]_.

        >>> import scipy.stats as stats
        >>> res = stats.poisson_means_test(0, 100, 3, 100)
        >>> res.statistic, res.pvalue
        (-1.7320508075688772, 0.08837900929018157)

        The p-value is .088, indicating a near 9% chance of observing a value of
        the test statistic under the null hypothesis. This exceeds 5%, so the
        gardener does not reject the null hypothesis as the difference cannot be
        regarded as significant at this level.

    power(test, rvs, n_observations, *, significance=0.01, vectorized=None, n_resamples=10000, batch=None, kwargs=None)
        Simulate the power of a hypothesis test under an alternative hypothesis.

        Parameters
        ----------
        test : callable
            Hypothesis test for which the power is to be simulated.
            `test` must be a callable that accepts a sample (e.g. ``test(sample)``)
            or ``len(rvs)`` separate samples (e.g. ``test(samples1, sample2)`` if
            `rvs` contains two callables and `n_observations` contains two values)
            and returns the p-value of the test.
            If `vectorized` is set to ``True``, `test` must also accept a keyword
            argument `axis` and be vectorized to perform the test along the
            provided `axis` of the samples.
            Any callable from `scipy.stats` with an `axis` argument that returns an
            object with a `pvalue` attribute is also acceptable.
        rvs : callable or tuple of callables
            A callable or sequence of callables that generate(s) random variates
            under the alternative hypothesis. Each element of `rvs` must accept
            keyword argument ``size`` (e.g. ``rvs(size=(m, n))``) and return an
            N-d array of that shape. If `rvs` is a sequence, the number of callables
            in `rvs` must match the number of elements of `n_observations`, i.e.
            ``len(rvs) == len(n_observations)``. If `rvs` is a single callable,
            `n_observations` is treated as a single element.
        n_observations : tuple of ints or tuple of integer arrays
            If a sequence of ints, each is the sizes of a sample to be passed to `test`.
            If a sequence of integer arrays, the power is simulated for each
            set of corresponding sample sizes. See Examples.
        significance : float or array_like of floats, default: 0.01
            The threshold for significance; i.e., the p-value below which the
            hypothesis test results will be considered as evidence against the null
            hypothesis. Equivalently, the acceptable rate of Type I error under
            the null hypothesis. If an array, the power is simulated for each
            significance threshold.
        kwargs : dict, optional
            Keyword arguments to be passed to `rvs` and/or `test` callables.
            Introspection is used to determine which keyword arguments may be
            passed to each callable.
            The value corresponding with each keyword must be an array.
            Arrays must be broadcastable with one another and with each array in
            `n_observations`. The power is simulated for each set of corresponding
            sample sizes and arguments. See Examples.
        vectorized : bool, optional
            If `vectorized` is set to ``False``, `test` will not be passed keyword
            argument `axis` and is expected to perform the test only for 1D samples.
            If ``True``, `test` will be passed keyword argument `axis` and is
            expected to perform the test along `axis` when passed N-D sample arrays.
            If ``None`` (default), `vectorized` will be set ``True`` if ``axis`` is
            a parameter of `test`. Use of a vectorized test typically reduces
            computation time.
        n_resamples : int, default: 10000
            Number of samples drawn from each of the callables of `rvs`.
            Equivalently, the number tests performed under the alternative
            hypothesis to approximate the power.
        batch : int, optional
            The number of samples to process in each call to `test`. Memory usage is
            proportional to the product of `batch` and the largest sample size. Default
            is ``None``, in which case `batch` equals `n_resamples`.

        Returns
        -------
        res : PowerResult
            An object with attributes:

            power : float or ndarray
                The estimated power against the alternative.
            pvalues : ndarray
                The p-values observed under the alternative hypothesis.

        Notes
        -----
        The power is simulated as follows:

        - Draw many random samples (or sets of samples), each of the size(s)
          specified by `n_observations`, under the alternative specified by
          `rvs`.
        - For each sample (or set of samples), compute the p-value according to
          `test`. These p-values are recorded in the ``pvalues`` attribute of
          the result object.
        - Compute the proportion of p-values that are less than the `significance`
          level. This is the power recorded in the ``power`` attribute of the
          result object.

        Suppose that `significance` is an array with shape ``shape1``, the elements
        of `kwargs` and `n_observations` are mutually broadcastable to shape ``shape2``,
        and `test` returns an array of p-values of shape ``shape3``. Then the result
        object ``power`` attribute will be of shape ``shape1 + shape2 + shape3``, and
        the ``pvalues`` attribute will be of shape ``shape2 + shape3 + (n_resamples,)``.

        Examples
        --------
        Suppose we wish to simulate the power of the independent sample t-test
        under the following conditions:

        - The first sample has 10 observations drawn from a normal distribution
          with mean 0.
        - The second sample has 12 observations drawn from a normal distribution
          with mean 1.0.
        - The threshold on p-values for significance is 0.05.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng(2549598345528)
        >>>
        >>> test = stats.ttest_ind
        >>> n_observations = (10, 12)
        >>> rvs1 = rng.normal
        >>> rvs2 = lambda size: rng.normal(loc=1, size=size)
        >>> rvs = (rvs1, rvs2)
        >>> res = stats.power(test, rvs, n_observations, significance=0.05)
        >>> res.power
        0.6116

        With samples of size 10 and 12, respectively, the power of the t-test
        with a significance threshold of 0.05 is approximately 60% under the chosen
        alternative. We can investigate the effect of sample size on the power
        by passing sample size arrays.

        >>> import matplotlib.pyplot as plt
        >>> nobs_x = np.arange(5, 21)
        >>> nobs_y = nobs_x
        >>> n_observations = (nobs_x, nobs_y)
        >>> res = stats.power(test, rvs, n_observations, significance=0.05)
        >>> ax = plt.subplot()
        >>> ax.plot(nobs_x, res.power)
        >>> ax.set_xlabel('Sample Size')
        >>> ax.set_ylabel('Simulated Power')
        >>> ax.set_title('Simulated Power of `ttest_ind` with Equal Sample Sizes')
        >>> plt.show()

        Alternatively, we can investigate the impact that effect size has on the power.
        In this case, the effect size is the location of the distribution underlying
        the second sample.

        >>> n_observations = (10, 12)
        >>> loc = np.linspace(0, 1, 20)
        >>> rvs2 = lambda size, loc: rng.normal(loc=loc, size=size)
        >>> rvs = (rvs1, rvs2)
        >>> res = stats.power(test, rvs, n_observations, significance=0.05,
        ...                   kwargs={'loc': loc})
        >>> ax = plt.subplot()
        >>> ax.plot(loc, res.power)
        >>> ax.set_xlabel('Effect Size')
        >>> ax.set_ylabel('Simulated Power')
        >>> ax.set_title('Simulated Power of `ttest_ind`, Varying Effect Size')
        >>> plt.show()

        We can also use `power` to estimate the Type I error rate (also referred to by the
        ambiguous term "size") of a test and assess whether it matches the nominal level.
        For example, the null hypothesis of `jarque_bera` is that the sample was drawn from
        a distribution with the same skewness and kurtosis as the normal distribution. To
        estimate the Type I error rate, we can consider the null hypothesis to be a true
        *alternative* hypothesis and calculate the power.

        >>> test = stats.jarque_bera
        >>> n_observations = 10
        >>> rvs = rng.normal
        >>> significance = np.linspace(0.0001, 0.1, 1000)
        >>> res = stats.power(test, rvs, n_observations, significance=significance)
        >>> size = res.power

        As shown below, the Type I error rate of the test is far below the nominal level
        for such a small sample, as mentioned in its documentation.

        >>> ax = plt.subplot()
        >>> ax.plot(significance, size)
        >>> ax.plot([0, 0.1], [0, 0.1], '--')
        >>> ax.set_xlabel('nominal significance level')
        >>> ax.set_ylabel('estimated test size (Type I error rate)')
        >>> ax.set_title('Estimated test size vs nominal significance level')
        >>> ax.set_aspect('equal', 'box')
        >>> ax.legend(('`ttest_1samp`', 'ideal test'))
        >>> plt.show()

        As one might expect from such a conservative test, the power is quite low with
        respect to some alternatives. For example, the power of the test under the
        alternative that the sample was drawn from the Laplace distribution may not
        be much greater than the Type I error rate.

        >>> rvs = rng.laplace
        >>> significance = np.linspace(0.0001, 0.1, 1000)
        >>> res = stats.power(test, rvs, n_observations, significance=0.05)
        >>> print(res.power)
        0.0587

        This is not a mistake in SciPy's implementation; it is simply due to the fact
        that the null distribution of the test statistic is derived under the assumption
        that the sample size is large (i.e. approaches infinity), and this asymptotic
        approximation is not accurate for small samples. In such cases, resampling
        and Monte Carlo methods (e.g. `permutation_test`, `goodness_of_fit`,
        `monte_carlo_test`) may be more appropriate.

    power_divergence(f_obs, f_exp=None, ddof=0, axis=0, lambda_=None)
        Cressie-Read power divergence statistic and goodness of fit test.

        This function tests the null hypothesis that the categorical data
        has the given frequencies, using the Cressie-Read power divergence
        statistic.

        Parameters
        ----------
        f_obs : array_like
            Observed frequencies in each category.

            .. deprecated:: 1.14.0
                Support for masked array input was deprecated in
                SciPy 1.14.0 and will be removed in version 1.16.0.

        f_exp : array_like, optional
            Expected frequencies in each category.  By default the categories are
            assumed to be equally likely.

            .. deprecated:: 1.14.0
                Support for masked array input was deprecated in
                SciPy 1.14.0 and will be removed in version 1.16.0.

        ddof : int, optional
            "Delta degrees of freedom": adjustment to the degrees of freedom
            for the p-value.  The p-value is computed using a chi-squared
            distribution with ``k - 1 - ddof`` degrees of freedom, where `k`
            is the number of observed frequencies.  The default value of `ddof`
            is 0.
        axis : int or None, optional
            The axis of the broadcast result of `f_obs` and `f_exp` along which to
            apply the test.  If axis is None, all values in `f_obs` are treated
            as a single data set.  Default is 0.
        lambda_ : float or str, optional
            The power in the Cressie-Read power divergence statistic.  The default
            is 1.  For convenience, `lambda_` may be assigned one of the following
            strings, in which case the corresponding numerical value is used:

            * ``"pearson"`` (value 1)
                Pearson's chi-squared statistic. In this case, the function is
                equivalent to `chisquare`.
            * ``"log-likelihood"`` (value 0)
                Log-likelihood ratio. Also known as the G-test [3]_.
            * ``"freeman-tukey"`` (value -1/2)
                Freeman-Tukey statistic.
            * ``"mod-log-likelihood"`` (value -1)
                Modified log-likelihood ratio.
            * ``"neyman"`` (value -2)
                Neyman's statistic.
            * ``"cressie-read"`` (value 2/3)
                The power recommended in [5]_.

        Returns
        -------
        res: Power_divergenceResult
            An object containing attributes:

            statistic : float or ndarray
                The Cressie-Read power divergence test statistic.  The value is
                a float if `axis` is None or if` `f_obs` and `f_exp` are 1-D.
            pvalue : float or ndarray
                The p-value of the test.  The value is a float if `ddof` and the
                return value `stat` are scalars.

        See Also
        --------
        chisquare

        Notes
        -----
        This test is invalid when the observed or expected frequencies in each
        category are too small.  A typical rule is that all of the observed
        and expected frequencies should be at least 5.

        Also, the sum of the observed and expected frequencies must be the same
        for the test to be valid; `power_divergence` raises an error if the sums
        do not agree within a relative tolerance of ``eps**0.5``, where ``eps``
        is the precision of the input dtype.

        When `lambda_` is less than zero, the formula for the statistic involves
        dividing by `f_obs`, so a warning or error may be generated if any value
        in `f_obs` is 0.

        Similarly, a warning or error may be generated if any value in `f_exp` is
        zero when `lambda_` >= 0.

        The default degrees of freedom, k-1, are for the case when no parameters
        of the distribution are estimated. If p parameters are estimated by
        efficient maximum likelihood then the correct degrees of freedom are
        k-1-p. If the parameters are estimated in a different way, then the
        dof can be between k-1-p and k-1. However, it is also possible that
        the asymptotic distribution is not a chisquare, in which case this
        test is not appropriate.

        References
        ----------
        .. [1] Lowry, Richard.  "Concepts and Applications of Inferential
               Statistics". Chapter 8.
               https://web.archive.org/web/20171015035606/http://faculty.vassar.edu/lowry/ch8pt1.html
        .. [2] "Chi-squared test", https://en.wikipedia.org/wiki/Chi-squared_test
        .. [3] "G-test", https://en.wikipedia.org/wiki/G-test
        .. [4] Sokal, R. R. and Rohlf, F. J. "Biometry: the principles and
               practice of statistics in biological research", New York: Freeman
               (1981)
        .. [5] Cressie, N. and Read, T. R. C., "Multinomial Goodness-of-Fit
               Tests", J. Royal Stat. Soc. Series B, Vol. 46, No. 3 (1984),
               pp. 440-464.

        Examples
        --------
        (See `chisquare` for more examples.)

        When just `f_obs` is given, it is assumed that the expected frequencies
        are uniform and given by the mean of the observed frequencies.  Here we
        perform a G-test (i.e. use the log-likelihood ratio statistic):

        >>> import numpy as np
        >>> from scipy.stats import power_divergence
        >>> power_divergence([16, 18, 16, 14, 12, 12], lambda_='log-likelihood')
        (2.006573162632538, 0.84823476779463769)

        The expected frequencies can be given with the `f_exp` argument:

        >>> power_divergence([16, 18, 16, 14, 12, 12],
        ...                  f_exp=[16, 16, 16, 16, 16, 8],
        ...                  lambda_='log-likelihood')
        (3.3281031458963746, 0.6495419288047497)

        When `f_obs` is 2-D, by default the test is applied to each column.

        >>> obs = np.array([[16, 18, 16, 14, 12, 12], [32, 24, 16, 28, 20, 24]]).T
        >>> obs.shape
        (6, 2)
        >>> power_divergence(obs, lambda_="log-likelihood")
        (array([ 2.00657316,  6.77634498]), array([ 0.84823477,  0.23781225]))

        By setting ``axis=None``, the test is applied to all data in the array,
        which is equivalent to applying the test to the flattened array.

        >>> power_divergence(obs, axis=None)
        (23.31034482758621, 0.015975692534127565)
        >>> power_divergence(obs.ravel())
        (23.31034482758621, 0.015975692534127565)

        `ddof` is the change to make to the default degrees of freedom.

        >>> power_divergence([16, 18, 16, 14, 12, 12], ddof=1)
        (2.0, 0.73575888234288467)

        The calculation of the p-values is done by broadcasting the
        test statistic with `ddof`.

        >>> power_divergence([16, 18, 16, 14, 12, 12], ddof=[0,1,2])
        (2.0, array([ 0.84914504,  0.73575888,  0.5724067 ]))

        `f_obs` and `f_exp` are also broadcast.  In the following, `f_obs` has
        shape (6,) and `f_exp` has shape (2, 6), so the result of broadcasting
        `f_obs` and `f_exp` has shape (2, 6).  To compute the desired chi-squared
        statistics, we must use ``axis=1``:

        >>> power_divergence([16, 18, 16, 14, 12, 12],
        ...                  f_exp=[[16, 16, 16, 16, 16, 8],
        ...                         [8, 20, 20, 16, 12, 12]],
        ...                  axis=1)
        (array([ 3.5 ,  9.25]), array([ 0.62338763,  0.09949846]))

    ppcc_max(x, brack=(0.0, 1.0), dist='tukeylambda')
        Calculate the shape parameter that maximizes the PPCC.

        The probability plot correlation coefficient (PPCC) plot can be used
        to determine the optimal shape parameter for a one-parameter family
        of distributions. ``ppcc_max`` returns the shape parameter that would
        maximize the probability plot correlation coefficient for the given
        data to a one-parameter family of distributions.

        Parameters
        ----------
        x : array_like
            Input array.
        brack : tuple, optional
            Triple (a,b,c) where (a<b<c). If bracket consists of two numbers (a, c)
            then they are assumed to be a starting interval for a downhill bracket
            search (see `scipy.optimize.brent`).
        dist : str or stats.distributions instance, optional
            Distribution or distribution function name.  Objects that look enough
            like a stats.distributions instance (i.e. they have a ``ppf`` method)
            are also accepted.  The default is ``'tukeylambda'``.

        Returns
        -------
        shape_value : float
            The shape parameter at which the probability plot correlation
            coefficient reaches its max value.

        See Also
        --------
        ppcc_plot, probplot, boxcox

        Notes
        -----
        The brack keyword serves as a starting point which is useful in corner
        cases. One can use a plot to obtain a rough visual estimate of the location
        for the maximum to start the search near it.

        References
        ----------
        .. [1] J.J. Filliben, "The Probability Plot Correlation Coefficient Test
               for Normality", Technometrics, Vol. 17, pp. 111-117, 1975.
        .. [2] Engineering Statistics Handbook, NIST/SEMATEC,
               https://www.itl.nist.gov/div898/handbook/eda/section3/ppccplot.htm

        Examples
        --------
        First we generate some random data from a Weibull distribution
        with shape parameter 2.5:

        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> c = 2.5
        >>> x = stats.weibull_min.rvs(c, scale=4, size=2000, random_state=rng)

        Generate the PPCC plot for this data with the Weibull distribution.

        >>> fig, ax = plt.subplots(figsize=(8, 6))
        >>> res = stats.ppcc_plot(x, c/2, 2*c, dist='weibull_min', plot=ax)

        We calculate the value where the shape should reach its maximum and a
        red line is drawn there. The line should coincide with the highest
        point in the PPCC graph.

        >>> cmax = stats.ppcc_max(x, brack=(c/2, 2*c), dist='weibull_min')
        >>> ax.axvline(cmax, color='r')
        >>> plt.show()

    ppcc_plot(x, a, b, dist='tukeylambda', plot=None, N=80)
        Calculate and optionally plot probability plot correlation coefficient.

        The probability plot correlation coefficient (PPCC) plot can be used to
        determine the optimal shape parameter for a one-parameter family of
        distributions.  It cannot be used for distributions without shape
        parameters
        (like the normal distribution) or with multiple shape parameters.

        By default a Tukey-Lambda distribution (`stats.tukeylambda`) is used. A
        Tukey-Lambda PPCC plot interpolates from long-tailed to short-tailed
        distributions via an approximately normal one, and is therefore
        particularly useful in practice.

        Parameters
        ----------
        x : array_like
            Input array.
        a, b : scalar
            Lower and upper bounds of the shape parameter to use.
        dist : str or stats.distributions instance, optional
            Distribution or distribution function name.  Objects that look enough
            like a stats.distributions instance (i.e. they have a ``ppf`` method)
            are also accepted.  The default is ``'tukeylambda'``.
        plot : object, optional
            If given, plots PPCC against the shape parameter.
            `plot` is an object that has to have methods "plot" and "text".
            The `matplotlib.pyplot` module or a Matplotlib Axes object can be used,
            or a custom object with the same methods.
            Default is None, which means that no plot is created.
        N : int, optional
            Number of points on the horizontal axis (equally distributed from
            `a` to `b`).

        Returns
        -------
        svals : ndarray
            The shape values for which `ppcc` was calculated.
        ppcc : ndarray
            The calculated probability plot correlation coefficient values.

        See Also
        --------
        ppcc_max, probplot, boxcox_normplot, tukeylambda

        References
        ----------
        J.J. Filliben, "The Probability Plot Correlation Coefficient Test for
        Normality", Technometrics, Vol. 17, pp. 111-117, 1975.

        Examples
        --------
        First we generate some random data from a Weibull distribution
        with shape parameter 2.5, and plot the histogram of the data:

        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> rng = np.random.default_rng()
        >>> c = 2.5
        >>> x = stats.weibull_min.rvs(c, scale=4, size=2000, random_state=rng)

        Take a look at the histogram of the data.

        >>> fig1, ax = plt.subplots(figsize=(9, 4))
        >>> ax.hist(x, bins=50)
        >>> ax.set_title('Histogram of x')
        >>> plt.show()

        Now we explore this data with a PPCC plot as well as the related
        probability plot and Box-Cox normplot.  A red line is drawn where we
        expect the PPCC value to be maximal (at the shape parameter ``c``
        used above):

        >>> fig2 = plt.figure(figsize=(12, 4))
        >>> ax1 = fig2.add_subplot(1, 3, 1)
        >>> ax2 = fig2.add_subplot(1, 3, 2)
        >>> ax3 = fig2.add_subplot(1, 3, 3)
        >>> res = stats.probplot(x, plot=ax1)
        >>> res = stats.boxcox_normplot(x, -4, 4, plot=ax2)
        >>> res = stats.ppcc_plot(x, c/2, 2*c, dist='weibull_min', plot=ax3)
        >>> ax3.axvline(c, color='r')
        >>> plt.show()

    probplot(x, sparams=(), dist='norm', fit=True, plot=None, rvalue=False)
        Calculate quantiles for a probability plot, and optionally show the plot.

        Generates a probability plot of sample data against the quantiles of a
        specified theoretical distribution (the normal distribution by default).
        `probplot` optionally calculates a best-fit line for the data and plots the
        results using Matplotlib or a given plot function.

        Parameters
        ----------
        x : array_like
            Sample/response data from which `probplot` creates the plot.
        sparams : tuple, optional
            Distribution-specific shape parameters (shape parameters plus location
            and scale).
        dist : str or stats.distributions instance, optional
            Distribution or distribution function name. The default is 'norm' for a
            normal probability plot.  Objects that look enough like a
            stats.distributions instance (i.e. they have a ``ppf`` method) are also
            accepted.
        fit : bool, optional
            Fit a least-squares regression (best-fit) line to the sample data if
            True (default).
        plot : object, optional
            If given, plots the quantiles.
            If given and `fit` is True, also plots the least squares fit.
            `plot` is an object that has to have methods "plot" and "text".
            The `matplotlib.pyplot` module or a Matplotlib Axes object can be used,
            or a custom object with the same methods.
            Default is None, which means that no plot is created.
        rvalue : bool, optional
            If `plot` is provided and `fit` is True, setting `rvalue` to True
            includes the coefficient of determination on the plot.
            Default is False.

        Returns
        -------
        (osm, osr) : tuple of ndarrays
            Tuple of theoretical quantiles (osm, or order statistic medians) and
            ordered responses (osr).  `osr` is simply sorted input `x`.
            For details on how `osm` is calculated see the Notes section.
        (slope, intercept, r) : tuple of floats, optional
            Tuple  containing the result of the least-squares fit, if that is
            performed by `probplot`. `r` is the square root of the coefficient of
            determination.  If ``fit=False`` and ``plot=None``, this tuple is not
            returned.

        Notes
        -----
        Even if `plot` is given, the figure is not shown or saved by `probplot`;
        ``plt.show()`` or ``plt.savefig('figname.png')`` should be used after
        calling `probplot`.

        `probplot` generates a probability plot, which should not be confused with
        a Q-Q or a P-P plot.  Statsmodels has more extensive functionality of this
        type, see ``statsmodels.api.ProbPlot``.

        The formula used for the theoretical quantiles (horizontal axis of the
        probability plot) is Filliben's estimate::

            quantiles = dist.ppf(val), for

                    0.5**(1/n),                  for i = n
              val = (i - 0.3175) / (n + 0.365),  for i = 2, ..., n-1
                    1 - 0.5**(1/n),              for i = 1

        where ``i`` indicates the i-th ordered value and ``n`` is the total number
        of values.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> nsample = 100
        >>> rng = np.random.default_rng()

        A t distribution with small degrees of freedom:

        >>> ax1 = plt.subplot(221)
        >>> x = stats.t.rvs(3, size=nsample, random_state=rng)
        >>> res = stats.probplot(x, plot=plt)

        A t distribution with larger degrees of freedom:

        >>> ax2 = plt.subplot(222)
        >>> x = stats.t.rvs(25, size=nsample, random_state=rng)
        >>> res = stats.probplot(x, plot=plt)

        A mixture of two normal distributions with broadcasting:

        >>> ax3 = plt.subplot(223)
        >>> x = stats.norm.rvs(loc=[0,5], scale=[1,1.5],
        ...                    size=(nsample//2,2), random_state=rng).ravel()
        >>> res = stats.probplot(x, plot=plt)

        A standard normal distribution:

        >>> ax4 = plt.subplot(224)
        >>> x = stats.norm.rvs(loc=0, scale=1, size=nsample, random_state=rng)
        >>> res = stats.probplot(x, plot=plt)

        Produce a new figure with a loggamma distribution, using the ``dist`` and
        ``sparams`` keywords:

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> x = stats.loggamma.rvs(c=2.5, size=500, random_state=rng)
        >>> res = stats.probplot(x, dist=stats.loggamma, sparams=(2.5,), plot=ax)
        >>> ax.set_title("Probplot for loggamma dist with shape parameter 2.5")

        Show the results with Matplotlib:

        >>> plt.show()

    quantile_test(x, *, q=0, p=0.5, alternative='two-sided')
        Perform a quantile test and compute a confidence interval of the quantile.

        This function tests the null hypothesis that `q` is the value of the
        quantile associated with probability `p` of the population underlying
        sample `x`. For example, with default parameters, it tests that the
        median of the population underlying `x` is zero. The function returns an
        object including the test statistic, a p-value, and a method for computing
        the confidence interval around the quantile.

        Parameters
        ----------
        x : array_like
            A one-dimensional sample.
        q : float, default: 0
            The hypothesized value of the quantile.
        p : float, default: 0.5
            The probability associated with the quantile; i.e. the proportion of
            the population less than `q` is `p`. Must be strictly between 0 and
            1.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the quantile associated with the probability `p`
              is not `q`.
            * 'less': the quantile associated with the probability `p` is less
              than `q`.
            * 'greater': the quantile associated with the probability `p` is
              greater than `q`.

        Returns
        -------
        result : QuantileTestResult
            An object with the following attributes:

            statistic : float
                One of two test statistics that may be used in the quantile test.
                The first test statistic, ``T1``, is the proportion of samples in
                `x` that are less than or equal to the hypothesized quantile
                `q`. The second test statistic, ``T2``, is the proportion of
                samples in `x` that are strictly less than the hypothesized
                quantile `q`.

                When ``alternative = 'greater'``, ``T1`` is used to calculate the
                p-value and ``statistic`` is set to ``T1``.

                When ``alternative = 'less'``, ``T2`` is used to calculate the
                p-value and ``statistic`` is set to ``T2``.

                When ``alternative = 'two-sided'``, both ``T1`` and ``T2`` are
                considered, and the one that leads to the smallest p-value is used.

            statistic_type : int
                Either `1` or `2` depending on which of ``T1`` or ``T2`` was
                used to calculate the p-value.

            pvalue : float
                The p-value associated with the given alternative.

            The object also has the following method:

            confidence_interval(confidence_level=0.95)
                Computes a confidence interval around the the
                population quantile associated with the probability `p`. The
                confidence interval is returned in a ``namedtuple`` with
                fields `low` and `high`.  Values are `nan` when there are
                not enough observations to compute the confidence interval at
                the desired confidence.

        Notes
        -----
        This test and its method for computing confidence intervals are
        non-parametric. They are valid if and only if the observations are i.i.d.

        The implementation of the test follows Conover [1]_. Two test statistics
        are considered.

        ``T1``: The number of observations in `x` less than or equal to `q`.

            ``T1 = (x <= q).sum()``

        ``T2``: The number of observations in `x` strictly less than `q`.

            ``T2 = (x < q).sum()``

        The use of two test statistics is necessary to handle the possibility that
        `x` was generated from a discrete or mixed distribution.

        The null hypothesis for the test is:

            H0: The :math:`p^{\mathrm{th}}` population quantile is `q`.

        and the null distribution for each test statistic is
        :math:`\mathrm{binom}\left(n, p\right)`. When ``alternative='less'``,
        the alternative hypothesis is:

            H1: The :math:`p^{\mathrm{th}}` population quantile is less than `q`.

        and the p-value is the probability that the binomial random variable

        .. math::
            Y \sim \mathrm{binom}\left(n, p\right)

        is greater than or equal to the observed value ``T2``.

        When ``alternative='greater'``, the alternative hypothesis is:

            H1: The :math:`p^{\mathrm{th}}` population quantile is greater than `q`

        and the p-value is the probability that the binomial random variable Y
        is less than or equal to the observed value ``T1``.

        When ``alternative='two-sided'``, the alternative hypothesis is

            H1: `q` is not the :math:`p^{\mathrm{th}}` population quantile.

        and the p-value is twice the smaller of the p-values for the ``'less'``
        and ``'greater'`` cases. Both of these p-values can exceed 0.5 for the same
        data, so the value is clipped into the interval :math:`[0, 1]`.

        The approach for confidence intervals is attributed to Thompson [2]_ and
        later proven to be applicable to any set of i.i.d. samples [3]_. The
        computation is based on the observation that the probability of a quantile
        :math:`q` to be larger than any observations :math:`x_m (1\leq m \leq N)`
        can be computed as

        .. math::

            \mathbb{P}(x_m \leq q) = 1 - \sum_{k=0}^{m-1} \binom{N}{k}
            q^k(1-q)^{N-k}

        By default, confidence intervals are computed for a 95% confidence level.
        A common interpretation of a 95% confidence intervals is that if i.i.d.
        samples are drawn repeatedly from the same population and confidence
        intervals are formed each time, the confidence interval will contain the
        true value of the specified quantile in approximately 95% of trials.

        A similar function is available in the QuantileNPCI R package [4]_. The
        foundation is the same, but it computes the confidence interval bounds by
        doing interpolations between the sample values, whereas this function uses
        only sample values as bounds. Thus, ``quantile_test.confidence_interval``
        returns more conservative intervals (i.e., larger).

        The same computation of confidence intervals for quantiles is included in
        the confintr package [5]_.

        Two-sided confidence intervals are not guaranteed to be optimal; i.e.,
        there may exist a tighter interval that may contain the quantile of
        interest with probability larger than the confidence level.
        Without further assumption on the samples (e.g., the nature of the
        underlying distribution), the one-sided intervals are optimally tight.

        References
        ----------
        .. [1] W. J. Conover. Practical Nonparametric Statistics, 3rd Ed. 1999.
        .. [2] W. R. Thompson, "On Confidence Ranges for the Median and Other
           Expectation Distributions for Populations of Unknown Distribution
           Form," The Annals of Mathematical Statistics, vol. 7, no. 3,
           pp. 122-128, 1936, Accessed: Sep. 18, 2019. [Online]. Available:
           https://www.jstor.org/stable/2957563.
        .. [3] H. A. David and H. N. Nagaraja, "Order Statistics in Nonparametric
           Inference" in Order Statistics, John Wiley & Sons, Ltd, 2005, pp.
           159-170. Available:
           https://onlinelibrary.wiley.com/doi/10.1002/0471722162.ch7.
        .. [4] N. Hutson, A. Hutson, L. Yan, "QuantileNPCI: Nonparametric
           Confidence Intervals for Quantiles," R package,
           https://cran.r-project.org/package=QuantileNPCI
        .. [5] M. Mayer, "confintr: Confidence Intervals," R package,
           https://cran.r-project.org/package=confintr


        Examples
        --------

        Suppose we wish to test the null hypothesis that the median of a population
        is equal to 0.5. We choose a confidence level of 99%; that is, we will
        reject the null hypothesis in favor of the alternative if the p-value is
        less than 0.01.

        When testing random variates from the standard uniform distribution, which
        has a median of 0.5, we expect the data to be consistent with the null
        hypothesis most of the time.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng(6981396440634228121)
        >>> rvs = stats.uniform.rvs(size=100, random_state=rng)
        >>> stats.quantile_test(rvs, q=0.5, p=0.5)
        QuantileTestResult(statistic=45, statistic_type=1, pvalue=0.36820161732669576)

        As expected, the p-value is not below our threshold of 0.01, so
        we cannot reject the null hypothesis.

        When testing data from the standard *normal* distribution, which has a
        median of 0, we would expect the null hypothesis to be rejected.

        >>> rvs = stats.norm.rvs(size=100, random_state=rng)
        >>> stats.quantile_test(rvs, q=0.5, p=0.5)
        QuantileTestResult(statistic=67, statistic_type=2, pvalue=0.0008737198369123724)

        Indeed, the p-value is lower than our threshold of 0.01, so we reject the
        null hypothesis in favor of the default "two-sided" alternative: the median
        of the population is *not* equal to 0.5.

        However, suppose we were to test the null hypothesis against the
        one-sided alternative that the median of the population is *greater* than
        0.5. Since the median of the standard normal is less than 0.5, we would not
        expect the null hypothesis to be rejected.

        >>> stats.quantile_test(rvs, q=0.5, p=0.5, alternative='greater')
        QuantileTestResult(statistic=67, statistic_type=1, pvalue=0.9997956114162866)

        Unsurprisingly, with a p-value greater than our threshold, we would not
        reject the null hypothesis in favor of the chosen alternative.

        The quantile test can be used for any quantile, not only the median. For
        example, we can test whether the third quartile of the distribution
        underlying the sample is greater than 0.6.

        >>> rvs = stats.uniform.rvs(size=100, random_state=rng)
        >>> stats.quantile_test(rvs, q=0.6, p=0.75, alternative='greater')
        QuantileTestResult(statistic=64, statistic_type=1, pvalue=0.00940696592998271)

        The p-value is lower than the threshold. We reject the null hypothesis in
        favor of the alternative: the third quartile of the distribution underlying
        our sample is greater than 0.6.

        `quantile_test` can also compute confidence intervals for any quantile.

        >>> rvs = stats.norm.rvs(size=100, random_state=rng)
        >>> res = stats.quantile_test(rvs, q=0.6, p=0.75)
        >>> ci = res.confidence_interval(confidence_level=0.95)
        >>> ci
        ConfidenceInterval(low=0.284491604437432, high=0.8912531024914844)

        When testing a one-sided alternative, the confidence interval contains
        all observations such that if passed as `q`, the p-value of the
        test would be greater than 0.05, and therefore the null hypothesis
        would not be rejected. For example:

        >>> rvs.sort()
        >>> q, p, alpha = 0.6, 0.75, 0.95
        >>> res = stats.quantile_test(rvs, q=q, p=p, alternative='less')
        >>> ci = res.confidence_interval(confidence_level=alpha)
        >>> for x in rvs[rvs <= ci.high]:
        ...     res = stats.quantile_test(rvs, q=x, p=p, alternative='less')
        ...     assert res.pvalue > 1-alpha
        >>> for x in rvs[rvs > ci.high]:
        ...     res = stats.quantile_test(rvs, q=x, p=p, alternative='less')
        ...     assert res.pvalue < 1-alpha

        Also, if a 95% confidence interval is repeatedly generated for random
        samples, the confidence interval will contain the true quantile value in
        approximately 95% of replications.

        >>> dist = stats.rayleigh() # our "unknown" distribution
        >>> p = 0.2
        >>> true_stat = dist.ppf(p) # the true value of the statistic
        >>> n_trials = 1000
        >>> quantile_ci_contains_true_stat = 0
        >>> for i in range(n_trials):
        ...     data = dist.rvs(size=100, random_state=rng)
        ...     res = stats.quantile_test(data, p=p)
        ...     ci = res.confidence_interval(0.95)
        ...     if ci[0] < true_stat < ci[1]:
        ...         quantile_ci_contains_true_stat += 1
        >>> quantile_ci_contains_true_stat >= 950
        True

        This works with any distribution and any quantile, as long as the samples
        are i.i.d.

    rankdata(a, method='average', *, axis=None, nan_policy='propagate')
        Assign ranks to data, dealing with ties appropriately.

        By default (``axis=None``), the data array is first flattened, and a flat
        array of ranks is returned. Separately reshape the rank array to the
        shape of the data array if desired (see Examples).

        Ranks begin at 1.  The `method` argument controls how ranks are assigned
        to equal values.  See [1]_ for further discussion of ranking methods.

        Parameters
        ----------
        a : array_like
            The array of values to be ranked.
        method : {'average', 'min', 'max', 'dense', 'ordinal'}, optional
            The method used to assign ranks to tied elements.
            The following methods are available (default is 'average'):

              * 'average': The average of the ranks that would have been assigned to
                all the tied values is assigned to each value.
              * 'min': The minimum of the ranks that would have been assigned to all
                the tied values is assigned to each value.  (This is also
                referred to as "competition" ranking.)
              * 'max': The maximum of the ranks that would have been assigned to all
                the tied values is assigned to each value.
              * 'dense': Like 'min', but the rank of the next highest element is
                assigned the rank immediately after those assigned to the tied
                elements.
              * 'ordinal': All values are given a distinct rank, corresponding to
                the order that the values occur in `a`.
        axis : {None, int}, optional
            Axis along which to perform the ranking. If ``None``, the data array
            is first flattened.
        nan_policy : {'propagate', 'omit', 'raise'}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is 'propagate'):

              * 'propagate': propagates nans through the rank calculation
              * 'omit': performs the calculations ignoring nan values
              * 'raise': raises an error

            .. note::

                When `nan_policy` is 'propagate', the output is an array of *all*
                nans because ranks relative to nans in the input are undefined.
                When `nan_policy` is 'omit', nans in `a` are ignored when ranking
                the other values, and the corresponding locations of the output
                are nan.

            .. versionadded:: 1.10

        Returns
        -------
        ranks : ndarray
             An array of size equal to the size of `a`, containing rank
             scores.

        References
        ----------
        .. [1] "Ranking", https://en.wikipedia.org/wiki/Ranking

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import rankdata
        >>> rankdata([0, 2, 3, 2])
        array([ 1. ,  2.5,  4. ,  2.5])
        >>> rankdata([0, 2, 3, 2], method='min')
        array([ 1,  2,  4,  2])
        >>> rankdata([0, 2, 3, 2], method='max')
        array([ 1,  3,  4,  3])
        >>> rankdata([0, 2, 3, 2], method='dense')
        array([ 1,  2,  3,  2])
        >>> rankdata([0, 2, 3, 2], method='ordinal')
        array([ 1,  2,  4,  3])
        >>> rankdata([[0, 2], [3, 2]]).reshape(2,2)
        array([[1. , 2.5],
              [4. , 2.5]])
        >>> rankdata([[0, 2, 2], [3, 2, 5]], axis=1)
        array([[1. , 2.5, 2.5],
               [2. , 1. , 3. ]])
        >>> rankdata([0, 2, 3, np.nan, -2, np.nan], nan_policy="propagate")
        array([nan, nan, nan, nan, nan, nan])
        >>> rankdata([0, 2, 3, np.nan, -2, np.nan], nan_policy="omit")
        array([ 2.,  3.,  4., nan,  1., nan])

    ranksums(x, y, alternative='two-sided', *, axis=0, nan_policy='propagate', keepdims=False)
        Compute the Wilcoxon rank-sum statistic for two samples.

        The Wilcoxon rank-sum test tests the null hypothesis that two sets
        of measurements are drawn from the same distribution.  The alternative
        hypothesis is that values in one sample are more likely to be
        larger than the values in the other sample.

        This test should be used to compare two samples from continuous
        distributions.  It does not handle ties between measurements
        in x and y.  For tie-handling and an optional continuity correction
        see `scipy.stats.mannwhitneyu`.

        Parameters
        ----------
        x,y : array_like
            The data from the two samples.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': one of the distributions (underlying `x` or `y`) is
              stochastically greater than the other.
            * 'less': the distribution underlying `x` is stochastically less
              than the distribution underlying `y`.
            * 'greater': the distribution underlying `x` is stochastically greater
              than the distribution underlying `y`.

            .. versionadded:: 1.7.0
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic under the large-sample approximation that the
            rank sum statistic is normally distributed.
        pvalue : float
            The p-value of the test.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Wilcoxon_rank-sum_test

        Examples
        --------
        We can test the hypothesis that two independent unequal-sized samples are
        drawn from the same distribution with computing the Wilcoxon rank-sum
        statistic.

        >>> import numpy as np
        >>> from scipy.stats import ranksums
        >>> rng = np.random.default_rng()
        >>> sample1 = rng.uniform(-1, 1, 200)
        >>> sample2 = rng.uniform(-0.5, 1.5, 300) # a shifted distribution
        >>> ranksums(sample1, sample2)
        RanksumsResult(statistic=-7.887059,
                       pvalue=3.09390448e-15) # may vary
        >>> ranksums(sample1, sample2, alternative='less')
        RanksumsResult(statistic=-7.750585297581713,
                       pvalue=4.573497606342543e-15) # may vary
        >>> ranksums(sample1, sample2, alternative='greater')
        RanksumsResult(statistic=-7.750585297581713,
                       pvalue=0.9999999999999954) # may vary

        The p-value of less than ``0.05`` indicates that this test rejects the
        hypothesis at the 5% significance level.

    relfreq(a, numbins=10, defaultreallimits=None, weights=None)
        Return a relative frequency histogram, using the histogram function.

        A relative frequency  histogram is a mapping of the number of
        observations in each of the bins relative to the total of observations.

        Parameters
        ----------
        a : array_like
            Input array.
        numbins : int, optional
            The number of bins to use for the histogram. Default is 10.
        defaultreallimits : tuple (lower, upper), optional
            The lower and upper values for the range of the histogram.
            If no value is given, a range slightly larger than the range of the
            values in a is used. Specifically ``(a.min() - s, a.max() + s)``,
            where ``s = (1/2)(a.max() - a.min()) / (numbins - 1)``.
        weights : array_like, optional
            The weights for each value in `a`. Default is None, which gives each
            value a weight of 1.0

        Returns
        -------
        frequency : ndarray
            Binned values of relative frequency.
        lowerlimit : float
            Lower real limit.
        binsize : float
            Width of each bin.
        extrapoints : int
            Extra points.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> a = np.array([2, 4, 1, 2, 3, 2])
        >>> res = stats.relfreq(a, numbins=4)
        >>> res.frequency
        array([ 0.16666667, 0.5       , 0.16666667,  0.16666667])
        >>> np.sum(res.frequency)  # relative frequencies should add up to 1
        1.0

        Create a normal distribution with 1000 random values

        >>> samples = stats.norm.rvs(size=1000, random_state=rng)

        Calculate relative frequencies

        >>> res = stats.relfreq(samples, numbins=25)

        Calculate space of values for x

        >>> x = res.lowerlimit + np.linspace(0, res.binsize*res.frequency.size,
        ...                                  res.frequency.size)

        Plot relative frequency histogram

        >>> fig = plt.figure(figsize=(5, 4))
        >>> ax = fig.add_subplot(1, 1, 1)
        >>> ax.bar(x, res.frequency, width=res.binsize)
        >>> ax.set_title('Relative frequency histogram')
        >>> ax.set_xlim([x.min(), x.max()])

        >>> plt.show()

    rvs_ratio_uniforms(pdf, umax, vmin, vmax, size=1, c=0, random_state=None)
        Generate random samples from a probability density function using the
        ratio-of-uniforms method.

        .. deprecated:: 1.12.0
            `rvs_ratio_uniforms` is deprecated in favour of
            `scipy.stats.sampling.RatioUniforms` from version 1.12.0 and will
            be removed in SciPy 1.15.0

        Parameters
        ----------
        pdf : callable
            A function with signature `pdf(x)` that is proportional to the
            probability density function of the distribution.
        umax : float
            The upper bound of the bounding rectangle in the u-direction.
        vmin : float
            The lower bound of the bounding rectangle in the v-direction.
        vmax : float
            The upper bound of the bounding rectangle in the v-direction.
        size : int or tuple of ints, optional
            Defining number of random variates (default is 1).
        c : float, optional.
            Shift parameter of ratio-of-uniforms method, see Notes. Default is 0.
        random_state : {None, int, `numpy.random.Generator`,
                        `numpy.random.RandomState`}, optional

            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

        Returns
        -------
        rvs : ndarray
            The random variates distributed according to the probability
            distribution defined by the pdf.

        Notes
        -----
        Please refer to `scipy.stats.sampling.RatioUniforms` for the documentation.

    scoreatpercentile(a, per, limit=(), interpolation_method='fraction', axis=None)
        Calculate the score at a given percentile of the input sequence.

        For example, the score at `per=50` is the median. If the desired quantile
        lies between two data points, we interpolate between them, according to
        the value of `interpolation`. If the parameter `limit` is provided, it
        should be a tuple (lower, upper) of two values.

        Parameters
        ----------
        a : array_like
            A 1-D array of values from which to extract score.
        per : array_like
            Percentile(s) at which to extract score.  Values should be in range
            [0,100].
        limit : tuple, optional
            Tuple of two scalars, the lower and upper limits within which to
            compute the percentile. Values of `a` outside
            this (closed) interval will be ignored.
        interpolation_method : {'fraction', 'lower', 'higher'}, optional
            Specifies the interpolation method to use,
            when the desired quantile lies between two data points `i` and `j`
            The following options are available (default is 'fraction'):

              * 'fraction': ``i + (j - i) * fraction`` where ``fraction`` is the
                fractional part of the index surrounded by ``i`` and ``j``
              * 'lower': ``i``
              * 'higher': ``j``

        axis : int, optional
            Axis along which the percentiles are computed. Default is None. If
            None, compute over the whole array `a`.

        Returns
        -------
        score : float or ndarray
            Score at percentile(s).

        See Also
        --------
        percentileofscore, numpy.percentile

        Notes
        -----
        This function will become obsolete in the future.
        For NumPy 1.9 and higher, `numpy.percentile` provides all the functionality
        that `scoreatpercentile` provides.  And it's significantly faster.
        Therefore it's recommended to use `numpy.percentile` for users that have
        numpy >= 1.9.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> a = np.arange(100)
        >>> stats.scoreatpercentile(a, 50)
        49.5

    sem(a, axis=0, ddof=1, nan_policy='propagate', *, keepdims=False)
        Compute standard error of the mean.

        Calculate the standard error of the mean (or standard error of
        measurement) of the values in the input array.

        Parameters
        ----------
        a : array_like
            An array containing the values for which the standard error is
            returned. Must contain at least two observations.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        ddof : int, optional
            Delta degrees-of-freedom. How many degrees of freedom to adjust
            for bias in limited samples relative to the population estimate
            of variance. Defaults to 1.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        s : ndarray or float
            The standard error of the mean in the sample(s), along the input axis.

        Notes
        -----
        The default value for `ddof` is different to the default (0) used by other
        ddof containing routines, such as np.std and np.nanstd.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        Find standard error along the first axis:

        >>> import numpy as np
        >>> from scipy import stats
        >>> a = np.arange(20).reshape(5,4)
        >>> stats.sem(a)
        array([ 2.8284,  2.8284,  2.8284,  2.8284])

        Find standard error across the whole array, using n degrees of freedom:

        >>> stats.sem(a, axis=None, ddof=0)
        1.2893796958227628

    shapiro(x, *, axis=None, nan_policy='propagate', keepdims=False)
        Perform the Shapiro-Wilk test for normality.

        The Shapiro-Wilk test tests the null hypothesis that the
        data was drawn from a normal distribution.

        Parameters
        ----------
        x : array_like
            Array of sample data. Must contain at least three observations.
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The test statistic.
        p-value : float
            The p-value for the hypothesis test.

        See Also
        --------

        :func:`anderson`
            The Anderson-Darling test for normality
        :func:`kstest`
            The Kolmogorov-Smirnov test for goodness of fit.


        Notes
        -----
        The algorithm used is described in [4]_ but censoring parameters as
        described are not implemented. For N > 5000 the W test statistic is
        accurate, but the p-value may not be.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://www.itl.nist.gov/div898/handbook/prc/section2/prc213.htm
               :doi:`10.18434/M32189`
        .. [2] Shapiro, S. S. & Wilk, M.B, "An analysis of variance test for
               normality (complete samples)", Biometrika, 1965, Vol. 52,
               pp. 591-611, :doi:`10.2307/2333709`
        .. [3] Razali, N. M. & Wah, Y. B., "Power comparisons of Shapiro-Wilk,
               Kolmogorov-Smirnov, Lilliefors and Anderson-Darling tests", Journal
               of Statistical Modeling and Analytics, 2011, Vol. 2, pp. 21-33.
        .. [4] Royston P., "Remark AS R94: A Remark on Algorithm AS 181: The
               W-test for Normality", 1995, Applied Statistics, Vol. 44,
               :doi:`10.2307/2986146`
        .. [5] Phipson B., and Smyth, G. K., "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn", Statistical Applications in Genetics and Molecular Biology,
               2010, Vol.9, :doi:`10.2202/1544-6115.1585`
        .. [6] Panagiotakos, D. B., "The value of p-value in biomedical
               research", The Open Cardiovascular Medicine Journal, 2008, Vol.2,
               pp. 97-99, :doi:`10.2174/1874192400802010097`

        Examples
        --------
        Suppose we wish to infer from measurements whether the weights of adult
        human males in a medical study are not normally distributed [2]_.
        The weights (lbs) are recorded in the array ``x`` below.

        >>> import numpy as np
        >>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

        The normality test of [1]_ and [2]_ begins by computing a statistic based
        on the relationship between the observations and the expected order
        statistics of a normal distribution.

        >>> from scipy import stats
        >>> res = stats.shapiro(x)
        >>> res.statistic
        0.7888147830963135

        The value of this statistic tends to be high (close to 1) for samples drawn
        from a normal distribution.

        The test is performed by comparing the observed value of the statistic
        against the null distribution: the distribution of statistic values formed
        under the null hypothesis that the weights were drawn from a normal
        distribution. For this normality test, the null distribution is not easy to
        calculate exactly, so it is usually approximated by Monte Carlo methods,
        that is, drawing many samples of the same size as ``x`` from a normal
        distribution and computing the values of the statistic for each.

        >>> def statistic(x):
        ...     # Get only the `shapiro` statistic; ignore its p-value
        ...     return stats.shapiro(x).statistic
        >>> ref = stats.monte_carlo_test(x, stats.norm.rvs, statistic,
        ...                              alternative='less')
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> bins = np.linspace(0.65, 1, 50)
        >>> def plot(ax):  # we'll reuse this
        ...     ax.hist(ref.null_distribution, density=True, bins=bins)
        ...     ax.set_title("Shapiro-Wilk Test Null Distribution \n"
        ...                  "(Monte Carlo Approximation, 11 Observations)")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution less than or equal to the observed value of the
        statistic.

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> annotation = (f'p-value={res.pvalue:.6f}\n(highlighted area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (0.75, 0.1), (0.68, 0.7), arrowprops=props)
        >>> i_extreme = np.where(bins <= res.statistic)[0]
        >>> for i in i_extreme:
        ...     ax.patches[i].set_color('C1')
        >>> plt.xlim(0.65, 0.9)
        >>> plt.ylim(0, 4)
        >>> plt.show
        >>> res.pvalue
        0.006703833118081093

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from a normally distributed population that produces such an
        extreme value of the statistic - this may be taken as evidence against
        the null hypothesis in favor of the alternative: the weights were not
        drawn from a normal distribution. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence *for* the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [5]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).

    siegelslopes(y, x=None, method='hierarchical')
        Computes the Siegel estimator for a set of points (x, y).

        `siegelslopes` implements a method for robust linear regression
        using repeated medians (see [1]_) to fit a line to the points (x, y).
        The method is robust to outliers with an asymptotic breakdown point
        of 50%.

        Parameters
        ----------
        y : array_like
            Dependent variable.
        x : array_like or None, optional
            Independent variable. If None, use ``arange(len(y))`` instead.
        method : {'hierarchical', 'separate'}
            If 'hierarchical', estimate the intercept using the estimated
            slope ``slope`` (default option).
            If 'separate', estimate the intercept independent of the estimated
            slope. See Notes for details.

        Returns
        -------
        result : ``SiegelslopesResult`` instance
            The return value is an object with the following attributes:

            slope : float
                Estimate of the slope of the regression line.
            intercept : float
                Estimate of the intercept of the regression line.

        See Also
        --------
        theilslopes : a similar technique without repeated medians

        Notes
        -----
        With ``n = len(y)``, compute ``m_j`` as the median of
        the slopes from the point ``(x[j], y[j])`` to all other `n-1` points.
        ``slope`` is then the median of all slopes ``m_j``.
        Two ways are given to estimate the intercept in [1]_ which can be chosen
        via the parameter ``method``.
        The hierarchical approach uses the estimated slope ``slope``
        and computes ``intercept`` as the median of ``y - slope*x``.
        The other approach estimates the intercept separately as follows: for
        each point ``(x[j], y[j])``, compute the intercepts of all the `n-1`
        lines through the remaining points and take the median ``i_j``.
        ``intercept`` is the median of the ``i_j``.

        The implementation computes `n` times the median of a vector of size `n`
        which can be slow for large vectors. There are more efficient algorithms
        (see [2]_) which are not implemented here.

        For compatibility with older versions of SciPy, the return value acts
        like a ``namedtuple`` of length 2, with fields ``slope`` and
        ``intercept``, so one can continue to write::

            slope, intercept = siegelslopes(y, x)

        References
        ----------
        .. [1] A. Siegel, "Robust Regression Using Repeated Medians",
               Biometrika, Vol. 69, pp. 242-244, 1982.

        .. [2] A. Stein and M. Werman, "Finding the repeated median regression
               line", Proceedings of the Third Annual ACM-SIAM Symposium on
               Discrete Algorithms, pp. 409-413, 1992.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(-5, 5, num=150)
        >>> y = x + np.random.normal(size=x.size)
        >>> y[11:15] += 10  # add outliers
        >>> y[-5:] -= 7

        Compute the slope and intercept.  For comparison, also compute the
        least-squares fit with `linregress`:

        >>> res = stats.siegelslopes(y, x)
        >>> lsq_res = stats.linregress(x, y)

        Plot the results. The Siegel regression line is shown in red. The green
        line shows the least-squares fit for comparison.

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, y, 'b.')
        >>> ax.plot(x, res[1] + res[0] * x, 'r-')
        >>> ax.plot(x, lsq_res[1] + lsq_res[0] * x, 'g-')
        >>> plt.show()

    sigmaclip(a, low=4.0, high=4.0)
        Perform iterative sigma-clipping of array elements.

        Starting from the full sample, all elements outside the critical range are
        removed, i.e. all elements of the input array `c` that satisfy either of
        the following conditions::

            c < mean(c) - std(c)*low
            c > mean(c) + std(c)*high

        The iteration continues with the updated sample until no
        elements are outside the (updated) range.

        Parameters
        ----------
        a : array_like
            Data array, will be raveled if not 1-D.
        low : float, optional
            Lower bound factor of sigma clipping. Default is 4.
        high : float, optional
            Upper bound factor of sigma clipping. Default is 4.

        Returns
        -------
        clipped : ndarray
            Input array with clipped elements removed.
        lower : float
            Lower threshold value use for clipping.
        upper : float
            Upper threshold value use for clipping.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import sigmaclip
        >>> a = np.concatenate((np.linspace(9.5, 10.5, 31),
        ...                     np.linspace(0, 20, 5)))
        >>> fact = 1.5
        >>> c, low, upp = sigmaclip(a, fact, fact)
        >>> c
        array([  9.96666667,  10.        ,  10.03333333,  10.        ])
        >>> c.var(), c.std()
        (0.00055555555555555165, 0.023570226039551501)
        >>> low, c.mean() - fact*c.std(), c.min()
        (9.9646446609406727, 9.9646446609406727, 9.9666666666666668)
        >>> upp, c.mean() + fact*c.std(), c.max()
        (10.035355339059327, 10.035355339059327, 10.033333333333333)

        >>> a = np.concatenate((np.linspace(9.5, 10.5, 11),
        ...                     np.linspace(-100, -50, 3)))
        >>> c, low, upp = sigmaclip(a, 1.8, 1.8)
        >>> (c == np.linspace(9.5, 10.5, 11)).all()
        True

    skew(a, axis=0, bias=True, nan_policy='propagate', *, keepdims=False)
        Compute the sample skewness of a data set.

        For normally distributed data, the skewness should be about zero. For
        unimodal continuous distributions, a skewness value greater than zero means
        that there is more weight in the right tail of the distribution. The
        function `skewtest` can be used to determine if the skewness value
        is close enough to zero, statistically speaking.

        Parameters
        ----------
        a : ndarray
            Input array.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        bias : bool, optional
            If False, then the calculations are corrected for statistical bias.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        skewness : ndarray
            The skewness of values along an axis, returning NaN where all values
            are equal.

        Notes
        -----
        The sample skewness is computed as the Fisher-Pearson coefficient
        of skewness, i.e.

        .. math::

            g_1=\frac{m_3}{m_2^{3/2}}

        where

        .. math::

            m_i=\frac{1}{N}\sum_{n=1}^N(x[n]-\bar{x})^i

        is the biased sample :math:`i\texttt{th}` central moment, and
        :math:`\bar{x}` is
        the sample mean.  If ``bias`` is False, the calculations are
        corrected for bias and the value computed is the adjusted
        Fisher-Pearson standardized moment coefficient, i.e.

        .. math::

            G_1=\frac{k_3}{k_2^{3/2}}=
                \frac{\sqrt{N(N-1)}}{N-2}\frac{m_3}{m_2^{3/2}}.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Zwillinger, D. and Kokoska, S. (2000). CRC Standard
           Probability and Statistics Tables and Formulae. Chapman & Hall: New
           York. 2000.
           Section 2.2.24.1

        Examples
        --------
        >>> from scipy.stats import skew
        >>> skew([1, 2, 3, 4, 5])
        0.0
        >>> skew([2, 8, 0, 4, 1, 9, 9, 0])
        0.2650554122698573

    skewtest(a, axis=0, nan_policy='propagate', alternative='two-sided', *, keepdims=False)
        Test whether the skew is different from the normal distribution.

        This function tests the null hypothesis that the skewness of
        the population that the sample was drawn from is the same
        as that of a corresponding normal distribution.

        Parameters
        ----------
        a : array
            The data to be tested. Must contain at least eight observations.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the skewness of the distribution underlying the sample
              is different from that of the normal distribution (i.e. 0)
            * 'less': the skewness of the distribution underlying the sample
              is less than that of the normal distribution
            * 'greater': the skewness of the distribution underlying the sample
              is greater than that of the normal distribution

            .. versionadded:: 1.7.0
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        statistic : float
            The computed z-score for this test.
        pvalue : float
            The p-value for the hypothesis test.

        Notes
        -----
        The sample size must be at least 8.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] R. B. D'Agostino, A. J. Belanger and R. B. D'Agostino Jr.,
                "A suggestion for using powerful and informative tests of
                normality", American Statistician 44, pp. 316-321, 1990.
        .. [2] Shapiro, S. S., & Wilk, M. B. (1965). An analysis of variance test
               for normality (complete samples). Biometrika, 52(3/4), 591-611.
        .. [3] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
               Zero: Calculating Exact P-values When Permutations Are Randomly
               Drawn." Statistical Applications in Genetics and Molecular Biology
               9.1 (2010).

        Examples
        --------
        Suppose we wish to infer from measurements whether the weights of adult
        human males in a medical study are not normally distributed [2]_.
        The weights (lbs) are recorded in the array ``x`` below.

        >>> import numpy as np
        >>> x = np.array([148, 154, 158, 160, 161, 162, 166, 170, 182, 195, 236])

        The skewness test from [1]_ begins by computing a statistic based on the
        sample skewness.

        >>> from scipy import stats
        >>> res = stats.skewtest(x)
        >>> res.statistic
        2.7788579769903414

        Because normal distributions have zero skewness, the magnitude of this
        statistic tends to be low for samples drawn from a normal distribution.

        The test is performed by comparing the observed value of the
        statistic against the null distribution: the distribution of statistic
        values derived under the null hypothesis that the weights were drawn from
        a normal distribution.

        For this test, the null distribution of the statistic for very large
        samples is the standard normal distribution.

        >>> import matplotlib.pyplot as plt
        >>> dist = stats.norm()
        >>> st_val = np.linspace(-5, 5, 100)
        >>> pdf = dist.pdf(st_val)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def st_plot(ax):  # we'll reuse this
        ...     ax.plot(st_val, pdf)
        ...     ax.set_title("Skew Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> st_plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution as extreme or more extreme than the observed
        value of the statistic. In a two-sided test, elements of the null
        distribution greater than the observed statistic and elements of the null
        distribution less than the negative of the observed statistic are both
        considered "more extreme".

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> st_plot(ax)
        >>> pvalue = dist.cdf(-res.statistic) + dist.sf(res.statistic)
        >>> annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (3, 0.005), (3.25, 0.02), arrowprops=props)
        >>> i = st_val >= res.statistic
        >>> ax.fill_between(st_val[i], y1=0, y2=pdf[i], color='C0')
        >>> i = st_val <= -res.statistic
        >>> ax.fill_between(st_val[i], y1=0, y2=pdf[i], color='C0')
        >>> ax.set_xlim(-5, 5)
        >>> ax.set_ylim(0, 0.1)
        >>> plt.show()
        >>> res.pvalue
        0.005455036974740185

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from a normally distributed population that produces such an
        extreme value of the statistic - this may be taken as evidence against
        the null hypothesis in favor of the alternative: the weights were not
        drawn from a normal distribution. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [3]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).

        Note that the standard normal distribution provides an asymptotic
        approximation of the null distribution; it is only accurate for samples
        with many observations. For small samples like ours,
        `scipy.stats.monte_carlo_test` may provide a more accurate, albeit
        stochastic, approximation of the exact p-value.

        >>> def statistic(x, axis):
        ...     # get just the skewtest statistic; ignore the p-value
        ...     return stats.skewtest(x, axis=axis).statistic
        >>> res = stats.monte_carlo_test(x, stats.norm.rvs, statistic)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> st_plot(ax)
        >>> ax.hist(res.null_distribution, np.linspace(-5, 5, 50),
        ...         density=True)
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            'Monte Carlo approximation\n(11 observations)'])
        >>> plt.show()
        >>> res.pvalue
        0.0062  # may vary

        In this case, the asymptotic approximation and Monte Carlo approximation
        agree fairly closely, even for our small sample.

    sobol_indices(*, func: "Callable[[np.ndarray], npt.ArrayLike] | dict[Literal['f_A', 'f_B', 'f_AB'], np.ndarray]", n: 'IntNumber', dists: 'list[PPFDist] | None' = None, method: "Callable | Literal['saltelli_2010']" = 'saltelli_2010', random_state: 'SeedType' = None) -> 'SobolResult'
        Global sensitivity indices of Sobol'.

        Parameters
        ----------
        func : callable or dict(str, array_like)
            If `func` is a callable, function to compute the Sobol' indices from.
            Its signature must be::

                func(x: ArrayLike) -> ArrayLike

            with ``x`` of shape ``(d, n)`` and output of shape ``(s, n)`` where:

            - ``d`` is the input dimensionality of `func`
              (number of input variables),
            - ``s`` is the output dimensionality of `func`
              (number of output variables), and
            - ``n`` is the number of samples (see `n` below).

            Function evaluation values must be finite.

            If `func` is a dictionary, contains the function evaluations from three
            different arrays. Keys must be: ``f_A``, ``f_B`` and ``f_AB``.
            ``f_A`` and ``f_B`` should have a shape ``(s, n)`` and ``f_AB``
            should have a shape ``(d, s, n)``.
            This is an advanced feature and misuse can lead to wrong analysis.
        n : int
            Number of samples used to generate the matrices ``A`` and ``B``.
            Must be a power of 2. The total number of points at which `func` is
            evaluated will be ``n*(d+2)``.
        dists : list(distributions), optional
            List of each parameter's distribution. The distribution of parameters
            depends on the application and should be carefully chosen.
            Parameters are assumed to be independently distributed, meaning there
            is no constraint nor relationship between their values.

            Distributions must be an instance of a class with a ``ppf``
            method.

            Must be specified if `func` is a callable, and ignored otherwise.
        method : Callable or str, default: 'saltelli_2010'
            Method used to compute the first and total Sobol' indices.

            If a callable, its signature must be::

                func(f_A: np.ndarray, f_B: np.ndarray, f_AB: np.ndarray)
                -> Tuple[np.ndarray, np.ndarray]

            with ``f_A, f_B`` of shape ``(s, n)`` and ``f_AB`` of shape
            ``(d, s, n)``.
            These arrays contain the function evaluations from three different sets
            of samples.
            The output is a tuple of the first and total indices with
            shape ``(s, d)``.
            This is an advanced feature and misuse can lead to wrong analysis.
        random_state : {None, int, `numpy.random.Generator`}, optional
            If `random_state` is an int or None, a new `numpy.random.Generator` is
            created using ``np.random.default_rng(random_state)``.
            If `random_state` is already a ``Generator`` instance, then the
            provided instance is used.

        Returns
        -------
        res : SobolResult
            An object with attributes:

            first_order : ndarray of shape (s, d)
                First order Sobol' indices.
            total_order : ndarray of shape (s, d)
                Total order Sobol' indices.

            And method:

            bootstrap(confidence_level: float, n_resamples: int)
            -> BootstrapSobolResult

                A method providing confidence intervals on the indices.
                See `scipy.stats.bootstrap` for more details.

                The bootstrapping is done on both first and total order indices,
                and they are available in `BootstrapSobolResult` as attributes
                ``first_order`` and ``total_order``.

        Notes
        -----
        The Sobol' method [1]_, [2]_ is a variance-based Sensitivity Analysis which
        obtains the contribution of each parameter to the variance of the
        quantities of interest (QoIs; i.e., the outputs of `func`).
        Respective contributions can be used to rank the parameters and
        also gauge the complexity of the model by computing the
        model's effective (or mean) dimension.

        .. note::

            Parameters are assumed to be independently distributed. Each
            parameter can still follow any distribution. In fact, the distribution
            is very important and should match the real distribution of the
            parameters.

        It uses a functional decomposition of the variance of the function to
        explore

        .. math::

            \mathbb{V}(Y) = \sum_{i}^{d} \mathbb{V}_i (Y) + \sum_{i<j}^{d}
            \mathbb{V}_{ij}(Y) + ... + \mathbb{V}_{1,2,...,d}(Y),

        introducing conditional variances:

        .. math::

            \mathbb{V}_i(Y) = \mathbb{\mathbb{V}}[\mathbb{E}(Y|x_i)]
            \qquad
            \mathbb{V}_{ij}(Y) = \mathbb{\mathbb{V}}[\mathbb{E}(Y|x_i x_j)]
            - \mathbb{V}_i(Y) - \mathbb{V}_j(Y),

        Sobol' indices are expressed as

        .. math::

            S_i = \frac{\mathbb{V}_i(Y)}{\mathbb{V}[Y]}
            \qquad
            S_{ij} =\frac{\mathbb{V}_{ij}(Y)}{\mathbb{V}[Y]}.

        :math:`S_{i}` corresponds to the first-order term which apprises the
        contribution of the i-th parameter, while :math:`S_{ij}` corresponds to the
        second-order term which informs about the contribution of interactions
        between the i-th and the j-th parameters. These equations can be
        generalized to compute higher order terms; however, they are expensive to
        compute and their interpretation is complex.
        This is why only first order indices are provided.

        Total order indices represent the global contribution of the parameters
        to the variance of the QoI and are defined as:

        .. math::

            S_{T_i} = S_i + \sum_j S_{ij} + \sum_{j,k} S_{ijk} + ...
            = 1 - \frac{\mathbb{V}[\mathbb{E}(Y|x_{\sim i})]}{\mathbb{V}[Y]}.

        First order indices sum to at most 1, while total order indices sum to at
        least 1. If there are no interactions, then first and total order indices
        are equal, and both first and total order indices sum to 1.

        .. warning::

            Negative Sobol' values are due to numerical errors. Increasing the
            number of points `n` should help.

            The number of sample required to have a good analysis increases with
            the dimensionality of the problem. e.g. for a 3 dimension problem,
            consider at minima ``n >= 2**12``. The more complex the model is,
            the more samples will be needed.

            Even for a purely addiditive model, the indices may not sum to 1 due
            to numerical noise.

        References
        ----------
        .. [1] Sobol, I. M.. "Sensitivity analysis for nonlinear mathematical
           models." Mathematical Modeling and Computational Experiment, 1:407-414,
           1993.
        .. [2] Sobol, I. M. (2001). "Global sensitivity indices for nonlinear
           mathematical models and their Monte Carlo estimates." Mathematics
           and Computers in Simulation, 55(1-3):271-280,
           :doi:`10.1016/S0378-4754(00)00270-6`, 2001.
        .. [3] Saltelli, A. "Making best use of model evaluations to
           compute sensitivity indices."  Computer Physics Communications,
           145(2):280-297, :doi:`10.1016/S0010-4655(02)00280-1`, 2002.
        .. [4] Saltelli, A., M. Ratto, T. Andres, F. Campolongo, J. Cariboni,
           D. Gatelli, M. Saisana, and S. Tarantola. "Global Sensitivity Analysis.
           The Primer." 2007.
        .. [5] Saltelli, A., P. Annoni, I. Azzini, F. Campolongo, M. Ratto, and
           S. Tarantola. "Variance based sensitivity analysis of model
           output. Design and estimator for the total sensitivity index."
           Computer Physics Communications, 181(2):259-270,
           :doi:`10.1016/j.cpc.2009.09.018`, 2010.
        .. [6] Ishigami, T. and T. Homma. "An importance quantification technique
           in uncertainty analysis for computer models." IEEE,
           :doi:`10.1109/ISUMA.1990.151285`, 1990.

        Examples
        --------
        The following is an example with the Ishigami function [6]_

        .. math::

            Y(\mathbf{x}) = \sin x_1 + 7 \sin^2 x_2 + 0.1 x_3^4 \sin x_1,

        with :math:`\mathbf{x} \in [-\pi, \pi]^3`. This function exhibits strong
        non-linearity and non-monotonicity.

        Remember, Sobol' indices assumes that samples are independently
        distributed. In this case we use a uniform distribution on each marginals.

        >>> import numpy as np
        >>> from scipy.stats import sobol_indices, uniform
        >>> rng = np.random.default_rng()
        >>> def f_ishigami(x):
        ...     f_eval = (
        ...         np.sin(x[0])
        ...         + 7 * np.sin(x[1])**2
        ...         + 0.1 * (x[2]**4) * np.sin(x[0])
        ...     )
        ...     return f_eval
        >>> indices = sobol_indices(
        ...     func=f_ishigami, n=1024,
        ...     dists=[
        ...         uniform(loc=-np.pi, scale=2*np.pi),
        ...         uniform(loc=-np.pi, scale=2*np.pi),
        ...         uniform(loc=-np.pi, scale=2*np.pi)
        ...     ],
        ...     random_state=rng
        ... )
        >>> indices.first_order
        array([0.31637954, 0.43781162, 0.00318825])
        >>> indices.total_order
        array([0.56122127, 0.44287857, 0.24229595])

        Confidence interval can be obtained using bootstrapping.

        >>> boot = indices.bootstrap()

        Then, this information can be easily visualized.

        >>> import matplotlib.pyplot as plt
        >>> fig, axs = plt.subplots(1, 2, figsize=(9, 4))
        >>> _ = axs[0].errorbar(
        ...     [1, 2, 3], indices.first_order, fmt='o',
        ...     yerr=[
        ...         indices.first_order - boot.first_order.confidence_interval.low,
        ...         boot.first_order.confidence_interval.high - indices.first_order
        ...     ],
        ... )
        >>> axs[0].set_ylabel("First order Sobol' indices")
        >>> axs[0].set_xlabel('Input parameters')
        >>> axs[0].set_xticks([1, 2, 3])
        >>> _ = axs[1].errorbar(
        ...     [1, 2, 3], indices.total_order, fmt='o',
        ...     yerr=[
        ...         indices.total_order - boot.total_order.confidence_interval.low,
        ...         boot.total_order.confidence_interval.high - indices.total_order
        ...     ],
        ... )
        >>> axs[1].set_ylabel("Total order Sobol' indices")
        >>> axs[1].set_xlabel('Input parameters')
        >>> axs[1].set_xticks([1, 2, 3])
        >>> plt.tight_layout()
        >>> plt.show()

        .. note::

            By default, `scipy.stats.uniform` has support ``[0, 1]``.
            Using the parameters ``loc`` and ``scale``, one obtains the uniform
            distribution on ``[loc, loc + scale]``.

        This result is particularly interesting because the first order index
        :math:`S_{x_3} = 0` whereas its total order is :math:`S_{T_{x_3}} = 0.244`.
        This means that higher order interactions with :math:`x_3` are responsible
        for the difference. Almost 25% of the observed variance
        on the QoI is due to the correlations between :math:`x_3` and :math:`x_1`,
        although :math:`x_3` by itself has no impact on the QoI.

        The following gives a visual explanation of Sobol' indices on this
        function. Let's generate 1024 samples in :math:`[-\pi, \pi]^3` and
        calculate the value of the output.

        >>> from scipy.stats import qmc
        >>> n_dim = 3
        >>> p_labels = ['$x_1$', '$x_2$', '$x_3$']
        >>> sample = qmc.Sobol(d=n_dim, seed=rng).random(1024)
        >>> sample = qmc.scale(
        ...     sample=sample,
        ...     l_bounds=[-np.pi, -np.pi, -np.pi],
        ...     u_bounds=[np.pi, np.pi, np.pi]
        ... )
        >>> output = f_ishigami(sample.T)

        Now we can do scatter plots of the output with respect to each parameter.
        This gives a visual way to understand how each parameter impacts the
        output of the function.

        >>> fig, ax = plt.subplots(1, n_dim, figsize=(12, 4))
        >>> for i in range(n_dim):
        ...     xi = sample[:, i]
        ...     ax[i].scatter(xi, output, marker='+')
        ...     ax[i].set_xlabel(p_labels[i])
        >>> ax[0].set_ylabel('Y')
        >>> plt.tight_layout()
        >>> plt.show()

        Now Sobol' goes a step further:
        by conditioning the output value by given values of the parameter
        (black lines), the conditional output mean is computed. It corresponds to
        the term :math:`\mathbb{E}(Y|x_i)`. Taking the variance of this term gives
        the numerator of the Sobol' indices.

        >>> mini = np.min(output)
        >>> maxi = np.max(output)
        >>> n_bins = 10
        >>> bins = np.linspace(-np.pi, np.pi, num=n_bins, endpoint=False)
        >>> dx = bins[1] - bins[0]
        >>> fig, ax = plt.subplots(1, n_dim, figsize=(12, 4))
        >>> for i in range(n_dim):
        ...     xi = sample[:, i]
        ...     ax[i].scatter(xi, output, marker='+')
        ...     ax[i].set_xlabel(p_labels[i])
        ...     for bin_ in bins:
        ...         idx = np.where((bin_ <= xi) & (xi <= bin_ + dx))
        ...         xi_ = xi[idx]
        ...         y_ = output[idx]
        ...         ave_y_ = np.mean(y_)
        ...         ax[i].plot([bin_ + dx/2] * 2, [mini, maxi], c='k')
        ...         ax[i].scatter(bin_ + dx/2, ave_y_, c='r')
        >>> ax[0].set_ylabel('Y')
        >>> plt.tight_layout()
        >>> plt.show()

        Looking at :math:`x_3`, the variance
        of the mean is zero leading to :math:`S_{x_3} = 0`. But we can further
        observe that the variance of the output is not constant along the parameter
        values of :math:`x_3`. This heteroscedasticity is explained by higher order
        interactions. Moreover, an heteroscedasticity is also noticeable on
        :math:`x_1` leading to an interaction between :math:`x_3` and :math:`x_1`.
        On :math:`x_2`, the variance seems to be constant and thus null interaction
        with this parameter can be supposed.

        This case is fairly simple to analyse visually---although it is only a
        qualitative analysis. Nevertheless, when the number of input parameters
        increases such analysis becomes unrealistic as it would be difficult to
        conclude on high-order terms. Hence the benefit of using Sobol' indices.

    somersd(x, y=None, alternative='two-sided')
        Calculates Somers' D, an asymmetric measure of ordinal association.

        Like Kendall's :math:`\tau`, Somers' :math:`D` is a measure of the
        correspondence between two rankings. Both statistics consider the
        difference between the number of concordant and discordant pairs in two
        rankings :math:`X` and :math:`Y`, and both are normalized such that values
        close  to 1 indicate strong agreement and values close to -1 indicate
        strong disagreement. They differ in how they are normalized. To show the
        relationship, Somers' :math:`D` can be defined in terms of Kendall's
        :math:`\tau_a`:

        .. math::
            D(Y|X) = \frac{\tau_a(X, Y)}{\tau_a(X, X)}

        Suppose the first ranking :math:`X` has :math:`r` distinct ranks and the
        second ranking :math:`Y` has :math:`s` distinct ranks. These two lists of
        :math:`n` rankings can also be viewed as an :math:`r \times s` contingency
        table in which element :math:`i, j` is the number of rank pairs with rank
        :math:`i` in ranking :math:`X` and rank :math:`j` in ranking :math:`Y`.
        Accordingly, `somersd` also allows the input data to be supplied as a
        single, 2D contingency table instead of as two separate, 1D rankings.

        Note that the definition of Somers' :math:`D` is asymmetric: in general,
        :math:`D(Y|X) \neq D(X|Y)`. ``somersd(x, y)`` calculates Somers'
        :math:`D(Y|X)`: the "row" variable :math:`X` is treated as an independent
        variable, and the "column" variable :math:`Y` is dependent. For Somers'
        :math:`D(X|Y)`, swap the input lists or transpose the input table.

        Parameters
        ----------
        x : array_like
            1D array of rankings, treated as the (row) independent variable.
            Alternatively, a 2D contingency table.
        y : array_like, optional
            If `x` is a 1D array of rankings, `y` is a 1D array of rankings of the
            same length, treated as the (column) dependent variable.
            If `x` is 2D, `y` is ignored.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:
            * 'two-sided': the rank correlation is nonzero
            * 'less': the rank correlation is negative (less than zero)
            * 'greater':  the rank correlation is positive (greater than zero)

        Returns
        -------
        res : SomersDResult
            A `SomersDResult` object with the following fields:

                statistic : float
                   The Somers' :math:`D` statistic.
                pvalue : float
                   The p-value for a hypothesis test whose null
                   hypothesis is an absence of association, :math:`D=0`.
                   See notes for more information.
                table : 2D array
                   The contingency table formed from rankings `x` and `y` (or the
                   provided contingency table, if `x` is a 2D array)

        See Also
        --------
        kendalltau : Calculates Kendall's tau, another correlation measure.
        weightedtau : Computes a weighted version of Kendall's tau.
        spearmanr : Calculates a Spearman rank-order correlation coefficient.
        pearsonr : Calculates a Pearson correlation coefficient.

        Notes
        -----
        This function follows the contingency table approach of [2]_ and
        [3]_. *p*-values are computed based on an asymptotic approximation of
        the test statistic distribution under the null hypothesis :math:`D=0`.

        Theoretically, hypothesis tests based on Kendall's :math:`tau` and Somers'
        :math:`D` should be identical.
        However, the *p*-values returned by `kendalltau` are based
        on the null hypothesis of *independence* between :math:`X` and :math:`Y`
        (i.e. the population from which pairs in :math:`X` and :math:`Y` are
        sampled contains equal numbers of all possible pairs), which is more
        specific than the null hypothesis :math:`D=0` used here. If the null
        hypothesis of independence is desired, it is acceptable to use the
        *p*-value returned by `kendalltau` with the statistic returned by
        `somersd` and vice versa. For more information, see [2]_.

        Contingency tables are formatted according to the convention used by
        SAS and R: the first ranking supplied (``x``) is the "row" variable, and
        the second ranking supplied (``y``) is the "column" variable. This is
        opposite the convention of Somers' original paper [1]_.

        References
        ----------
        .. [1] Robert H. Somers, "A New Asymmetric Measure of Association for
               Ordinal Variables", *American Sociological Review*, Vol. 27, No. 6,
               pp. 799--811, 1962.

        .. [2] Morton B. Brown and Jacqueline K. Benedetti, "Sampling Behavior of
               Tests for Correlation in Two-Way Contingency Tables", *Journal of
               the American Statistical Association* Vol. 72, No. 358, pp.
               309--315, 1977.

        .. [3] SAS Institute, Inc., "The FREQ Procedure (Book Excerpt)",
               *SAS/STAT 9.2 User's Guide, Second Edition*, SAS Publishing, 2009.

        .. [4] Laerd Statistics, "Somers' d using SPSS Statistics", *SPSS
               Statistics Tutorials and Statistical Guides*,
               https://statistics.laerd.com/spss-tutorials/somers-d-using-spss-statistics.php,
               Accessed July 31, 2020.

        Examples
        --------
        We calculate Somers' D for the example given in [4]_, in which a hotel
        chain owner seeks to determine the association between hotel room
        cleanliness and customer satisfaction. The independent variable, hotel
        room cleanliness, is ranked on an ordinal scale: "below average (1)",
        "average (2)", or "above average (3)". The dependent variable, customer
        satisfaction, is ranked on a second scale: "very dissatisfied (1)",
        "moderately dissatisfied (2)", "neither dissatisfied nor satisfied (3)",
        "moderately satisfied (4)", or "very satisfied (5)". 189 customers
        respond to the survey, and the results are cast into a contingency table
        with the hotel room cleanliness as the "row" variable and customer
        satisfaction as the "column" variable.

        +-----+-----+-----+-----+-----+-----+
        |     | (1) | (2) | (3) | (4) | (5) |
        +=====+=====+=====+=====+=====+=====+
        | (1) | 27  | 25  | 14  | 7   | 0   |
        +-----+-----+-----+-----+-----+-----+
        | (2) | 7   | 14  | 18  | 35  | 12  |
        +-----+-----+-----+-----+-----+-----+
        | (3) | 1   | 3   | 2   | 7   | 17  |
        +-----+-----+-----+-----+-----+-----+

        For example, 27 customers assigned their room a cleanliness ranking of
        "below average (1)" and a corresponding satisfaction of "very
        dissatisfied (1)". We perform the analysis as follows.

        >>> from scipy.stats import somersd
        >>> table = [[27, 25, 14, 7, 0], [7, 14, 18, 35, 12], [1, 3, 2, 7, 17]]
        >>> res = somersd(table)
        >>> res.statistic
        0.6032766111513396
        >>> res.pvalue
        1.0007091191074533e-27

        The value of the Somers' D statistic is approximately 0.6, indicating
        a positive correlation between room cleanliness and customer satisfaction
        in the sample.
        The *p*-value is very small, indicating a very small probability of
        observing such an extreme value of the statistic under the null
        hypothesis that the statistic of the entire population (from which
        our sample of 189 customers is drawn) is zero. This supports the
        alternative hypothesis that the true value of Somers' D for the population
        is nonzero.

    spearmanr(a, b=None, axis=0, nan_policy='propagate', alternative='two-sided')
        Calculate a Spearman correlation coefficient with associated p-value.

        The Spearman rank-order correlation coefficient is a nonparametric measure
        of the monotonicity of the relationship between two datasets.
        Like other correlation coefficients,
        this one varies between -1 and +1 with 0 implying no correlation.
        Correlations of -1 or +1 imply an exact monotonic relationship. Positive
        correlations imply that as x increases, so does y. Negative correlations
        imply that as x increases, y decreases.

        The p-value roughly indicates the probability of an uncorrelated system
        producing datasets that have a Spearman correlation at least as extreme
        as the one computed from these datasets. Although calculation of the
        p-value does not make strong assumptions about the distributions underlying
        the samples, it is only accurate for very large samples (>500
        observations). For smaller sample sizes, consider a permutation test (see
        Examples section below).

        Parameters
        ----------
        a, b : 1D or 2D array_like, b is optional
            One or two 1-D or 2-D arrays containing multiple variables and
            observations. When these are 1-D, each represents a vector of
            observations of a single variable. For the behavior in the 2-D case,
            see under ``axis``, below.
            Both arrays need to have the same length in the ``axis`` dimension.
        axis : int or None, optional
            If axis=0 (default), then each column represents a variable, with
            observations in the rows. If axis=1, the relationship is transposed:
            each row represents a variable, while the columns contain observations.
            If axis=None, then both arrays will be raveled.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan.
            The following options are available (default is 'propagate'):

            * 'propagate': returns nan
            * 'raise': throws an error
            * 'omit': performs the calculations ignoring nan values

        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            The following options are available:

            * 'two-sided': the correlation is nonzero
            * 'less': the correlation is negative (less than zero)
            * 'greater':  the correlation is positive (greater than zero)

            .. versionadded:: 1.7.0

        Returns
        -------
        res : SignificanceResult
            An object containing attributes:

            statistic : float or ndarray (2-D square)
                Spearman correlation matrix or correlation coefficient (if only 2
                variables are given as parameters). Correlation matrix is square
                with length equal to total number of variables (columns or rows) in
                ``a`` and ``b`` combined.
            pvalue : float
                The p-value for a hypothesis test whose null hypothesis
                is that two samples have no ordinal correlation. See
                `alternative` above for alternative hypotheses. `pvalue` has the
                same shape as `statistic`.

        Warns
        -----
        `~scipy.stats.ConstantInputWarning`
            Raised if an input is a constant array.  The correlation coefficient
            is not defined in this case, so ``np.nan`` is returned.

        References
        ----------
        .. [1] Zwillinger, D. and Kokoska, S. (2000). CRC Standard
           Probability and Statistics Tables and Formulae. Chapman & Hall: New
           York. 2000.
           Section  14.7
        .. [2] Kendall, M. G. and Stuart, A. (1973).
           The Advanced Theory of Statistics, Volume 2: Inference and Relationship.
           Griffin. 1973.
           Section 31.18
        .. [3] Kershenobich, D., Fierro, F. J., & Rojkind, M. (1970). The
           relationship between the free pool of proline and collagen content in
           human liver cirrhosis. The Journal of Clinical Investigation, 49(12),
           2246-2249.
        .. [4] Hollander, M., Wolfe, D. A., & Chicken, E. (2013). Nonparametric
           statistical methods. John Wiley & Sons.
        .. [5] B. Phipson and G. K. Smyth. "Permutation P-values Should Never Be
           Zero: Calculating Exact P-values When Permutations Are Randomly Drawn."
           Statistical Applications in Genetics and Molecular Biology 9.1 (2010).
        .. [6] Ludbrook, J., & Dudley, H. (1998). Why permutation tests are
           superior to t and F tests in biomedical research. The American
           Statistician, 52(2), 127-132.

        Examples
        --------
        Consider the following data from [3]_, which studied the relationship
        between free proline (an amino acid) and total collagen (a protein often
        found in connective tissue) in unhealthy human livers.

        The ``x`` and ``y`` arrays below record measurements of the two compounds.
        The observations are paired: each free proline measurement was taken from
        the same liver as the total collagen measurement at the same index.

        >>> import numpy as np
        >>> # total collagen (mg/g dry weight of liver)
        >>> x = np.array([7.1, 7.1, 7.2, 8.3, 9.4, 10.5, 11.4])
        >>> # free proline (μ mole/g dry weight of liver)
        >>> y = np.array([2.8, 2.9, 2.8, 2.6, 3.5, 4.6, 5.0])

        These data were analyzed in [4]_ using Spearman's correlation coefficient,
        a statistic sensitive to monotonic correlation between the samples.

        >>> from scipy import stats
        >>> res = stats.spearmanr(x, y)
        >>> res.statistic
        0.7000000000000001

        The value of this statistic tends to be high (close to 1) for samples with
        a strongly positive ordinal correlation, low (close to -1) for samples with
        a strongly negative ordinal correlation, and small in magnitude (close to
        zero) for samples with weak ordinal correlation.

        The test is performed by comparing the observed value of the
        statistic against the null distribution: the distribution of statistic
        values derived under the null hypothesis that total collagen and free
        proline measurements are independent.

        For this test, the statistic can be transformed such that the null
        distribution for large samples is Student's t distribution with
        ``len(x) - 2`` degrees of freedom.

        >>> import matplotlib.pyplot as plt
        >>> dof = len(x)-2  # len(x) == len(y)
        >>> dist = stats.t(df=dof)
        >>> t_vals = np.linspace(-5, 5, 100)
        >>> pdf = dist.pdf(t_vals)
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> def plot(ax):  # we'll reuse this
        ...     ax.plot(t_vals, pdf)
        ...     ax.set_title("Spearman's Rho Test Null Distribution")
        ...     ax.set_xlabel("statistic")
        ...     ax.set_ylabel("probability density")
        >>> plot(ax)
        >>> plt.show()

        The comparison is quantified by the p-value: the proportion of values in
        the null distribution as extreme or more extreme than the observed
        value of the statistic. In a two-sided test in which the statistic is
        positive, elements of the null distribution greater than the transformed
        statistic and elements of the null distribution less than the negative of
        the observed statistic are both considered "more extreme".

        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> rs = res.statistic  # original statistic
        >>> transformed = rs * np.sqrt(dof / ((rs+1.0)*(1.0-rs)))
        >>> pvalue = dist.cdf(-transformed) + dist.sf(transformed)
        >>> annotation = (f'p-value={pvalue:.4f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (2.7, 0.025), (3, 0.03), arrowprops=props)
        >>> i = t_vals >= transformed
        >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0')
        >>> i = t_vals <= -transformed
        >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0')
        >>> ax.set_xlim(-5, 5)
        >>> ax.set_ylim(0, 0.1)
        >>> plt.show()
        >>> res.pvalue
        0.07991669030889909  # two-sided p-value

        If the p-value is "small" - that is, if there is a low probability of
        sampling data from independent distributions that produces such an extreme
        value of the statistic - this may be taken as evidence against the null
        hypothesis in favor of the alternative: the distribution of total collagen
        and free proline are *not* independent. Note that:

        - The inverse is not true; that is, the test is not used to provide
          evidence for the null hypothesis.
        - The threshold for values that will be considered "small" is a choice that
          should be made before the data is analyzed [5]_ with consideration of the
          risks of both false positives (incorrectly rejecting the null hypothesis)
          and false negatives (failure to reject a false null hypothesis).
        - Small p-values are not evidence for a *large* effect; rather, they can
          only provide evidence for a "significant" effect, meaning that they are
          unlikely to have occurred under the null hypothesis.

        Suppose that before performing the experiment, the authors had reason
        to predict a positive correlation between the total collagen and free
        proline measurements, and that they had chosen to assess the plausibility
        of the null hypothesis against a one-sided alternative: free proline has a
        positive ordinal correlation with total collagen. In this case, only those
        values in the null distribution that are as great or greater than the
        observed statistic are considered to be more extreme.

        >>> res = stats.spearmanr(x, y, alternative='greater')
        >>> res.statistic
        0.7000000000000001  # same statistic
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> pvalue = dist.sf(transformed)
        >>> annotation = (f'p-value={pvalue:.6f}\n(shaded area)')
        >>> props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
        >>> _ = ax.annotate(annotation, (3, 0.018), (3.5, 0.03), arrowprops=props)
        >>> i = t_vals >= transformed
        >>> ax.fill_between(t_vals[i], y1=0, y2=pdf[i], color='C0')
        >>> ax.set_xlim(1, 5)
        >>> ax.set_ylim(0, 0.1)
        >>> plt.show()
        >>> res.pvalue
        0.03995834515444954  # one-sided p-value; half of the two-sided p-value

        Note that the t-distribution provides an asymptotic approximation of the
        null distribution; it is only accurate for samples with many observations.
        For small samples, it may be more appropriate to perform a permutation
        test: Under the null hypothesis that total collagen and free proline are
        independent, each of the free proline measurements were equally likely to
        have been observed with any of the total collagen measurements. Therefore,
        we can form an *exact* null distribution by calculating the statistic under
        each possible pairing of elements between ``x`` and ``y``.

        >>> def statistic(x):  # explore all possible pairings by permuting `x`
        ...     rs = stats.spearmanr(x, y).statistic  # ignore pvalue
        ...     transformed = rs * np.sqrt(dof / ((rs+1.0)*(1.0-rs)))
        ...     return transformed
        >>> ref = stats.permutation_test((x,), statistic, alternative='greater',
        ...                              permutation_type='pairings')
        >>> fig, ax = plt.subplots(figsize=(8, 5))
        >>> plot(ax)
        >>> ax.hist(ref.null_distribution, np.linspace(-5, 5, 26),
        ...         density=True)
        >>> ax.legend(['aymptotic approximation\n(many observations)',
        ...            f'exact \n({len(ref.null_distribution)} permutations)'])
        >>> plt.show()
        >>> ref.pvalue
        0.04563492063492063  # exact one-sided p-value

    theilslopes(y, x=None, alpha=0.95, method='separate')
        Computes the Theil-Sen estimator for a set of points (x, y).

        `theilslopes` implements a method for robust linear regression.  It
        computes the slope as the median of all slopes between paired values.

        Parameters
        ----------
        y : array_like
            Dependent variable.
        x : array_like or None, optional
            Independent variable. If None, use ``arange(len(y))`` instead.
        alpha : float, optional
            Confidence degree between 0 and 1. Default is 95% confidence.
            Note that `alpha` is symmetric around 0.5, i.e. both 0.1 and 0.9 are
            interpreted as "find the 90% confidence interval".
        method : {'joint', 'separate'}, optional
            Method to be used for computing estimate for intercept.
            Following methods are supported,

                * 'joint': Uses np.median(y - slope * x) as intercept.
                * 'separate': Uses np.median(y) - slope * np.median(x)
                              as intercept.

            The default is 'separate'.

            .. versionadded:: 1.8.0

        Returns
        -------
        result : ``TheilslopesResult`` instance
            The return value is an object with the following attributes:

            slope : float
                Theil slope.
            intercept : float
                Intercept of the Theil line.
            low_slope : float
                Lower bound of the confidence interval on `slope`.
            high_slope : float
                Upper bound of the confidence interval on `slope`.

        See Also
        --------
        siegelslopes : a similar technique using repeated medians

        Notes
        -----
        The implementation of `theilslopes` follows [1]_. The intercept is
        not defined in [1]_, and here it is defined as ``median(y) -
        slope*median(x)``, which is given in [3]_. Other definitions of
        the intercept exist in the literature such as  ``median(y - slope*x)``
        in [4]_. The approach to compute the intercept can be determined by the
        parameter ``method``. A confidence interval for the intercept is not
        given as this question is not addressed in [1]_.

        For compatibility with older versions of SciPy, the return value acts
        like a ``namedtuple`` of length 4, with fields ``slope``, ``intercept``,
        ``low_slope``, and ``high_slope``, so one can continue to write::

            slope, intercept, low_slope, high_slope = theilslopes(y, x)

        References
        ----------
        .. [1] P.K. Sen, "Estimates of the regression coefficient based on
               Kendall's tau", J. Am. Stat. Assoc., Vol. 63, pp. 1379-1389, 1968.
        .. [2] H. Theil, "A rank-invariant method of linear and polynomial
               regression analysis I, II and III",  Nederl. Akad. Wetensch., Proc.
               53:, pp. 386-392, pp. 521-525, pp. 1397-1412, 1950.
        .. [3] W.L. Conover, "Practical nonparametric statistics", 2nd ed.,
               John Wiley and Sons, New York, pp. 493.
        .. [4] https://en.wikipedia.org/wiki/Theil%E2%80%93Sen_estimator

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        >>> x = np.linspace(-5, 5, num=150)
        >>> y = x + np.random.normal(size=x.size)
        >>> y[11:15] += 10  # add outliers
        >>> y[-5:] -= 7

        Compute the slope, intercept and 90% confidence interval.  For comparison,
        also compute the least-squares fit with `linregress`:

        >>> res = stats.theilslopes(y, x, 0.90, method='separate')
        >>> lsq_res = stats.linregress(x, y)

        Plot the results. The Theil-Sen regression line is shown in red, with the
        dashed red lines illustrating the confidence interval of the slope (note
        that the dashed red lines are not the confidence interval of the regression
        as the confidence interval of the intercept is not included). The green
        line shows the least-squares fit for comparison.

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, y, 'b.')
        >>> ax.plot(x, res[1] + res[0] * x, 'r-')
        >>> ax.plot(x, res[1] + res[2] * x, 'r--')
        >>> ax.plot(x, res[1] + res[3] * x, 'r--')
        >>> ax.plot(x, lsq_res[1] + lsq_res[0] * x, 'g-')
        >>> plt.show()

    tiecorrect(rankvals)
        Tie correction factor for Mann-Whitney U and Kruskal-Wallis H tests.

        Parameters
        ----------
        rankvals : array_like
            A 1-D sequence of ranks.  Typically this will be the array
            returned by `~scipy.stats.rankdata`.

        Returns
        -------
        factor : float
            Correction factor for U or H.

        See Also
        --------
        rankdata : Assign ranks to the data
        mannwhitneyu : Mann-Whitney rank test
        kruskal : Kruskal-Wallis H test

        References
        ----------
        .. [1] Siegel, S. (1956) Nonparametric Statistics for the Behavioral
               Sciences.  New York: McGraw-Hill.

        Examples
        --------
        >>> from scipy.stats import tiecorrect, rankdata
        >>> tiecorrect([1, 2.5, 2.5, 4])
        0.9
        >>> ranks = rankdata([1, 3, 2, 4, 5, 7, 2, 8, 4])
        >>> ranks
        array([ 1. ,  4. ,  2.5,  5.5,  7. ,  8. ,  2.5,  9. ,  5.5])
        >>> tiecorrect(ranks)
        0.9833333333333333

    tmax(a, upperlimit=None, axis=0, inclusive=True, nan_policy='propagate', *, keepdims=False)
        Compute the trimmed maximum.

        This function computes the maximum value of an array along a given axis,
        while ignoring values larger than a specified upper limit.

        Parameters
        ----------
        a : array_like
            Array of values.
        upperlimit : None or float, optional
            Values in the input array greater than the given limit will be ignored.
            When upperlimit is None, then all values are used. The default value
            is None.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        inclusive : {True, False}, optional
            This flag determines whether values exactly equal to the upper limit
            are included.  The default value is True.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tmax : float, int or ndarray
            Trimmed maximum.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tmax(x)
        19

        >>> stats.tmax(x, 13)
        13

        >>> stats.tmax(x, 13, inclusive=False)
        12

    tmean(a, limits=None, inclusive=(True, True), axis=None, *, nan_policy='propagate', keepdims=False)
        Compute the trimmed mean.

        This function finds the arithmetic mean of given values, ignoring values
        outside the given `limits`.

        Parameters
        ----------
        a : array_like
            Array of values.
        limits : None or (lower limit, upper limit), optional
            Values in the input array less than the lower limit or greater than the
            upper limit will be ignored.  When limits is None (default), then all
            values are used.  Either of the limit values in the tuple can also be
            None representing a half-open interval.
        inclusive : (bool, bool), optional
            A tuple consisting of the (lower flag, upper flag).  These flags
            determine whether values exactly equal to the lower or upper limits
            are included.  The default value is (True, True).
        axis : int or None, default: None
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tmean : ndarray
            Trimmed mean.

        See Also
        --------

        :func:`trim_mean`
            Returns mean after trimming a proportion from both tails.


        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tmean(x)
        9.5
        >>> stats.tmean(x, (3,17))
        10.0

    tmin(a, lowerlimit=None, axis=0, inclusive=True, nan_policy='propagate', *, keepdims=False)
        Compute the trimmed minimum.

        This function finds the minimum value of an array `a` along the
        specified axis, but only considering values greater than a specified
        lower limit.

        Parameters
        ----------
        a : array_like
            Array of values.
        lowerlimit : None or float, optional
            Values in the input array less than the given limit will be ignored.
            When lowerlimit is None, then all values are used. The default value
            is None.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        inclusive : {True, False}, optional
            This flag determines whether values exactly equal to the lower limit
            are included.  The default value is True.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tmin : float, int or ndarray
            Trimmed minimum.

        Notes
        -----

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tmin(x)
        0

        >>> stats.tmin(x, 13)
        13

        >>> stats.tmin(x, 13, inclusive=False)
        14

    trim1(a, proportiontocut, tail='right', axis=0)
        Slice off a proportion from ONE end of the passed array distribution.

        If `proportiontocut` = 0.1, slices off 'leftmost' or 'rightmost'
        10% of scores. The lowest or highest values are trimmed (depending on
        the tail).
        Slice off less if proportion results in a non-integer slice index
        (i.e. conservatively slices off `proportiontocut` ).

        Parameters
        ----------
        a : array_like
            Input array.
        proportiontocut : float
            Fraction to cut off of 'left' or 'right' of distribution.
        tail : {'left', 'right'}, optional
            Defaults to 'right'.
        axis : int or None, optional
            Axis along which to trim data. Default is 0. If None, compute over
            the whole array `a`.

        Returns
        -------
        trim1 : ndarray
            Trimmed version of array `a`. The order of the trimmed content is
            undefined.

        Examples
        --------
        Create an array of 10 values and trim 20% of its lowest values:

        >>> import numpy as np
        >>> from scipy import stats
        >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> stats.trim1(a, 0.2, 'left')
        array([2, 4, 3, 5, 6, 7, 8, 9])

        Note that the elements of the input array are trimmed by value, but the
        output array is not necessarily sorted.

        The proportion to trim is rounded down to the nearest integer. For
        instance, trimming 25% of the values from an array of 10 values will
        return an array of 8 values:

        >>> b = np.arange(10)
        >>> stats.trim1(b, 1/4).shape
        (8,)

        Multidimensional arrays can be trimmed along any axis or across the entire
        array:

        >>> c = [2, 4, 6, 8, 0, 1, 3, 5, 7, 9]
        >>> d = np.array([a, b, c])
        >>> stats.trim1(d, 0.8, axis=0).shape
        (1, 10)
        >>> stats.trim1(d, 0.8, axis=1).shape
        (3, 2)
        >>> stats.trim1(d, 0.8, axis=None).shape
        (6,)

    trim_mean(a, proportiontocut, axis=0)
        Return mean of array after trimming a specified fraction of extreme values

        Removes the specified proportion of elements from *each* end of the
        sorted array, then computes the mean of the remaining elements.

        Parameters
        ----------
        a : array_like
            Input array.
        proportiontocut : float
            Fraction of the most positive and most negative elements to remove.
            When the specified proportion does not result in an integer number of
            elements, the number of elements to trim is rounded down.
        axis : int or None, default: 0
            Axis along which the trimmed means are computed.
            If None, compute over the raveled array.

        Returns
        -------
        trim_mean : ndarray
            Mean of trimmed array.

        See Also
        --------
        trimboth : Remove a proportion of elements from each end of an array.
        tmean : Compute the mean after trimming values outside specified limits.

        Notes
        -----
        For 1-D array `a`, `trim_mean` is approximately equivalent to the following
        calculation::

            import numpy as np
            a = np.sort(a)
            m = int(proportiontocut * len(a))
            np.mean(a[m: len(a) - m])

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = [1, 2, 3, 5]
        >>> stats.trim_mean(x, 0.25)
        2.5

        When the specified proportion does not result in an integer number of
        elements, the number of elements to trim is rounded down.

        >>> stats.trim_mean(x, 0.24999) == np.mean(x)
        True

        Use `axis` to specify the axis along which the calculation is performed.

        >>> x2 = [[1, 2, 3, 5],
        ...       [10, 20, 30, 50]]
        >>> stats.trim_mean(x2, 0.25)
        array([ 5.5, 11. , 16.5, 27.5])
        >>> stats.trim_mean(x2, 0.25, axis=1)
        array([ 2.5, 25. ])

    trimboth(a, proportiontocut, axis=0)
        Slice off a proportion of items from both ends of an array.

        Slice off the passed proportion of items from both ends of the passed
        array (i.e., with `proportiontocut` = 0.1, slices leftmost 10% **and**
        rightmost 10% of scores). The trimmed values are the lowest and
        highest ones.
        Slice off less if proportion results in a non-integer slice index (i.e.
        conservatively slices off `proportiontocut`).

        Parameters
        ----------
        a : array_like
            Data to trim.
        proportiontocut : float
            Proportion (in range 0-1) of total data set to trim of each end.
        axis : int or None, optional
            Axis along which to trim data. Default is 0. If None, compute over
            the whole array `a`.

        Returns
        -------
        out : ndarray
            Trimmed version of array `a`. The order of the trimmed content
            is undefined.

        See Also
        --------
        trim_mean

        Examples
        --------
        Create an array of 10 values and trim 10% of those values from each end:

        >>> import numpy as np
        >>> from scipy import stats
        >>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> stats.trimboth(a, 0.1)
        array([1, 3, 2, 4, 5, 6, 7, 8])

        Note that the elements of the input array are trimmed by value, but the
        output array is not necessarily sorted.

        The proportion to trim is rounded down to the nearest integer. For
        instance, trimming 25% of the values from each end of an array of 10
        values will return an array of 6 values:

        >>> b = np.arange(10)
        >>> stats.trimboth(b, 1/4).shape
        (6,)

        Multidimensional arrays can be trimmed along any axis or across the entire
        array:

        >>> c = [2, 4, 6, 8, 0, 1, 3, 5, 7, 9]
        >>> d = np.array([a, b, c])
        >>> stats.trimboth(d, 0.4, axis=0).shape
        (1, 10)
        >>> stats.trimboth(d, 0.4, axis=1).shape
        (3, 2)
        >>> stats.trimboth(d, 0.4, axis=None).shape
        (6,)

    tsem(a, limits=None, inclusive=(True, True), axis=0, ddof=1, *, nan_policy='propagate', keepdims=False)
        Compute the trimmed standard error of the mean.

        This function finds the standard error of the mean for given
        values, ignoring values outside the given `limits`.

        Parameters
        ----------
        a : array_like
            Array of values.
        limits : None or (lower limit, upper limit), optional
            Values in the input array less than the lower limit or greater than the
            upper limit will be ignored. When limits is None, then all values are
            used. Either of the limit values in the tuple can also be None
            representing a half-open interval.  The default value is None.
        inclusive : (bool, bool), optional
            A tuple consisting of the (lower flag, upper flag).  These flags
            determine whether values exactly equal to the lower or upper limits
            are included.  The default value is (True, True).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        ddof : int, optional
            Delta degrees of freedom.  Default is 1.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tsem : float
            Trimmed standard error of the mean.

        Notes
        -----
        `tsem` uses unbiased sample standard deviation, i.e. it uses a
        correction factor ``n / (n - 1)``.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tsem(x)
        1.3228756555322954
        >>> stats.tsem(x, (3,17))
        1.1547005383792515

    tstd(a, limits=None, inclusive=(True, True), axis=0, ddof=1, *, nan_policy='propagate', keepdims=False)
        Compute the trimmed sample standard deviation.

        This function finds the sample standard deviation of given values,
        ignoring values outside the given `limits`.

        Parameters
        ----------
        a : array_like
            Array of values.
        limits : None or (lower limit, upper limit), optional
            Values in the input array less than the lower limit or greater than the
            upper limit will be ignored. When limits is None, then all values are
            used. Either of the limit values in the tuple can also be None
            representing a half-open interval.  The default value is None.
        inclusive : (bool, bool), optional
            A tuple consisting of the (lower flag, upper flag).  These flags
            determine whether values exactly equal to the lower or upper limits
            are included.  The default value is (True, True).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        ddof : int, optional
            Delta degrees of freedom.  Default is 1.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tstd : float
            Trimmed sample standard deviation.

        Notes
        -----
        `tstd` computes the unbiased sample standard deviation, i.e. it uses a
        correction factor ``n / (n - 1)``.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tstd(x)
        5.9160797830996161
        >>> stats.tstd(x, (3,17))
        4.4721359549995796

    ttest_1samp(a, popmean, axis=0, nan_policy='propagate', alternative='two-sided', *, keepdims=False)
        Calculate the T-test for the mean of ONE group of scores.

        This is a test for the null hypothesis that the expected value
        (mean) of a sample of independent observations `a` is equal to the given
        population mean, `popmean`.

        Parameters
        ----------
        a : array_like
            Sample observations.
        popmean : float or array_like
            Expected value in null hypothesis. If array_like, then its length along
            `axis` must equal 1, and it must otherwise be broadcastable with `a`.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the mean of the underlying distribution of the sample
              is different than the given population mean (`popmean`)
            * 'less': the mean of the underlying distribution of the sample is
              less than the given population mean (`popmean`)
            * 'greater': the mean of the underlying distribution of the sample is
              greater than the given population mean (`popmean`)
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        result : `~scipy.stats._result_classes.TtestResult`
            An object with the following attributes:

            statistic : float or array
                The t-statistic.
            pvalue : float or array
                The p-value associated with the given alternative.
            df : float or array
                The number of degrees of freedom used in calculation of the
                t-statistic; this is one less than the size of the sample
                (``a.shape[axis]``).

                .. versionadded:: 1.10.0

            The object also has the following method:

            confidence_interval(confidence_level=0.95)
                Computes a confidence interval around the population
                mean for the given confidence level.
                The confidence interval is returned in a ``namedtuple`` with
                fields `low` and `high`.

                .. versionadded:: 1.10.0

        Notes
        -----
        The statistic is calculated as ``(np.mean(a) - popmean)/se``, where
        ``se`` is the standard error. Therefore, the statistic will be positive
        when the sample mean is greater than the population mean and negative when
        the sample mean is less than the population mean.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        Suppose we wish to test the null hypothesis that the mean of a population
        is equal to 0.5. We choose a confidence level of 99%; that is, we will
        reject the null hypothesis in favor of the alternative if the p-value is
        less than 0.01.

        When testing random variates from the standard uniform distribution, which
        has a mean of 0.5, we expect the data to be consistent with the null
        hypothesis most of the time.

        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()
        >>> rvs = stats.uniform.rvs(size=50, random_state=rng)
        >>> stats.ttest_1samp(rvs, popmean=0.5)
        TtestResult(statistic=2.456308468440, pvalue=0.017628209047638, df=49)

        As expected, the p-value of 0.017 is not below our threshold of 0.01, so
        we cannot reject the null hypothesis.

        When testing data from the standard *normal* distribution, which has a mean
        of 0, we would expect the null hypothesis to be rejected.

        >>> rvs = stats.norm.rvs(size=50, random_state=rng)
        >>> stats.ttest_1samp(rvs, popmean=0.5)
        TtestResult(statistic=-7.433605518875, pvalue=1.416760157221e-09, df=49)

        Indeed, the p-value is lower than our threshold of 0.01, so we reject the
        null hypothesis in favor of the default "two-sided" alternative: the mean
        of the population is *not* equal to 0.5.

        However, suppose we were to test the null hypothesis against the
        one-sided alternative that the mean of the population is *greater* than
        0.5. Since the mean of the standard normal is less than 0.5, we would not
        expect the null hypothesis to be rejected.

        >>> stats.ttest_1samp(rvs, popmean=0.5, alternative='greater')
        TtestResult(statistic=-7.433605518875, pvalue=0.99999999929, df=49)

        Unsurprisingly, with a p-value greater than our threshold, we would not
        reject the null hypothesis.

        Note that when working with a confidence level of 99%, a true null
        hypothesis will be rejected approximately 1% of the time.

        >>> rvs = stats.uniform.rvs(size=(100, 50), random_state=rng)
        >>> res = stats.ttest_1samp(rvs, popmean=0.5, axis=1)
        >>> np.sum(res.pvalue < 0.01)
        1

        Indeed, even though all 100 samples above were drawn from the standard
        uniform distribution, which *does* have a population mean of 0.5, we would
        mistakenly reject the null hypothesis for one of them.

        `ttest_1samp` can also compute a confidence interval around the population
        mean.

        >>> rvs = stats.norm.rvs(size=50, random_state=rng)
        >>> res = stats.ttest_1samp(rvs, popmean=0)
        >>> ci = res.confidence_interval(confidence_level=0.95)
        >>> ci
        ConfidenceInterval(low=-0.3193887540880017, high=0.2898583388980972)

        The bounds of the 95% confidence interval are the
        minimum and maximum values of the parameter `popmean` for which the
        p-value of the test would be 0.05.

        >>> res = stats.ttest_1samp(rvs, popmean=ci.low)
        >>> np.testing.assert_allclose(res.pvalue, 0.05)
        >>> res = stats.ttest_1samp(rvs, popmean=ci.high)
        >>> np.testing.assert_allclose(res.pvalue, 0.05)

        Under certain assumptions about the population from which a sample
        is drawn, the confidence interval with confidence level 95% is expected
        to contain the true population mean in 95% of sample replications.

        >>> rvs = stats.norm.rvs(size=(50, 1000), loc=1, random_state=rng)
        >>> res = stats.ttest_1samp(rvs, popmean=0)
        >>> ci = res.confidence_interval()
        >>> contains_pop_mean = (ci.low < 1) & (ci.high > 1)
        >>> contains_pop_mean.sum()
        953

    ttest_ind(a, b, axis=0, equal_var=True, nan_policy='propagate', permutations=None, random_state=None, alternative='two-sided', trim=0, *, keepdims=False)
        Calculate the T-test for the means of *two independent* samples of scores.

        This is a test for the null hypothesis that 2 independent samples
        have identical average (expected) values. This test assumes that the
        populations have identical variances by default.

        Parameters
        ----------
        a, b : array_like
            The arrays must have the same shape, except in the dimension
            corresponding to `axis` (the first, by default).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        equal_var : bool, optional
            If True (default), perform a standard independent 2 sample test
            that assumes equal population variances [1]_.
            If False, perform Welch's t-test, which does not assume equal
            population variance [2]_.

            .. versionadded:: 0.11.0
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        permutations : non-negative int, np.inf, or None (default), optional
            If 0 or None (default), use the t-distribution to calculate p-values.
            Otherwise, `permutations` is  the number of random permutations that
            will be used to estimate p-values using a permutation test. If
            `permutations` equals or exceeds the number of distinct partitions of
            the pooled data, an exact test is performed instead (i.e. each
            distinct partition is used exactly once). See Notes for details.

            .. versionadded:: 1.7.0
        random_state : {None, int, `numpy.random.Generator`,
                `numpy.random.RandomState`}, optional

            If `seed` is None (or `np.random`), the `numpy.random.RandomState`
            singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used,
            seeded with `seed`.
            If `seed` is already a ``Generator`` or ``RandomState`` instance then
            that instance is used.

            Pseudorandom number generator state used to generate permutations
            (used only when `permutations` is not None).

            .. versionadded:: 1.7.0
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the means of the distributions underlying the samples
              are unequal.
            * 'less': the mean of the distribution underlying the first sample
              is less than the mean of the distribution underlying the second
              sample.
            * 'greater': the mean of the distribution underlying the first
              sample is greater than the mean of the distribution underlying
              the second sample.

            .. versionadded:: 1.6.0
        trim : float, optional
            If nonzero, performs a trimmed (Yuen's) t-test.
            Defines the fraction of elements to be trimmed from each end of the
            input samples. If 0 (default), no elements will be trimmed from either
            side. The number of trimmed elements from each tail is the floor of the
            trim times the number of elements. Valid range is [0, .5).

            .. versionadded:: 1.7
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        result : `~scipy.stats._result_classes.TtestResult`
            An object with the following attributes:

            statistic : float or ndarray
                The t-statistic.
            pvalue : float or ndarray
                The p-value associated with the given alternative.
            df : float or ndarray
                The number of degrees of freedom used in calculation of the
                t-statistic. This is always NaN for a permutation t-test.

                .. versionadded:: 1.11.0

            The object also has the following method:

            confidence_interval(confidence_level=0.95)
                Computes a confidence interval around the difference in
                population means for the given confidence level.
                The confidence interval is returned in a ``namedtuple`` with
                fields ``low`` and ``high``.
                When a permutation t-test is performed, the confidence interval
                is not computed, and fields ``low`` and ``high`` contain NaN.

                .. versionadded:: 1.11.0

        Notes
        -----
        Suppose we observe two independent samples, e.g. flower petal lengths, and
        we are considering whether the two samples were drawn from the same
        population (e.g. the same species of flower or two species with similar
        petal characteristics) or two different populations.

        The t-test quantifies the difference between the arithmetic means
        of the two samples. The p-value quantifies the probability of observing
        as or more extreme values assuming the null hypothesis, that the
        samples are drawn from populations with the same population means, is true.
        A p-value larger than a chosen threshold (e.g. 5% or 1%) indicates that
        our observation is not so unlikely to have occurred by chance. Therefore,
        we do not reject the null hypothesis of equal population means.
        If the p-value is smaller than our threshold, then we have evidence
        against the null hypothesis of equal population means.

        By default, the p-value is determined by comparing the t-statistic of the
        observed data against a theoretical t-distribution.
        When ``1 < permutations < binom(n, k)``, where

        * ``k`` is the number of observations in `a`,
        * ``n`` is the total number of observations in `a` and `b`, and
        * ``binom(n, k)`` is the binomial coefficient (``n`` choose ``k``),

        the data are pooled (concatenated), randomly assigned to either group `a`
        or `b`, and the t-statistic is calculated. This process is performed
        repeatedly (`permutation` times), generating a distribution of the
        t-statistic under the null hypothesis, and the t-statistic of the observed
        data is compared to this distribution to determine the p-value.
        Specifically, the p-value reported is the "achieved significance level"
        (ASL) as defined in 4.4 of [3]_. Note that there are other ways of
        estimating p-values using randomized permutation tests; for other
        options, see the more general `permutation_test`.

        When ``permutations >= binom(n, k)``, an exact test is performed: the data
        are partitioned between the groups in each distinct way exactly once.

        The permutation test can be computationally expensive and not necessarily
        more accurate than the analytical test, but it does not make strong
        assumptions about the shape of the underlying distribution.

        Use of trimming is commonly referred to as the trimmed t-test. At times
        called Yuen's t-test, this is an extension of Welch's t-test, with the
        difference being the use of winsorized means in calculation of the variance
        and the trimmed sample size in calculation of the statistic. Trimming is
        recommended if the underlying distribution is long-tailed or contaminated
        with outliers [4]_.

        The statistic is calculated as ``(np.mean(a) - np.mean(b))/se``, where
        ``se`` is the standard error. Therefore, the statistic will be positive
        when the sample mean of `a` is greater than the sample mean of `b` and
        negative when the sample mean of `a` is less than the sample mean of
        `b`.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/T-test#Independent_two-sample_t-test

        .. [2] https://en.wikipedia.org/wiki/Welch%27s_t-test

        .. [3] B. Efron and T. Hastie. Computer Age Statistical Inference. (2016).

        .. [4] Yuen, Karen K. "The Two-Sample Trimmed t for Unequal Population
               Variances." Biometrika, vol. 61, no. 1, 1974, pp. 165-170. JSTOR,
               www.jstor.org/stable/2334299. Accessed 30 Mar. 2021.

        .. [5] Yuen, Karen K., and W. J. Dixon. "The Approximate Behaviour and
               Performance of the Two-Sample Trimmed t." Biometrika, vol. 60,
               no. 2, 1973, pp. 369-374. JSTOR, www.jstor.org/stable/2334550.
               Accessed 30 Mar. 2021.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()

        Test with sample with identical means:

        >>> rvs1 = stats.norm.rvs(loc=5, scale=10, size=500, random_state=rng)
        >>> rvs2 = stats.norm.rvs(loc=5, scale=10, size=500, random_state=rng)
        >>> stats.ttest_ind(rvs1, rvs2)
        TtestResult(statistic=-0.4390847099199348,
                    pvalue=0.6606952038870015,
                    df=998.0)
        >>> stats.ttest_ind(rvs1, rvs2, equal_var=False)
        TtestResult(statistic=-0.4390847099199348,
                    pvalue=0.6606952553131064,
                    df=997.4602304121448)

        `ttest_ind` underestimates p for unequal variances:

        >>> rvs3 = stats.norm.rvs(loc=5, scale=20, size=500, random_state=rng)
        >>> stats.ttest_ind(rvs1, rvs3)
        TtestResult(statistic=-1.6370984482905417,
                    pvalue=0.1019251574705033,
                    df=998.0)
        >>> stats.ttest_ind(rvs1, rvs3, equal_var=False)
        TtestResult(statistic=-1.637098448290542,
                    pvalue=0.10202110497954867,
                    df=765.1098655246868)

        When ``n1 != n2``, the equal variance t-statistic is no longer equal to the
        unequal variance t-statistic:

        >>> rvs4 = stats.norm.rvs(loc=5, scale=20, size=100, random_state=rng)
        >>> stats.ttest_ind(rvs1, rvs4)
        TtestResult(statistic=-1.9481646859513422,
                    pvalue=0.05186270935842703,
                    df=598.0)
        >>> stats.ttest_ind(rvs1, rvs4, equal_var=False)
        TtestResult(statistic=-1.3146566100751664,
                    pvalue=0.1913495266513811,
                    df=110.41349083985212)

        T-test with different means, variance, and n:

        >>> rvs5 = stats.norm.rvs(loc=8, scale=20, size=100, random_state=rng)
        >>> stats.ttest_ind(rvs1, rvs5)
        TtestResult(statistic=-2.8415950600298774,
                    pvalue=0.0046418707568707885,
                    df=598.0)
        >>> stats.ttest_ind(rvs1, rvs5, equal_var=False)
        TtestResult(statistic=-1.8686598649188084,
                    pvalue=0.06434714193919686,
                    df=109.32167496550137)

        When performing a permutation test, more permutations typically yields
        more accurate results. Use a ``np.random.Generator`` to ensure
        reproducibility:

        >>> stats.ttest_ind(rvs1, rvs5, permutations=10000,
        ...                 random_state=rng)
        TtestResult(statistic=-2.8415950600298774,
                    pvalue=0.0052994700529947,
                    df=nan)

        Take these two samples, one of which has an extreme tail.

        >>> a = (56, 128.6, 12, 123.8, 64.34, 78, 763.3)
        >>> b = (1.1, 2.9, 4.2)

        Use the `trim` keyword to perform a trimmed (Yuen) t-test. For example,
        using 20% trimming, ``trim=.2``, the test will reduce the impact of one
        (``np.floor(trim*len(a))``) element from each tail of sample `a`. It will
        have no effect on sample `b` because ``np.floor(trim*len(b))`` is 0.

        >>> stats.ttest_ind(a, b, trim=.2)
        TtestResult(statistic=3.4463884028073513,
                    pvalue=0.01369338726499547,
                    df=6.0)

    ttest_ind_from_stats(mean1, std1, nobs1, mean2, std2, nobs2, equal_var=True, alternative='two-sided')
        T-test for means of two independent samples from descriptive statistics.

        This is a test for the null hypothesis that two independent
        samples have identical average (expected) values.

        Parameters
        ----------
        mean1 : array_like
            The mean(s) of sample 1.
        std1 : array_like
            The corrected sample standard deviation of sample 1 (i.e. ``ddof=1``).
        nobs1 : array_like
            The number(s) of observations of sample 1.
        mean2 : array_like
            The mean(s) of sample 2.
        std2 : array_like
            The corrected sample standard deviation of sample 2 (i.e. ``ddof=1``).
        nobs2 : array_like
            The number(s) of observations of sample 2.
        equal_var : bool, optional
            If True (default), perform a standard independent 2 sample test
            that assumes equal population variances [1]_.
            If False, perform Welch's t-test, which does not assume equal
            population variance [2]_.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the means of the distributions are unequal.
            * 'less': the mean of the first distribution is less than the
              mean of the second distribution.
            * 'greater': the mean of the first distribution is greater than the
              mean of the second distribution.

            .. versionadded:: 1.6.0

        Returns
        -------
        statistic : float or array
            The calculated t-statistics.
        pvalue : float or array
            The two-tailed p-value.

        See Also
        --------
        scipy.stats.ttest_ind

        Notes
        -----
        The statistic is calculated as ``(mean1 - mean2)/se``, where ``se`` is the
        standard error. Therefore, the statistic will be positive when `mean1` is
        greater than `mean2` and negative when `mean1` is less than `mean2`.

        This method does not check whether any of the elements of `std1` or `std2`
        are negative. If any elements of the `std1` or `std2` parameters are
        negative in a call to this method, this method will return the same result
        as if it were passed ``numpy.abs(std1)`` and ``numpy.abs(std2)``,
        respectively, instead; no exceptions or warnings will be emitted.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/T-test#Independent_two-sample_t-test

        .. [2] https://en.wikipedia.org/wiki/Welch%27s_t-test

        Examples
        --------
        Suppose we have the summary data for two samples, as follows (with the
        Sample Variance being the corrected sample variance)::

                             Sample   Sample
                       Size   Mean   Variance
            Sample 1    13    15.0     87.5
            Sample 2    11    12.0     39.0

        Apply the t-test to this data (with the assumption that the population
        variances are equal):

        >>> import numpy as np
        >>> from scipy.stats import ttest_ind_from_stats
        >>> ttest_ind_from_stats(mean1=15.0, std1=np.sqrt(87.5), nobs1=13,
        ...                      mean2=12.0, std2=np.sqrt(39.0), nobs2=11)
        Ttest_indResult(statistic=0.9051358093310269, pvalue=0.3751996797581487)

        For comparison, here is the data from which those summary statistics
        were taken.  With this data, we can compute the same result using
        `scipy.stats.ttest_ind`:

        >>> a = np.array([1, 3, 4, 6, 11, 13, 15, 19, 22, 24, 25, 26, 26])
        >>> b = np.array([2, 4, 6, 9, 11, 13, 14, 15, 18, 19, 21])
        >>> from scipy.stats import ttest_ind
        >>> ttest_ind(a, b)
        TtestResult(statistic=0.905135809331027,
                    pvalue=0.3751996797581486,
                    df=22.0)

        Suppose we instead have binary data and would like to apply a t-test to
        compare the proportion of 1s in two independent groups::

                              Number of    Sample     Sample
                        Size    ones        Mean     Variance
            Sample 1    150      30         0.2        0.161073
            Sample 2    200      45         0.225      0.175251

        The sample mean :math:`\hat{p}` is the proportion of ones in the sample
        and the variance for a binary observation is estimated by
        :math:`\hat{p}(1-\hat{p})`.

        >>> ttest_ind_from_stats(mean1=0.2, std1=np.sqrt(0.161073), nobs1=150,
        ...                      mean2=0.225, std2=np.sqrt(0.175251), nobs2=200)
        Ttest_indResult(statistic=-0.5627187905196761, pvalue=0.5739887114209541)

        For comparison, we could compute the t statistic and p-value using
        arrays of 0s and 1s and `scipy.stat.ttest_ind`, as above.

        >>> group1 = np.array([1]*30 + [0]*(150-30))
        >>> group2 = np.array([1]*45 + [0]*(200-45))
        >>> ttest_ind(group1, group2)
        TtestResult(statistic=-0.5627179589855622,
                    pvalue=0.573989277115258,
                    df=348.0)

    ttest_rel(a, b, axis=0, nan_policy='propagate', alternative='two-sided', *, keepdims=False)
        Calculate the t-test on TWO RELATED samples of scores, a and b.

        This is a test for the null hypothesis that two related or
        repeated samples have identical average (expected) values.

        Parameters
        ----------
        a, b : array_like
            The arrays must have the same shape.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        alternative : {'two-sided', 'less', 'greater'}, optional
            Defines the alternative hypothesis.
            The following options are available (default is 'two-sided'):

            * 'two-sided': the means of the distributions underlying the samples
              are unequal.
            * 'less': the mean of the distribution underlying the first sample
              is less than the mean of the distribution underlying the second
              sample.
            * 'greater': the mean of the distribution underlying the first
              sample is greater than the mean of the distribution underlying
              the second sample.

            .. versionadded:: 1.6.0
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        result : `~scipy.stats._result_classes.TtestResult`
            An object with the following attributes:

            statistic : float or array
                The t-statistic.
            pvalue : float or array
                The p-value associated with the given alternative.
            df : float or array
                The number of degrees of freedom used in calculation of the
                t-statistic; this is one less than the size of the sample
                (``a.shape[axis]``).

                .. versionadded:: 1.10.0

            The object also has the following method:

            confidence_interval(confidence_level=0.95)
                Computes a confidence interval around the difference in
                population means for the given confidence level.
                The confidence interval is returned in a ``namedtuple`` with
                fields `low` and `high`.

                .. versionadded:: 1.10.0

        Notes
        -----
        Examples for use are scores of the same set of student in
        different exams, or repeated sampling from the same units. The
        test measures whether the average score differs significantly
        across samples (e.g. exams). If we observe a large p-value, for
        example greater than 0.05 or 0.1 then we cannot reject the null
        hypothesis of identical average scores. If the p-value is smaller
        than the threshold, e.g. 1%, 5% or 10%, then we reject the null
        hypothesis of equal averages. Small p-values are associated with
        large t-statistics.

        The t-statistic is calculated as ``np.mean(a - b)/se``, where ``se`` is the
        standard error. Therefore, the t-statistic will be positive when the sample
        mean of ``a - b`` is greater than zero and negative when the sample mean of
        ``a - b`` is less than zero.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        https://en.wikipedia.org/wiki/T-test#Dependent_t-test_for_paired_samples

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> rng = np.random.default_rng()

        >>> rvs1 = stats.norm.rvs(loc=5, scale=10, size=500, random_state=rng)
        >>> rvs2 = (stats.norm.rvs(loc=5, scale=10, size=500, random_state=rng)
        ...         + stats.norm.rvs(scale=0.2, size=500, random_state=rng))
        >>> stats.ttest_rel(rvs1, rvs2)
        TtestResult(statistic=-0.4549717054410304, pvalue=0.6493274702088672, df=499)
        >>> rvs3 = (stats.norm.rvs(loc=8, scale=10, size=500, random_state=rng)
        ...         + stats.norm.rvs(scale=0.2, size=500, random_state=rng))
        >>> stats.ttest_rel(rvs1, rvs3)
        TtestResult(statistic=-5.879467544540889, pvalue=7.540777129099917e-09, df=499)

    tukey_hsd(*args)
        Perform Tukey's HSD test for equality of means over multiple treatments.

        Tukey's honestly significant difference (HSD) test performs pairwise
        comparison of means for a set of samples. Whereas ANOVA (e.g. `f_oneway`)
        assesses whether the true means underlying each sample are identical,
        Tukey's HSD is a post hoc test used to compare the mean of each sample
        to the mean of each other sample.

        The null hypothesis is that the distributions underlying the samples all
        have the same mean. The test statistic, which is computed for every
        possible pairing of samples, is simply the difference between the sample
        means. For each pair, the p-value is the probability under the null
        hypothesis (and other assumptions; see notes) of observing such an extreme
        value of the statistic, considering that many pairwise comparisons are
        being performed. Confidence intervals for the difference between each pair
        of means are also available.

        Parameters
        ----------
        sample1, sample2, ... : array_like
            The sample measurements for each group. There must be at least
            two arguments.

        Returns
        -------
        result : `~scipy.stats._result_classes.TukeyHSDResult` instance
            The return value is an object with the following attributes:

            statistic : float ndarray
                The computed statistic of the test for each comparison. The element
                at index ``(i, j)`` is the statistic for the comparison between
                groups ``i`` and ``j``.
            pvalue : float ndarray
                The computed p-value of the test for each comparison. The element
                at index ``(i, j)`` is the p-value for the comparison between
                groups ``i`` and ``j``.

            The object has the following methods:

            confidence_interval(confidence_level=0.95):
                Compute the confidence interval for the specified confidence level.

        See Also
        --------
        dunnett : performs comparison of means against a control group.

        Notes
        -----
        The use of this test relies on several assumptions.

        1. The observations are independent within and among groups.
        2. The observations within each group are normally distributed.
        3. The distributions from which the samples are drawn have the same finite
           variance.

        The original formulation of the test was for samples of equal size [6]_.
        In case of unequal sample sizes, the test uses the Tukey-Kramer method
        [4]_.

        References
        ----------
        .. [1] NIST/SEMATECH e-Handbook of Statistical Methods, "7.4.7.1. Tukey's
               Method."
               https://www.itl.nist.gov/div898/handbook/prc/section4/prc471.htm,
               28 November 2020.
        .. [2] Abdi, Herve & Williams, Lynne. (2021). "Tukey's Honestly Significant
               Difference (HSD) Test."
               https://personal.utdallas.edu/~herve/abdi-HSD2010-pretty.pdf
        .. [3] "One-Way ANOVA Using SAS PROC ANOVA & PROC GLM." SAS
               Tutorials, 2007, www.stattutorials.com/SAS/TUTORIAL-PROC-GLM.htm.
        .. [4] Kramer, Clyde Young. "Extension of Multiple Range Tests to Group
               Means with Unequal Numbers of Replications." Biometrics, vol. 12,
               no. 3, 1956, pp. 307-310. JSTOR, www.jstor.org/stable/3001469.
               Accessed 25 May 2021.
        .. [5] NIST/SEMATECH e-Handbook of Statistical Methods, "7.4.3.3.
               The ANOVA table and tests of hypotheses about means"
               https://www.itl.nist.gov/div898/handbook/prc/section4/prc433.htm,
               2 June 2021.
        .. [6] Tukey, John W. "Comparing Individual Means in the Analysis of
               Variance." Biometrics, vol. 5, no. 2, 1949, pp. 99-114. JSTOR,
               www.jstor.org/stable/3001913. Accessed 14 June 2021.


        Examples
        --------
        Here are some data comparing the time to relief of three brands of
        headache medicine, reported in minutes. Data adapted from [3]_.

        >>> import numpy as np
        >>> from scipy.stats import tukey_hsd
        >>> group0 = [24.5, 23.5, 26.4, 27.1, 29.9]
        >>> group1 = [28.4, 34.2, 29.5, 32.2, 30.1]
        >>> group2 = [26.1, 28.3, 24.3, 26.2, 27.8]

        We would like to see if the means between any of the groups are
        significantly different. First, visually examine a box and whisker plot.

        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.boxplot([group0, group1, group2])
        >>> ax.set_xticklabels(["group0", "group1", "group2"]) # doctest: +SKIP
        >>> ax.set_ylabel("mean") # doctest: +SKIP
        >>> plt.show()

        From the box and whisker plot, we can see overlap in the interquartile
        ranges group 1 to group 2 and group 3, but we can apply the ``tukey_hsd``
        test to determine if the difference between means is significant. We
        set a significance level of .05 to reject the null hypothesis.

        >>> res = tukey_hsd(group0, group1, group2)
        >>> print(res)
        Tukey's HSD Pairwise Group Comparisons (95.0% Confidence Interval)
        Comparison  Statistic  p-value   Lower CI   Upper CI
        (0 - 1)     -4.600      0.014     -8.249     -0.951
        (0 - 2)     -0.260      0.980     -3.909      3.389
        (1 - 0)      4.600      0.014      0.951      8.249
        (1 - 2)      4.340      0.020      0.691      7.989
        (2 - 0)      0.260      0.980     -3.389      3.909
        (2 - 1)     -4.340      0.020     -7.989     -0.691

        The null hypothesis is that each group has the same mean. The p-value for
        comparisons between ``group0`` and ``group1`` as well as ``group1`` and
        ``group2`` do not exceed .05, so we reject the null hypothesis that they
        have the same means. The p-value of the comparison between ``group0``
        and ``group2`` exceeds .05, so we accept the null hypothesis that there
        is not a significant difference between their means.

        We can also compute the confidence interval associated with our chosen
        confidence level.

        >>> group0 = [24.5, 23.5, 26.4, 27.1, 29.9]
        >>> group1 = [28.4, 34.2, 29.5, 32.2, 30.1]
        >>> group2 = [26.1, 28.3, 24.3, 26.2, 27.8]
        >>> result = tukey_hsd(group0, group1, group2)
        >>> conf = res.confidence_interval(confidence_level=.99)
        >>> for ((i, j), l) in np.ndenumerate(conf.low):
        ...     # filter out self comparisons
        ...     if i != j:
        ...         h = conf.high[i,j]
        ...         print(f"({i} - {j}) {l:>6.3f} {h:>6.3f}")
        (0 - 1) -9.480  0.280
        (0 - 2) -5.140  4.620
        (1 - 0) -0.280  9.480
        (1 - 2) -0.540  9.220
        (2 - 0) -4.620  5.140
        (2 - 1) -9.220  0.540

    tvar(a, limits=None, inclusive=(True, True), axis=0, ddof=1, *, nan_policy='propagate', keepdims=False)
        Compute the trimmed variance.

        This function computes the sample variance of an array of values,
        while ignoring values which are outside of given `limits`.

        Parameters
        ----------
        a : array_like
            Array of values.
        limits : None or (lower limit, upper limit), optional
            Values in the input array less than the lower limit or greater than the
            upper limit will be ignored. When limits is None, then all values are
            used. Either of the limit values in the tuple can also be None
            representing a half-open interval.  The default value is None.
        inclusive : (bool, bool), optional
            A tuple consisting of the (lower flag, upper flag).  These flags
            determine whether values exactly equal to the lower or upper limits
            are included.  The default value is (True, True).
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        ddof : int, optional
            Delta degrees of freedom.  Default is 1.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        tvar : float
            Trimmed variance.

        Notes
        -----
        `tvar` computes the unbiased sample variance, i.e. it uses a correction
        factor ``n / (n - 1)``.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = np.arange(20)
        >>> stats.tvar(x)
        35.0
        >>> stats.tvar(x, (3,17))
        20.0

    variation(a, axis=0, nan_policy='propagate', ddof=0, *, keepdims=False)
        Compute the coefficient of variation.

        The coefficient of variation is the standard deviation divided by the
        mean.  This function is equivalent to::

            np.std(x, axis=axis, ddof=ddof) / np.mean(x)

        The default for ``ddof`` is 0, but many definitions of the coefficient
        of variation use the square root of the unbiased sample variance
        for the sample standard deviation, which corresponds to ``ddof=1``.

        The function does not take the absolute value of the mean of the data,
        so the return value is negative if the mean is negative.

        Parameters
        ----------
        a : array_like
            Input array.
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        ddof : int, optional
            Gives the "Delta Degrees Of Freedom" used when computing the
            standard deviation.  The divisor used in the calculation of the
            standard deviation is ``N - ddof``, where ``N`` is the number of
            elements.  `ddof` must be less than ``N``; if it isn't, the result
            will be ``nan`` or ``inf``, depending on ``N`` and the values in
            the array.  By default `ddof` is zero for backwards compatibility,
            but it is recommended to use ``ddof=1`` to ensure that the sample
            standard deviation is computed as the square root of the unbiased
            sample variance.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        variation : ndarray
            The calculated variation along the requested axis.

        Notes
        -----
        There are several edge cases that are handled without generating a
        warning:

        * If both the mean and the standard deviation are zero, ``nan``
          is returned.
        * If the mean is zero and the standard deviation is nonzero, ``inf``
          is returned.
        * If the input has length zero (either because the array has zero
          length, or all the input values are ``nan`` and ``nan_policy`` is
          ``'omit'``), ``nan`` is returned.
        * If the input contains ``inf``, ``nan`` is returned.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] Zwillinger, D. and Kokoska, S. (2000). CRC Standard
           Probability and Statistics Tables and Formulae. Chapman & Hall: New
           York. 2000.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import variation
        >>> variation([1, 2, 3, 4, 5], ddof=1)
        0.5270462766947299

        Compute the variation along a given dimension of an array that contains
        a few ``nan`` values:

        >>> x = np.array([[  10.0, np.nan, 11.0, 19.0, 23.0, 29.0, 98.0],
        ...               [  29.0,   30.0, 32.0, 33.0, 35.0, 56.0, 57.0],
        ...               [np.nan, np.nan, 12.0, 13.0, 16.0, 16.0, 17.0]])
        >>> variation(x, axis=1, ddof=1, nan_policy='omit')
        array([1.05109361, 0.31428986, 0.146483  ])

    wasserstein_distance(u_values, v_values, u_weights=None, v_weights=None)
        Compute the Wasserstein-1 distance between two 1D discrete distributions.

        The Wasserstein distance, also called the Earth mover's distance or the
        optimal transport distance, is a similarity metric between two probability
        distributions [1]_. In the discrete case, the Wasserstein distance can be
        understood as the cost of an optimal transport plan to convert one
        distribution into the other. The cost is calculated as the product of the
        amount of probability mass being moved and the distance it is being moved.
        A brief and intuitive introduction can be found at [2]_.

        .. versionadded:: 1.0.0

        Parameters
        ----------
        u_values : 1d array_like
            A sample from a probability distribution or the support (set of all
            possible values) of a probability distribution. Each element is an
            observation or possible value.

        v_values : 1d array_like
            A sample from or the support of a second distribution.

        u_weights, v_weights : 1d array_like, optional
            Weights or counts corresponding with the sample or probability masses
            corresponding with the support values. Sum of elements must be positive
            and finite. If unspecified, each value is assigned the same weight.

        Returns
        -------
        distance : float
            The computed distance between the distributions.

        Notes
        -----
        Given two 1D probability mass functions, :math:`u` and :math:`v`, the first
        Wasserstein distance between the distributions is:

        .. math::

            l_1 (u, v) = \inf_{\pi \in \Gamma (u, v)} \int_{\mathbb{R} \times
            \mathbb{R}} |x-y| \mathrm{d} \pi (x, y)

        where :math:`\Gamma (u, v)` is the set of (probability) distributions on
        :math:`\mathbb{R} \times \mathbb{R}` whose marginals are :math:`u` and
        :math:`v` on the first and second factors respectively. For a given value
        :math:`x`, :math:`u(x)` gives the probabilty of :math:`u` at position
        :math:`x`, and the same for :math:`v(x)`.

        If :math:`U` and :math:`V` are the respective CDFs of :math:`u` and
        :math:`v`, this distance also equals to:

        .. math::

            l_1(u, v) = \int_{-\infty}^{+\infty} |U-V|

        See [3]_ for a proof of the equivalence of both definitions.

        The input distributions can be empirical, therefore coming from samples
        whose values are effectively inputs of the function, or they can be seen as
        generalized functions, in which case they are weighted sums of Dirac delta
        functions located at the specified values.

        References
        ----------
        .. [1] "Wasserstein metric", https://en.wikipedia.org/wiki/Wasserstein_metric
        .. [2] Lili Weng, "What is Wasserstein distance?", Lil'log,
               https://lilianweng.github.io/posts/2017-08-20-gan/#what-is-wasserstein-distance.
        .. [3] Ramdas, Garcia, Cuturi "On Wasserstein Two Sample Testing and Related
               Families of Nonparametric Tests" (2015). :arXiv:`1509.02237`.

        See Also
        --------
        wasserstein_distance_nd: Compute the Wasserstein-1 distance between two N-D
            discrete distributions.

        Examples
        --------
        >>> from scipy.stats import wasserstein_distance
        >>> wasserstein_distance([0, 1, 3], [5, 6, 8])
        5.0
        >>> wasserstein_distance([0, 1], [0, 1], [3, 1], [2, 2])
        0.25
        >>> wasserstein_distance([3.4, 3.9, 7.5, 7.8], [4.5, 1.4],
        ...                      [1.4, 0.9, 3.1, 7.2], [3.2, 3.5])
        4.0781331438047861

    wasserstein_distance_nd(u_values, v_values, u_weights=None, v_weights=None)
        Compute the Wasserstein-1 distance between two N-D discrete distributions.

        The Wasserstein distance, also called the Earth mover's distance or the
        optimal transport distance, is a similarity metric between two probability
        distributions [1]_. In the discrete case, the Wasserstein distance can be
        understood as the cost of an optimal transport plan to convert one
        distribution into the other. The cost is calculated as the product of the
        amount of probability mass being moved and the distance it is being moved.
        A brief and intuitive introduction can be found at [2]_.

        .. versionadded:: 1.13.0

        Parameters
        ----------
        u_values : 2d array_like
            A sample from a probability distribution or the support (set of all
            possible values) of a probability distribution. Each element along
            axis 0 is an observation or possible value, and axis 1 represents the
            dimensionality of the distribution; i.e., each row is a vector
            observation or possible value.

        v_values : 2d array_like
            A sample from or the support of a second distribution.

        u_weights, v_weights : 1d array_like, optional
            Weights or counts corresponding with the sample or probability masses
            corresponding with the support values. Sum of elements must be positive
            and finite. If unspecified, each value is assigned the same weight.

        Returns
        -------
        distance : float
            The computed distance between the distributions.

        Notes
        -----
        Given two probability mass functions, :math:`u`
        and :math:`v`, the first Wasserstein distance between the distributions
        using the Euclidean norm is:

        .. math::

            l_1 (u, v) = \inf_{\pi \in \Gamma (u, v)} \int \| x-y \|_2 \mathrm{d} \pi (x, y)

        where :math:`\Gamma (u, v)` is the set of (probability) distributions on
        :math:`\mathbb{R}^n \times \mathbb{R}^n` whose marginals are :math:`u` and
        :math:`v` on the first and second factors respectively. For a given value
        :math:`x`, :math:`u(x)` gives the probabilty of :math:`u` at position
        :math:`x`, and the same for :math:`v(x)`.

        This is also called the optimal transport problem or the Monge problem.
        Let the finite point sets :math:`\{x_i\}` and :math:`\{y_j\}` denote
        the support set of probability mass function :math:`u` and :math:`v`
        respectively. The Monge problem can be expressed as follows,

        Let :math:`\Gamma` denote the transport plan, :math:`D` denote the
        distance matrix and,

        .. math::

            x = \text{vec}(\Gamma)          \\
            c = \text{vec}(D)               \\
            b = \begin{bmatrix}
                    u\\
                    v\\
                \end{bmatrix}

        The :math:`\text{vec}()` function denotes the Vectorization function
        that transforms a matrix into a column vector by vertically stacking
        the columns of the matrix.
        The tranport plan :math:`\Gamma` is a matrix :math:`[\gamma_{ij}]` in
        which :math:`\gamma_{ij}` is a positive value representing the amount of
        probability mass transported from :math:`u(x_i)` to :math:`v(y_i)`.
        Summing over the rows of :math:`\Gamma` should give the source distribution
        :math:`u` : :math:`\sum_j \gamma_{ij} = u(x_i)` holds for all :math:`i`
        and summing over the columns of :math:`\Gamma` should give the target
        distribution :math:`v`: :math:`\sum_i \gamma_{ij} = v(y_j)` holds for all
        :math:`j`.
        The distance matrix :math:`D` is a matrix :math:`[d_{ij}]`, in which
        :math:`d_{ij} = d(x_i, y_j)`.

        Given :math:`\Gamma`, :math:`D`, :math:`b`, the Monge problem can be
        tranformed into a linear programming problem by
        taking :math:`A x = b` as constraints and :math:`z = c^T x` as minimization
        target (sum of costs) , where matrix :math:`A` has the form

        .. math::

            \begin{array} {rrrr|rrrr|r|rrrr}
                1 & 1 & \dots & 1 & 0 & 0 & \dots & 0 & \dots & 0 & 0 & \dots &
                    0 \cr
                0 & 0 & \dots & 0 & 1 & 1 & \dots & 1 & \dots & 0 & 0 &\dots &
                    0 \cr
                \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots
                    & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots  \cr
                0 & 0 & \dots & 0 & 0 & 0 & \dots & 0 & \dots & 1 & 1 & \dots &
                    1 \cr \hline

                1 & 0 & \dots & 0 & 1 & 0 & \dots & \dots & \dots & 1 & 0 & \dots &
                    0 \cr
                0 & 1 & \dots & 0 & 0 & 1 & \dots & \dots & \dots & 0 & 1 & \dots &
                    0 \cr
                \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots &
                    \vdots & \vdots & \vdots & \vdots & \ddots & \vdots \cr
                0 & 0 & \dots & 1 & 0 & 0 & \dots & 1 & \dots & 0 & 0 & \dots & 1
            \end{array}

        By solving the dual form of the above linear programming problem (with
        solution :math:`y^*`), the Wasserstein distance :math:`l_1 (u, v)` can
        be computed as :math:`b^T y^*`.

        The above solution is inspired by Vincent Herrmann's blog [3]_ . For a
        more thorough explanation, see [4]_ .

        The input distributions can be empirical, therefore coming from samples
        whose values are effectively inputs of the function, or they can be seen as
        generalized functions, in which case they are weighted sums of Dirac delta
        functions located at the specified values.

        References
        ----------
        .. [1] "Wasserstein metric",
               https://en.wikipedia.org/wiki/Wasserstein_metric
        .. [2] Lili Weng, "What is Wasserstein distance?", Lil'log,
               https://lilianweng.github.io/posts/2017-08-20-gan/#what-is-wasserstein-distance.
        .. [3] Hermann, Vincent. "Wasserstein GAN and the Kantorovich-Rubinstein
               Duality". https://vincentherrmann.github.io/blog/wasserstein/.
        .. [4] Peyré, Gabriel, and Marco Cuturi. "Computational optimal
               transport." Center for Research in Economics and Statistics
               Working Papers 2017-86 (2017).

        See Also
        --------
        wasserstein_distance: Compute the Wasserstein-1 distance between two
            1D discrete distributions.

        Examples
        --------
        Compute the Wasserstein distance between two three-dimensional samples,
        each with two observations.

        >>> from scipy.stats import wasserstein_distance_nd
        >>> wasserstein_distance_nd([[0, 2, 3], [1, 2, 5]], [[3, 2, 3], [4, 2, 5]])
        3.0

        Compute the Wasserstein distance between two two-dimensional distributions
        with three and two weighted observations, respectively.

        >>> wasserstein_distance_nd([[0, 2.75], [2, 209.3], [0, 0]],
        ...                      [[0.2, 0.322], [4.5, 25.1808]],
        ...                      [0.4, 5.2, 0.114], [0.8, 1.5])
        174.15840245217169

    weightedtau(x, y, rank=True, weigher=None, additive=True)
        Compute a weighted version of Kendall's :math:`\tau`.

        The weighted :math:`\tau` is a weighted version of Kendall's
        :math:`\tau` in which exchanges of high weight are more influential than
        exchanges of low weight. The default parameters compute the additive
        hyperbolic version of the index, :math:`\tau_\mathrm h`, which has
        been shown to provide the best balance between important and
        unimportant elements [1]_.

        The weighting is defined by means of a rank array, which assigns a
        nonnegative rank to each element (higher importance ranks being
        associated with smaller values, e.g., 0 is the highest possible rank),
        and a weigher function, which assigns a weight based on the rank to
        each element. The weight of an exchange is then the sum or the product
        of the weights of the ranks of the exchanged elements. The default
        parameters compute :math:`\tau_\mathrm h`: an exchange between
        elements with rank :math:`r` and :math:`s` (starting from zero) has
        weight :math:`1/(r+1) + 1/(s+1)`.

        Specifying a rank array is meaningful only if you have in mind an
        external criterion of importance. If, as it usually happens, you do
        not have in mind a specific rank, the weighted :math:`\tau` is
        defined by averaging the values obtained using the decreasing
        lexicographical rank by (`x`, `y`) and by (`y`, `x`). This is the
        behavior with default parameters. Note that the convention used
        here for ranking (lower values imply higher importance) is opposite
        to that used by other SciPy statistical functions.

        Parameters
        ----------
        x, y : array_like
            Arrays of scores, of the same shape. If arrays are not 1-D, they will
            be flattened to 1-D.
        rank : array_like of ints or bool, optional
            A nonnegative rank assigned to each element. If it is None, the
            decreasing lexicographical rank by (`x`, `y`) will be used: elements of
            higher rank will be those with larger `x`-values, using `y`-values to
            break ties (in particular, swapping `x` and `y` will give a different
            result). If it is False, the element indices will be used
            directly as ranks. The default is True, in which case this
            function returns the average of the values obtained using the
            decreasing lexicographical rank by (`x`, `y`) and by (`y`, `x`).
        weigher : callable, optional
            The weigher function. Must map nonnegative integers (zero
            representing the most important element) to a nonnegative weight.
            The default, None, provides hyperbolic weighing, that is,
            rank :math:`r` is mapped to weight :math:`1/(r+1)`.
        additive : bool, optional
            If True, the weight of an exchange is computed by adding the
            weights of the ranks of the exchanged elements; otherwise, the weights
            are multiplied. The default is True.

        Returns
        -------
        res: SignificanceResult
            An object containing attributes:

            statistic : float
               The weighted :math:`\tau` correlation index.
            pvalue : float
               Presently ``np.nan``, as the null distribution of the statistic is
               unknown (even in the additive hyperbolic case).

        See Also
        --------
        kendalltau : Calculates Kendall's tau.
        spearmanr : Calculates a Spearman rank-order correlation coefficient.
        theilslopes : Computes the Theil-Sen estimator for a set of points (x, y).

        Notes
        -----
        This function uses an :math:`O(n \log n)`, mergesort-based algorithm
        [1]_ that is a weighted extension of Knight's algorithm for Kendall's
        :math:`\tau` [2]_. It can compute Shieh's weighted :math:`\tau` [3]_
        between rankings without ties (i.e., permutations) by setting
        `additive` and `rank` to False, as the definition given in [1]_ is a
        generalization of Shieh's.

        NaNs are considered the smallest possible score.

        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] Sebastiano Vigna, "A weighted correlation index for rankings with
               ties", Proceedings of the 24th international conference on World
               Wide Web, pp. 1166-1176, ACM, 2015.
        .. [2] W.R. Knight, "A Computer Method for Calculating Kendall's Tau with
               Ungrouped Data", Journal of the American Statistical Association,
               Vol. 61, No. 314, Part 1, pp. 436-439, 1966.
        .. [3] Grace S. Shieh. "A weighted Kendall's tau statistic", Statistics &
               Probability Letters, Vol. 39, No. 1, pp. 17-24, 1998.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> x = [12, 2, 1, 12, 2]
        >>> y = [1, 4, 7, 1, 0]
        >>> res = stats.weightedtau(x, y)
        >>> res.statistic
        -0.56694968153682723
        >>> res.pvalue
        nan
        >>> res = stats.weightedtau(x, y, additive=False)
        >>> res.statistic
        -0.62205716951801038

        NaNs are considered the smallest possible score:

        >>> x = [12, 2, 1, 12, 2]
        >>> y = [1, 4, 7, 1, np.nan]
        >>> res = stats.weightedtau(x, y)
        >>> res.statistic
        -0.56694968153682723

        This is exactly Kendall's tau:

        >>> x = [12, 2, 1, 12, 2]
        >>> y = [1, 4, 7, 1, 0]
        >>> res = stats.weightedtau(x, y, weigher=lambda x: 1)
        >>> res.statistic
        -0.47140452079103173

        >>> x = [12, 2, 1, 12, 2]
        >>> y = [1, 4, 7, 1, 0]
        >>> stats.weightedtau(x, y, rank=None)
        SignificanceResult(statistic=-0.4157652301037516, pvalue=nan)
        >>> stats.weightedtau(y, x, rank=None)
        SignificanceResult(statistic=-0.7181341329699028, pvalue=nan)

    wilcoxon(x, y=None, zero_method='wilcox', correction=False, alternative='two-sided', method='auto', *, axis=0, nan_policy='propagate', keepdims=False)
        Calculate the Wilcoxon signed-rank test.

        The Wilcoxon signed-rank test tests the null hypothesis that two
        related paired samples come from the same distribution. In particular,
        it tests whether the distribution of the differences ``x - y`` is symmetric
        about zero. It is a non-parametric version of the paired T-test.

        Parameters
        ----------
        x : array_like
            Either the first set of measurements (in which case ``y`` is the second
            set of measurements), or the differences between two sets of
            measurements (in which case ``y`` is not to be specified.)  Must be
            one-dimensional.
        y : array_like, optional
            Either the second set of measurements (if ``x`` is the first set of
            measurements), or not specified (if ``x`` is the differences between
            two sets of measurements.)  Must be one-dimensional.

            .. warning::
                When `y` is provided, `wilcoxon` calculates the test statistic
                based on the ranks of the absolute values of ``d = x - y``.
                Roundoff error in the subtraction can result in elements of ``d``
                being assigned different ranks even when they would be tied with
                exact arithmetic. Rather than passing `x` and `y` separately,
                consider computing the difference ``x - y``, rounding as needed to
                ensure that only truly unique elements are numerically distinct,
                and passing the result as `x`, leaving `y` at the default (None).
        zero_method : {"wilcox", "pratt", "zsplit"}, optional
            There are different conventions for handling pairs of observations
            with equal values ("zero-differences", or "zeros").

            * "wilcox": Discards all zero-differences (default); see [4]_.
            * "pratt": Includes zero-differences in the ranking process,
              but drops the ranks of the zeros (more conservative); see [3]_.
              In this case, the normal approximation is adjusted as in [5]_.
            * "zsplit": Includes zero-differences in the ranking process and
              splits the zero rank between positive and negative ones.
        correction : bool, optional
            If True, apply continuity correction by adjusting the Wilcoxon rank
            statistic by 0.5 towards the mean value when computing the
            z-statistic if a normal approximation is used.  Default is False.
        alternative : {"two-sided", "greater", "less"}, optional
            Defines the alternative hypothesis. Default is 'two-sided'.
            In the following, let ``d`` represent the difference between the paired
            samples: ``d = x - y`` if both ``x`` and ``y`` are provided, or
            ``d = x`` otherwise.

            * 'two-sided': the distribution underlying ``d`` is not symmetric
              about zero.
            * 'less': the distribution underlying ``d`` is stochastically less
              than a distribution symmetric about zero.
            * 'greater': the distribution underlying ``d`` is stochastically
              greater than a distribution symmetric about zero.
        method : {"auto", "exact", "approx"} or `PermutationMethod` instance, optional
            Method to calculate the p-value, see Notes. Default is "auto".
        axis : int or None, default: 0
            If an int, the axis of the input along which to compute the statistic.
            The statistic of each axis-slice (e.g. row) of the input will appear in a
            corresponding element of the output.
            If ``None``, the input will be raveled before computing the statistic.
        nan_policy : {'propagate', 'omit', 'raise'}
            Defines how to handle input NaNs.

            - ``propagate``: if a NaN is present in the axis slice (e.g. row) along
              which the  statistic is computed, the corresponding entry of the output
              will be NaN.
            - ``omit``: NaNs will be omitted when performing the calculation.
              If insufficient data remains in the axis slice along which the
              statistic is computed, the corresponding entry of the output will be
              NaN.
            - ``raise``: if a NaN is present, a ``ValueError`` will be raised.
        keepdims : bool, default: False
            If this is set to True, the axes which are reduced are left
            in the result as dimensions with size one. With this option,
            the result will broadcast correctly against the input array.

        Returns
        -------
        An object with the following attributes.
        statistic : array_like
            If `alternative` is "two-sided", the sum of the ranks of the
            differences above or below zero, whichever is smaller.
            Otherwise the sum of the ranks of the differences above zero.
        pvalue : array_like
            The p-value for the test depending on `alternative` and `method`.
        zstatistic : array_like
            When ``method = 'approx'``, this is the normalized z-statistic::

                z = (T - mn - d) / se

            where ``T`` is `statistic` as defined above, ``mn`` is the mean of the
            distribution under the null hypothesis, ``d`` is a continuity
            correction, and ``se`` is the standard error.
            When ``method != 'approx'``, this attribute is not available.

        See Also
        --------

        :func:`kruskal`, :func:`mannwhitneyu`
            ..

        Notes
        -----
        In the following, let ``d`` represent the difference between the paired
        samples: ``d = x - y`` if both ``x`` and ``y`` are provided, or ``d = x``
        otherwise. Assume that all elements of ``d`` are independent and
        identically distributed observations, and all are distinct and nonzero.

        - When ``len(d)`` is sufficiently large, the null distribution of the
          normalized test statistic (`zstatistic` above) is approximately normal,
          and ``method = 'approx'`` can be used to compute the p-value.

        - When ``len(d)`` is small, the normal approximation may not be accurate,
          and ``method='exact'`` is preferred (at the cost of additional
          execution time).

        - The default, ``method='auto'``, selects between the two: when
          ``len(d) <= 50`` and there are no zeros, the exact method is used;
          otherwise, the approximate method is used.

        The presence of "ties" (i.e. not all elements of ``d`` are unique) or
        "zeros" (i.e. elements of ``d`` are zero) changes the null distribution
        of the test statistic, and ``method='exact'`` no longer calculates
        the exact p-value. If ``method='approx'``, the z-statistic is adjusted
        for more accurate comparison against the standard normal, but still,
        for finite sample sizes, the standard normal is only an approximation of
        the true null distribution of the z-statistic. For such situations, the
        `method` parameter also accepts instances `PermutationMethod`. In this
        case, the p-value is computed using `permutation_test` with the provided
        configuration options and other appropriate settings.

        Beginning in SciPy 1.9, ``np.matrix`` inputs (not recommended for new
        code) are converted to ``np.ndarray`` before the calculation is performed. In
        this case, the output will be a scalar or ``np.ndarray`` of appropriate shape
        rather than a 2D ``np.matrix``. Similarly, while masked elements of masked
        arrays are ignored, the output will be a scalar or ``np.ndarray`` rather than a
        masked array with ``mask=False``.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test
        .. [2] Conover, W.J., Practical Nonparametric Statistics, 1971.
        .. [3] Pratt, J.W., Remarks on Zeros and Ties in the Wilcoxon Signed
           Rank Procedures, Journal of the American Statistical Association,
           Vol. 54, 1959, pp. 655-667. :doi:`10.1080/01621459.1959.10501526`
        .. [4] Wilcoxon, F., Individual Comparisons by Ranking Methods,
           Biometrics Bulletin, Vol. 1, 1945, pp. 80-83. :doi:`10.2307/3001968`
        .. [5] Cureton, E.E., The Normal Approximation to the Signed-Rank
           Sampling Distribution When Zero Differences are Present,
           Journal of the American Statistical Association, Vol. 62, 1967,
           pp. 1068-1069. :doi:`10.1080/01621459.1967.10500917`

        Examples
        --------
        In [4]_, the differences in height between cross- and self-fertilized
        corn plants is given as follows:

        >>> d = [6, 8, 14, 16, 23, 24, 28, 29, 41, -48, 49, 56, 60, -67, 75]

        Cross-fertilized plants appear to be higher. To test the null
        hypothesis that there is no height difference, we can apply the
        two-sided test:

        >>> from scipy.stats import wilcoxon
        >>> res = wilcoxon(d)
        >>> res.statistic, res.pvalue
        (24.0, 0.041259765625)

        Hence, we would reject the null hypothesis at a confidence level of 5%,
        concluding that there is a difference in height between the groups.
        To confirm that the median of the differences can be assumed to be
        positive, we use:

        >>> res = wilcoxon(d, alternative='greater')
        >>> res.statistic, res.pvalue
        (96.0, 0.0206298828125)

        This shows that the null hypothesis that the median is negative can be
        rejected at a confidence level of 5% in favor of the alternative that
        the median is greater than zero. The p-values above are exact. Using the
        normal approximation gives very similar values:

        >>> res = wilcoxon(d, method='approx')
        >>> res.statistic, res.pvalue
        (24.0, 0.04088813291185591)

        Note that the statistic changed to 96 in the one-sided case (the sum
        of ranks of positive differences) whereas it is 24 in the two-sided
        case (the minimum of sum of ranks above and below zero).

        In the example above, the differences in height between paired plants are
        provided to `wilcoxon` directly. Alternatively, `wilcoxon` accepts two
        samples of equal length, calculates the differences between paired
        elements, then performs the test. Consider the samples ``x`` and ``y``:

        >>> import numpy as np
        >>> x = np.array([0.5, 0.825, 0.375, 0.5])
        >>> y = np.array([0.525, 0.775, 0.325, 0.55])
        >>> res = wilcoxon(x, y, alternative='greater')
        >>> res
        WilcoxonResult(statistic=5.0, pvalue=0.5625)

        Note that had we calculated the differences by hand, the test would have
        produced different results:

        >>> d = [-0.025, 0.05, 0.05, -0.05]
        >>> ref = wilcoxon(d, alternative='greater')
        >>> ref
        WilcoxonResult(statistic=6.0, pvalue=0.4375)

        The substantial difference is due to roundoff error in the results of
        ``x-y``:

        >>> d - (x-y)
        array([2.08166817e-17, 6.93889390e-17, 1.38777878e-17, 4.16333634e-17])

        Even though we expected all the elements of ``(x-y)[1:]`` to have the same
        magnitude ``0.05``, they have slightly different magnitudes in practice,
        and therefore are assigned different ranks in the test. Before performing
        the test, consider calculating ``d`` and adjusting it as necessary to
        ensure that theoretically identically values are not numerically distinct.
        For example:

        >>> d2 = np.around(x - y, decimals=3)
        >>> wilcoxon(d2, alternative='greater')
        WilcoxonResult(statistic=6.0, pvalue=0.4375)

    yeojohnson(x, lmbda=None)
        Return a dataset transformed by a Yeo-Johnson power transformation.

        Parameters
        ----------
        x : ndarray
            Input array.  Should be 1-dimensional.
        lmbda : float, optional
            If ``lmbda`` is ``None``, find the lambda that maximizes the
            log-likelihood function and return it as the second output argument.
            Otherwise the transformation is done for the given value.

        Returns
        -------
        yeojohnson: ndarray
            Yeo-Johnson power transformed array.
        maxlog : float, optional
            If the `lmbda` parameter is None, the second returned argument is
            the lambda that maximizes the log-likelihood function.

        See Also
        --------
        probplot, yeojohnson_normplot, yeojohnson_normmax, yeojohnson_llf, boxcox

        Notes
        -----
        The Yeo-Johnson transform is given by::

            y = ((x + 1)**lmbda - 1) / lmbda,                for x >= 0, lmbda != 0
                log(x + 1),                                  for x >= 0, lmbda = 0
                -((-x + 1)**(2 - lmbda) - 1) / (2 - lmbda),  for x < 0, lmbda != 2
                -log(-x + 1),                                for x < 0, lmbda = 2

        Unlike `boxcox`, `yeojohnson` does not require the input data to be
        positive.

        .. versionadded:: 1.2.0


        References
        ----------
        I. Yeo and R.A. Johnson, "A New Family of Power Transformations to
        Improve Normality or Symmetry", Biometrika 87.4 (2000):


        Examples
        --------
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        We generate some random variates from a non-normal distribution and make a
        probability plot for it, to show it is non-normal in the tails:

        >>> fig = plt.figure()
        >>> ax1 = fig.add_subplot(211)
        >>> x = stats.loggamma.rvs(5, size=500) + 5
        >>> prob = stats.probplot(x, dist=stats.norm, plot=ax1)
        >>> ax1.set_xlabel('')
        >>> ax1.set_title('Probplot against normal distribution')

        We now use `yeojohnson` to transform the data so it's closest to normal:

        >>> ax2 = fig.add_subplot(212)
        >>> xt, lmbda = stats.yeojohnson(x)
        >>> prob = stats.probplot(xt, dist=stats.norm, plot=ax2)
        >>> ax2.set_title('Probplot after Yeo-Johnson transformation')

        >>> plt.show()

    yeojohnson_llf(lmb, data)
        The yeojohnson log-likelihood function.

        Parameters
        ----------
        lmb : scalar
            Parameter for Yeo-Johnson transformation. See `yeojohnson` for
            details.
        data : array_like
            Data to calculate Yeo-Johnson log-likelihood for. If `data` is
            multi-dimensional, the log-likelihood is calculated along the first
            axis.

        Returns
        -------
        llf : float
            Yeo-Johnson log-likelihood of `data` given `lmb`.

        See Also
        --------
        yeojohnson, probplot, yeojohnson_normplot, yeojohnson_normmax

        Notes
        -----
        The Yeo-Johnson log-likelihood function is defined here as

        .. math::

            llf = -N/2 \log(\hat{\sigma}^2) + (\lambda - 1)
                  \sum_i \text{ sign }(x_i)\log(|x_i| + 1)

        where :math:`\hat{\sigma}^2` is estimated variance of the Yeo-Johnson
        transformed input data ``x``.

        .. versionadded:: 1.2.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt
        >>> from mpl_toolkits.axes_grid1.inset_locator import inset_axes

        Generate some random variates and calculate Yeo-Johnson log-likelihood
        values for them for a range of ``lmbda`` values:

        >>> x = stats.loggamma.rvs(5, loc=10, size=1000)
        >>> lmbdas = np.linspace(-2, 10)
        >>> llf = np.zeros(lmbdas.shape, dtype=float)
        >>> for ii, lmbda in enumerate(lmbdas):
        ...     llf[ii] = stats.yeojohnson_llf(lmbda, x)

        Also find the optimal lmbda value with `yeojohnson`:

        >>> x_most_normal, lmbda_optimal = stats.yeojohnson(x)

        Plot the log-likelihood as function of lmbda.  Add the optimal lmbda as a
        horizontal line to check that that's really the optimum:

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(lmbdas, llf, 'b.-')
        >>> ax.axhline(stats.yeojohnson_llf(lmbda_optimal, x), color='r')
        >>> ax.set_xlabel('lmbda parameter')
        >>> ax.set_ylabel('Yeo-Johnson log-likelihood')

        Now add some probability plots to show that where the log-likelihood is
        maximized the data transformed with `yeojohnson` looks closest to normal:

        >>> locs = [3, 10, 4]  # 'lower left', 'center', 'lower right'
        >>> for lmbda, loc in zip([-1, lmbda_optimal, 9], locs):
        ...     xt = stats.yeojohnson(x, lmbda=lmbda)
        ...     (osm, osr), (slope, intercept, r_sq) = stats.probplot(xt)
        ...     ax_inset = inset_axes(ax, width="20%", height="20%", loc=loc)
        ...     ax_inset.plot(osm, osr, 'c.', osm, slope*osm + intercept, 'k-')
        ...     ax_inset.set_xticklabels([])
        ...     ax_inset.set_yticklabels([])
        ...     ax_inset.set_title(r'$\lambda=%1.2f$' % lmbda)

        >>> plt.show()

    yeojohnson_normmax(x, brack=None)
        Compute optimal Yeo-Johnson transform parameter.

        Compute optimal Yeo-Johnson transform parameter for input data, using
        maximum likelihood estimation.

        Parameters
        ----------
        x : array_like
            Input array.
        brack : 2-tuple, optional
            The starting interval for a downhill bracket search with
            `optimize.brent`. Note that this is in most cases not critical; the
            final result is allowed to be outside this bracket. If None,
            `optimize.fminbound` is used with bounds that avoid overflow.

        Returns
        -------
        maxlog : float
            The optimal transform parameter found.

        See Also
        --------
        yeojohnson, yeojohnson_llf, yeojohnson_normplot

        Notes
        -----
        .. versionadded:: 1.2.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        Generate some data and determine optimal ``lmbda``

        >>> rng = np.random.default_rng()
        >>> x = stats.loggamma.rvs(5, size=30, random_state=rng) + 5
        >>> lmax = stats.yeojohnson_normmax(x)

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> prob = stats.yeojohnson_normplot(x, -10, 10, plot=ax)
        >>> ax.axvline(lmax, color='r')

        >>> plt.show()

    yeojohnson_normplot(x, la, lb, plot=None, N=80)
        Compute parameters for a Yeo-Johnson normality plot, optionally show it.

        A Yeo-Johnson normality plot shows graphically what the best
        transformation parameter is to use in `yeojohnson` to obtain a
        distribution that is close to normal.

        Parameters
        ----------
        x : array_like
            Input array.
        la, lb : scalar
            The lower and upper bounds for the ``lmbda`` values to pass to
            `yeojohnson` for Yeo-Johnson transformations. These are also the
            limits of the horizontal axis of the plot if that is generated.
        plot : object, optional
            If given, plots the quantiles and least squares fit.
            `plot` is an object that has to have methods "plot" and "text".
            The `matplotlib.pyplot` module or a Matplotlib Axes object can be used,
            or a custom object with the same methods.
            Default is None, which means that no plot is created.
        N : int, optional
            Number of points on the horizontal axis (equally distributed from
            `la` to `lb`).

        Returns
        -------
        lmbdas : ndarray
            The ``lmbda`` values for which a Yeo-Johnson transform was done.
        ppcc : ndarray
            Probability Plot Correlelation Coefficient, as obtained from `probplot`
            when fitting the Box-Cox transformed input `x` against a normal
            distribution.

        See Also
        --------
        probplot, yeojohnson, yeojohnson_normmax, yeojohnson_llf, ppcc_max

        Notes
        -----
        Even if `plot` is given, the figure is not shown or saved by
        `boxcox_normplot`; ``plt.show()`` or ``plt.savefig('figname.png')``
        should be used after calling `probplot`.

        .. versionadded:: 1.2.0

        Examples
        --------
        >>> from scipy import stats
        >>> import matplotlib.pyplot as plt

        Generate some non-normally distributed data, and create a Yeo-Johnson plot:

        >>> x = stats.loggamma.rvs(5, size=500) + 5
        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> prob = stats.yeojohnson_normplot(x, -20, 20, plot=ax)

        Determine and plot the optimal ``lmbda`` to transform ``x`` and plot it in
        the same plot:

        >>> _, maxlog = stats.yeojohnson(x)
        >>> ax.axvline(maxlog, color='r')

        >>> plt.show()

    zmap(scores, compare, axis=0, ddof=0, nan_policy='propagate')
        Calculate the relative z-scores.

        Return an array of z-scores, i.e., scores that are standardized to
        zero mean and unit variance, where mean and variance are calculated
        from the comparison array.

        Parameters
        ----------
        scores : array_like
            The input for which z-scores are calculated.
        compare : array_like
            The input from which the mean and standard deviation of the
            normalization are taken; assumed to have the same dimension as
            `scores`.
        axis : int or None, optional
            Axis over which mean and variance of `compare` are calculated.
            Default is 0. If None, compute over the whole array `scores`.
        ddof : int, optional
            Degrees of freedom correction in the calculation of the
            standard deviation. Default is 0.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle the occurrence of nans in `compare`.
            'propagate' returns nan, 'raise' raises an exception, 'omit'
            performs the calculations ignoring nan values. Default is
            'propagate'. Note that when the value is 'omit', nans in `scores`
            also propagate to the output, but they do not affect the z-scores
            computed for the non-nan values.

        Returns
        -------
        zscore : array_like
            Z-scores, in the same shape as `scores`.

        Notes
        -----
        This function preserves ndarray subclasses, and works also with
        matrices and masked arrays (it uses `asanyarray` instead of
        `asarray` for parameters).

        Examples
        --------
        >>> from scipy.stats import zmap
        >>> a = [0.5, 2.0, 2.5, 3]
        >>> b = [0, 1, 2, 3, 4]
        >>> zmap(a, b)
        array([-1.06066017,  0.        ,  0.35355339,  0.70710678])

    zscore(a, axis=0, ddof=0, nan_policy='propagate')
        Compute the z score.

        Compute the z score of each value in the sample, relative to the
        sample mean and standard deviation.

        Parameters
        ----------
        a : array_like
            An array like object containing the sample data.
        axis : int or None, optional
            Axis along which to operate. Default is 0. If None, compute over
            the whole array `a`.
        ddof : int, optional
            Degrees of freedom correction in the calculation of the
            standard deviation. Default is 0.
        nan_policy : {'propagate', 'raise', 'omit'}, optional
            Defines how to handle when input contains nan. 'propagate' returns nan,
            'raise' throws an error, 'omit' performs the calculations ignoring nan
            values. Default is 'propagate'.  Note that when the value is 'omit',
            nans in the input also propagate to the output, but they do not affect
            the z-scores computed for the non-nan values.

        Returns
        -------
        zscore : array_like
            The z-scores, standardized by mean and standard deviation of
            input array `a`.

        See Also
        --------
        numpy.mean : Arithmetic average
        numpy.std : Arithmetic standard deviation
        scipy.stats.gzscore : Geometric standard score

        Notes
        -----
        This function preserves ndarray subclasses, and works also with
        matrices and masked arrays (it uses `asanyarray` instead of
        `asarray` for parameters).

        References
        ----------
        .. [1] "Standard score", *Wikipedia*,
               https://en.wikipedia.org/wiki/Standard_score.
        .. [2] Huck, S. W., Cross, T. L., Clark, S. B, "Overcoming misconceptions
               about Z-scores", Teaching Statistics, vol. 8, pp. 38-40, 1986

        Examples
        --------
        >>> import numpy as np
        >>> a = np.array([ 0.7972,  0.0767,  0.4383,  0.7866,  0.8091,
        ...                0.1954,  0.6307,  0.6599,  0.1065,  0.0508])
        >>> from scipy import stats
        >>> stats.zscore(a)
        array([ 1.1273, -1.247 , -0.0552,  1.0923,  1.1664, -0.8559,  0.5786,
                0.6748, -1.1488, -1.3324])

        Computing along a specified axis, using n-1 degrees of freedom
        (``ddof=1``) to calculate the standard deviation:

        >>> b = np.array([[ 0.3148,  0.0478,  0.6243,  0.4608],
        ...               [ 0.7149,  0.0775,  0.6072,  0.9656],
        ...               [ 0.6341,  0.1403,  0.9759,  0.4064],
        ...               [ 0.5918,  0.6948,  0.904 ,  0.3721],
        ...               [ 0.0921,  0.2481,  0.1188,  0.1366]])
        >>> stats.zscore(b, axis=1, ddof=1)
        array([[-0.19264823, -1.28415119,  1.07259584,  0.40420358],
               [ 0.33048416, -1.37380874,  0.04251374,  1.00081084],
               [ 0.26796377, -1.12598418,  1.23283094, -0.37481053],
               [-0.22095197,  0.24468594,  1.19042819, -1.21416216],
               [-0.82780366,  1.4457416 , -0.43867764, -0.1792603 ]])

        An example with `nan_policy='omit'`:

        >>> x = np.array([[25.11, 30.10, np.nan, 32.02, 43.15],
        ...               [14.95, 16.06, 121.25, 94.35, 29.81]])
        >>> stats.zscore(x, axis=1, nan_policy='omit')
        array([[-1.13490897, -0.37830299,         nan, -0.08718406,  1.60039602],
               [-0.91611681, -0.89090508,  1.4983032 ,  0.88731639, -0.5785977 ]])

DATA
    __all__ = ['BootstrapMethod', 'CensoredData', 'ConstantInputWarning', ...
    alpha = <scipy.stats._continuous_distns.alpha_gen object>
        An alpha continuous random variable.

        As an instance of the `rv_continuous` class, `alpha` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `alpha` ([1]_, [2]_) is:

        .. math::

            f(x, a) = \frac{1}{x^2 \Phi(a) \sqrt{2\pi}} *
                      \exp(-\frac{1}{2} (a-1/x)^2)

        where :math:`\Phi` is the normal CDF, :math:`x > 0`, and :math:`a > 0`.

        `alpha` takes ``a`` as a shape parameter.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``alpha.pdf(x, a, loc, scale)`` is identically
        equivalent to ``alpha.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Johnson, Kotz, and Balakrishnan, "Continuous Univariate
               Distributions, Volume 1", Second Edition, John Wiley and Sons,
               p. 173 (1994).
        .. [2] Anthony A. Salvia, "Reliability applications of the Alpha
               Distribution", IEEE Transactions on Reliability, Vol. R-34,
               No. 3, pp. 251-252 (1985).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import alpha
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 3.57
        >>> mean, var, skew, kurt = alpha.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(alpha.ppf(0.01, a),
        ...                 alpha.ppf(0.99, a), 100)
        >>> ax.plot(x, alpha.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='alpha pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = alpha(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = alpha.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], alpha.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = alpha.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    anglit = <scipy.stats._continuous_distns.anglit_gen object>
        An anglit continuous random variable.

        As an instance of the `rv_continuous` class, `anglit` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `anglit` is:

        .. math::

            f(x) = \sin(2x + \pi/2) = \cos(2x)

        for :math:`-\pi/4 \le x \le \pi/4`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``anglit.pdf(x, loc, scale)`` is identically
        equivalent to ``anglit.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import anglit
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = anglit.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(anglit.ppf(0.01),
        ...                 anglit.ppf(0.99), 100)
        >>> ax.plot(x, anglit.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='anglit pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = anglit()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = anglit.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], anglit.cdf(vals))
        True

        Generate random numbers:

        >>> r = anglit.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    arcsine = <scipy.stats._continuous_distns.arcsine_gen object>
        An arcsine continuous random variable.

        As an instance of the `rv_continuous` class, `arcsine` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `arcsine` is:

        .. math::

            f(x) = \frac{1}{\pi \sqrt{x (1-x)}}

        for :math:`0 < x < 1`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``arcsine.pdf(x, loc, scale)`` is identically
        equivalent to ``arcsine.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import arcsine
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = arcsine.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(arcsine.ppf(0.01),
        ...                 arcsine.ppf(0.99), 100)
        >>> ax.plot(x, arcsine.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='arcsine pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = arcsine()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = arcsine.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], arcsine.cdf(vals))
        True

        Generate random numbers:

        >>> r = arcsine.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    argus = <scipy.stats._continuous_distns.argus_gen object>
        Argus distribution

        As an instance of the `rv_continuous` class, `argus` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(chi, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, chi, loc=0, scale=1)
            Probability density function.
        logpdf(x, chi, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, chi, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, chi, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, chi, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, chi, loc=0, scale=1)
            Log of the survival function.
        ppf(q, chi, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, chi, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, chi, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(chi, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(chi, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(chi,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(chi, loc=0, scale=1)
            Median of the distribution.
        mean(chi, loc=0, scale=1)
            Mean of the distribution.
        var(chi, loc=0, scale=1)
            Variance of the distribution.
        std(chi, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, chi, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `argus` is:

        .. math::

            f(x, \chi) = \frac{\chi^3}{\sqrt{2\pi} \Psi(\chi)} x \sqrt{1-x^2}
                         \exp(-\chi^2 (1 - x^2)/2)

        for :math:`0 < x < 1` and :math:`\chi > 0`, where

        .. math::

            \Psi(\chi) = \Phi(\chi) - \chi \phi(\chi) - 1/2

        with :math:`\Phi` and :math:`\phi` being the CDF and PDF of a standard
        normal distribution, respectively.

        `argus` takes :math:`\chi` as shape a parameter. Details about sampling
        from the ARGUS distribution can be found in [2]_.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``argus.pdf(x, chi, loc, scale)`` is identically
        equivalent to ``argus.pdf(y, chi) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] "ARGUS distribution",
               https://en.wikipedia.org/wiki/ARGUS_distribution
        .. [2] Christoph Baumgarten "Random variate generation by fast numerical
               inversion in the varying parameter case." Research in Statistics,
               vol. 1, 2023, doi:10.1080/27684520.2023.2279060.

        .. versionadded:: 0.19.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import argus
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> chi = 1
        >>> mean, var, skew, kurt = argus.stats(chi, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(argus.ppf(0.01, chi),
        ...                 argus.ppf(0.99, chi), 100)
        >>> ax.plot(x, argus.pdf(x, chi),
        ...        'r-', lw=5, alpha=0.6, label='argus pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = argus(chi)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = argus.ppf([0.001, 0.5, 0.999], chi)
        >>> np.allclose([0.001, 0.5, 0.999], argus.cdf(vals, chi))
        True

        Generate random numbers:

        >>> r = argus.rvs(chi, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    bernoulli = <scipy.stats._discrete_distns.bernoulli_gen object>
        A Bernoulli discrete random variable.

        As an instance of the `rv_discrete` class, `bernoulli` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(p, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, p, loc=0)
            Probability mass function.
        logpmf(k, p, loc=0)
            Log of the probability mass function.
        cdf(k, p, loc=0)
            Cumulative distribution function.
        logcdf(k, p, loc=0)
            Log of the cumulative distribution function.
        sf(k, p, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, p, loc=0)
            Log of the survival function.
        ppf(q, p, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, p, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(p, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(p, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(p,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(p, loc=0)
            Median of the distribution.
        mean(p, loc=0)
            Mean of the distribution.
        var(p, loc=0)
            Variance of the distribution.
        std(p, loc=0)
            Standard deviation of the distribution.
        interval(confidence, p, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `bernoulli` is:

        .. math::

           f(k) = \begin{cases}1-p  &\text{if } k = 0\\
                               p    &\text{if } k = 1\end{cases}

        for :math:`k` in :math:`\{0, 1\}`, :math:`0 \leq p \leq 1`

        `bernoulli` takes :math:`p` as shape parameter,
        where :math:`p` is the probability of a single success
        and :math:`1-p` is the probability of a single failure.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``bernoulli.pmf(k, p, loc)`` is identically
        equivalent to ``bernoulli.pmf(k - loc, p)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import bernoulli
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> p = 0.3
        >>> mean, var, skew, kurt = bernoulli.stats(p, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(bernoulli.ppf(0.01, p),
        ...               bernoulli.ppf(0.99, p))
        >>> ax.plot(x, bernoulli.pmf(x, p), 'bo', ms=8, label='bernoulli pmf')
        >>> ax.vlines(x, 0, bernoulli.pmf(x, p), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = bernoulli(p)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = bernoulli.cdf(x, p)
        >>> np.allclose(x, bernoulli.ppf(prob, p))
        True

        Generate random numbers:

        >>> r = bernoulli.rvs(p, size=1000)

    beta = <scipy.stats._continuous_distns.beta_gen object>
        A beta continuous random variable.

        As an instance of the `rv_continuous` class, `beta` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `beta` is:

        .. math::

            f(x, a, b) = \frac{\Gamma(a+b) x^{a-1} (1-x)^{b-1}}
                              {\Gamma(a) \Gamma(b)}

        for :math:`0 <= x <= 1`, :math:`a > 0`, :math:`b > 0`, where
        :math:`\Gamma` is the gamma function (`scipy.special.gamma`).

        `beta` takes :math:`a` and :math:`b` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``beta.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``beta.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import beta
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 2.31, 0.627
        >>> mean, var, skew, kurt = beta.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(beta.ppf(0.01, a, b),
        ...                 beta.ppf(0.99, a, b), 100)
        >>> ax.plot(x, beta.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='beta pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = beta(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = beta.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], beta.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = beta.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    betabinom = <scipy.stats._discrete_distns.betabinom_gen object>
        A beta-binomial discrete random variable.

        As an instance of the `rv_discrete` class, `betabinom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, a, b, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, n, a, b, loc=0)
            Probability mass function.
        logpmf(k, n, a, b, loc=0)
            Log of the probability mass function.
        cdf(k, n, a, b, loc=0)
            Cumulative distribution function.
        logcdf(k, n, a, b, loc=0)
            Log of the cumulative distribution function.
        sf(k, n, a, b, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, n, a, b, loc=0)
            Log of the survival function.
        ppf(q, n, a, b, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, a, b, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(n, a, b, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, a, b, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(n, a, b), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, a, b, loc=0)
            Median of the distribution.
        mean(n, a, b, loc=0)
            Mean of the distribution.
        var(n, a, b, loc=0)
            Variance of the distribution.
        std(n, a, b, loc=0)
            Standard deviation of the distribution.
        interval(confidence, n, a, b, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The beta-binomial distribution is a binomial distribution with a
        probability of success `p` that follows a beta distribution.

        The probability mass function for `betabinom` is:

        .. math::

           f(k) = \binom{n}{k} \frac{B(k + a, n - k + b)}{B(a, b)}

        for :math:`k \in \{0, 1, \dots, n\}`, :math:`n \geq 0`, :math:`a > 0`,
        :math:`b > 0`, where :math:`B(a, b)` is the beta function.

        `betabinom` takes :math:`n`, :math:`a`, and :math:`b` as shape parameters.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Beta-binomial_distribution

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``betabinom.pmf(k, n, a, b, loc)`` is identically
        equivalent to ``betabinom.pmf(k - loc, n, a, b)``.

        .. versionadded:: 1.4.0

        See Also
        --------
        beta, binom

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import betabinom
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> n, a, b = 5, 2.3, 0.63
        >>> mean, var, skew, kurt = betabinom.stats(n, a, b, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(betabinom.ppf(0.01, n, a, b),
        ...               betabinom.ppf(0.99, n, a, b))
        >>> ax.plot(x, betabinom.pmf(x, n, a, b), 'bo', ms=8, label='betabinom pmf')
        >>> ax.vlines(x, 0, betabinom.pmf(x, n, a, b), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = betabinom(n, a, b)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = betabinom.cdf(x, n, a, b)
        >>> np.allclose(x, betabinom.ppf(prob, n, a, b))
        True

        Generate random numbers:

        >>> r = betabinom.rvs(n, a, b, size=1000)

    betanbinom = <scipy.stats._discrete_distns.betanbinom_gen object>
        A beta-negative-binomial discrete random variable.

        As an instance of the `rv_discrete` class, `betanbinom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, a, b, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, n, a, b, loc=0)
            Probability mass function.
        logpmf(k, n, a, b, loc=0)
            Log of the probability mass function.
        cdf(k, n, a, b, loc=0)
            Cumulative distribution function.
        logcdf(k, n, a, b, loc=0)
            Log of the cumulative distribution function.
        sf(k, n, a, b, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, n, a, b, loc=0)
            Log of the survival function.
        ppf(q, n, a, b, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, a, b, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(n, a, b, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, a, b, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(n, a, b), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, a, b, loc=0)
            Median of the distribution.
        mean(n, a, b, loc=0)
            Mean of the distribution.
        var(n, a, b, loc=0)
            Variance of the distribution.
        std(n, a, b, loc=0)
            Standard deviation of the distribution.
        interval(confidence, n, a, b, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The beta-negative-binomial distribution is a negative binomial
        distribution with a probability of success `p` that follows a
        beta distribution.

        The probability mass function for `betanbinom` is:

        .. math::

           f(k) = \binom{n + k - 1}{k} \frac{B(a + n, b + k)}{B(a, b)}

        for :math:`k \ge 0`, :math:`n \geq 0`, :math:`a > 0`,
        :math:`b > 0`, where :math:`B(a, b)` is the beta function.

        `betanbinom` takes :math:`n`, :math:`a`, and :math:`b` as shape parameters.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Beta_negative_binomial_distribution

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``betanbinom.pmf(k, n, a, b, loc)`` is identically
        equivalent to ``betanbinom.pmf(k - loc, n, a, b)``.

        .. versionadded:: 1.12.0

        See Also
        --------
        betabinom : Beta binomial distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import betanbinom
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> n, a, b = 5, 9.3, 1
        >>> mean, var, skew, kurt = betanbinom.stats(n, a, b, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(betanbinom.ppf(0.01, n, a, b),
        ...               betanbinom.ppf(0.99, n, a, b))
        >>> ax.plot(x, betanbinom.pmf(x, n, a, b), 'bo', ms=8, label='betanbinom pmf')
        >>> ax.vlines(x, 0, betanbinom.pmf(x, n, a, b), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = betanbinom(n, a, b)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = betanbinom.cdf(x, n, a, b)
        >>> np.allclose(x, betanbinom.ppf(prob, n, a, b))
        True

        Generate random numbers:

        >>> r = betanbinom.rvs(n, a, b, size=1000)

    betaprime = <scipy.stats._continuous_distns.betaprime_gen object>
        A beta prime continuous random variable.

        As an instance of the `rv_continuous` class, `betaprime` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `betaprime` is:

        .. math::

            f(x, a, b) = \frac{x^{a-1} (1+x)^{-a-b}}{\beta(a, b)}

        for :math:`x >= 0`, :math:`a > 0`, :math:`b > 0`, where
        :math:`\beta(a, b)` is the beta function (see `scipy.special.beta`).

        `betaprime` takes ``a`` and ``b`` as shape parameters.

        The distribution is related to the `beta` distribution as follows:
        If :math:`X` follows a beta distribution with parameters :math:`a, b`,
        then :math:`Y = X/(1-X)` has a beta prime distribution with
        parameters :math:`a, b` ([1]_).

        The beta prime distribution is a reparametrized version of the
        F distribution.  The beta prime distribution with shape parameters
        ``a`` and ``b`` and ``scale = s`` is equivalent to the F distribution
        with parameters ``d1 = 2*a``, ``d2 = 2*b`` and ``scale = (a/b)*s``.
        For example,

        >>> from scipy.stats import betaprime, f
        >>> x = [1, 2, 5, 10]
        >>> a = 12
        >>> b = 5
        >>> betaprime.pdf(x, a, b, scale=2)
        array([0.00541179, 0.08331299, 0.14669185, 0.03150079])
        >>> f.pdf(x, 2*a, 2*b, scale=(a/b)*2)
        array([0.00541179, 0.08331299, 0.14669185, 0.03150079])

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``betaprime.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``betaprime.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Beta prime distribution, Wikipedia,
               https://en.wikipedia.org/wiki/Beta_prime_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import betaprime
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 5, 6
        >>> mean, var, skew, kurt = betaprime.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(betaprime.ppf(0.01, a, b),
        ...                 betaprime.ppf(0.99, a, b), 100)
        >>> ax.plot(x, betaprime.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='betaprime pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = betaprime(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = betaprime.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], betaprime.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = betaprime.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    binom = <scipy.stats._discrete_distns.binom_gen object>
        A binomial discrete random variable.

        As an instance of the `rv_discrete` class, `binom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, p, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, n, p, loc=0)
            Probability mass function.
        logpmf(k, n, p, loc=0)
            Log of the probability mass function.
        cdf(k, n, p, loc=0)
            Cumulative distribution function.
        logcdf(k, n, p, loc=0)
            Log of the cumulative distribution function.
        sf(k, n, p, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, n, p, loc=0)
            Log of the survival function.
        ppf(q, n, p, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, p, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(n, p, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, p, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(n, p), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, p, loc=0)
            Median of the distribution.
        mean(n, p, loc=0)
            Mean of the distribution.
        var(n, p, loc=0)
            Variance of the distribution.
        std(n, p, loc=0)
            Standard deviation of the distribution.
        interval(confidence, n, p, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `binom` is:

        .. math::

           f(k) = \binom{n}{k} p^k (1-p)^{n-k}

        for :math:`k \in \{0, 1, \dots, n\}`, :math:`0 \leq p \leq 1`

        `binom` takes :math:`n` and :math:`p` as shape parameters,
        where :math:`p` is the probability of a single success
        and :math:`1-p` is the probability of a single failure.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``binom.pmf(k, n, p, loc)`` is identically
        equivalent to ``binom.pmf(k - loc, n, p)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import binom
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> n, p = 5, 0.4
        >>> mean, var, skew, kurt = binom.stats(n, p, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(binom.ppf(0.01, n, p),
        ...               binom.ppf(0.99, n, p))
        >>> ax.plot(x, binom.pmf(x, n, p), 'bo', ms=8, label='binom pmf')
        >>> ax.vlines(x, 0, binom.pmf(x, n, p), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = binom(n, p)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = binom.cdf(x, n, p)
        >>> np.allclose(x, binom.ppf(prob, n, p))
        True

        Generate random numbers:

        >>> r = binom.rvs(n, p, size=1000)

        See Also
        --------
        hypergeom, nbinom, nhypergeom

    boltzmann = <scipy.stats._discrete_distns.boltzmann_gen object>
        A Boltzmann (Truncated Discrete Exponential) random variable.

        As an instance of the `rv_discrete` class, `boltzmann` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(lambda_, N, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, lambda_, N, loc=0)
            Probability mass function.
        logpmf(k, lambda_, N, loc=0)
            Log of the probability mass function.
        cdf(k, lambda_, N, loc=0)
            Cumulative distribution function.
        logcdf(k, lambda_, N, loc=0)
            Log of the cumulative distribution function.
        sf(k, lambda_, N, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, lambda_, N, loc=0)
            Log of the survival function.
        ppf(q, lambda_, N, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, lambda_, N, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(lambda_, N, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(lambda_, N, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(lambda_, N), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(lambda_, N, loc=0)
            Median of the distribution.
        mean(lambda_, N, loc=0)
            Mean of the distribution.
        var(lambda_, N, loc=0)
            Variance of the distribution.
        std(lambda_, N, loc=0)
            Standard deviation of the distribution.
        interval(confidence, lambda_, N, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `boltzmann` is:

        .. math::

            f(k) = (1-\exp(-\lambda)) \exp(-\lambda k) / (1-\exp(-\lambda N))

        for :math:`k = 0,..., N-1`.

        `boltzmann` takes :math:`\lambda > 0` and :math:`N > 0` as shape parameters.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``boltzmann.pmf(k, lambda_, N, loc)`` is identically
        equivalent to ``boltzmann.pmf(k - loc, lambda_, N)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import boltzmann
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> lambda_, N = 1.4, 19
        >>> mean, var, skew, kurt = boltzmann.stats(lambda_, N, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(boltzmann.ppf(0.01, lambda_, N),
        ...               boltzmann.ppf(0.99, lambda_, N))
        >>> ax.plot(x, boltzmann.pmf(x, lambda_, N), 'bo', ms=8, label='boltzmann pmf')
        >>> ax.vlines(x, 0, boltzmann.pmf(x, lambda_, N), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = boltzmann(lambda_, N)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = boltzmann.cdf(x, lambda_, N)
        >>> np.allclose(x, boltzmann.ppf(prob, lambda_, N))
        True

        Generate random numbers:

        >>> r = boltzmann.rvs(lambda_, N, size=1000)

    bradford = <scipy.stats._continuous_distns.bradford_gen object>
        A Bradford continuous random variable.

        As an instance of the `rv_continuous` class, `bradford` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `bradford` is:

        .. math::

            f(x, c) = \frac{c}{\log(1+c) (1+cx)}

        for :math:`0 <= x <= 1` and :math:`c > 0`.

        `bradford` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``bradford.pdf(x, c, loc, scale)`` is identically
        equivalent to ``bradford.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import bradford
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.299
        >>> mean, var, skew, kurt = bradford.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(bradford.ppf(0.01, c),
        ...                 bradford.ppf(0.99, c), 100)
        >>> ax.plot(x, bradford.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='bradford pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = bradford(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = bradford.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], bradford.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = bradford.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    burr = <scipy.stats._continuous_distns.burr_gen object>
        A Burr (Type III) continuous random variable.

        As an instance of the `rv_continuous` class, `burr` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, d, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, d, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, d, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, d, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, d, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, d, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, d, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, d, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, d, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, d, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, d, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, d, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c, d), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, d, loc=0, scale=1)
            Median of the distribution.
        mean(c, d, loc=0, scale=1)
            Mean of the distribution.
        var(c, d, loc=0, scale=1)
            Variance of the distribution.
        std(c, d, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, d, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        fisk : a special case of either `burr` or `burr12` with ``d=1``
        burr12 : Burr Type XII distribution
        mielke : Mielke Beta-Kappa / Dagum distribution

        Notes
        -----
        The probability density function for `burr` is:

        .. math::

            f(x; c, d) = c d \frac{x^{-c - 1}}
                                  {{(1 + x^{-c})}^{d + 1}}

        for :math:`x >= 0` and :math:`c, d > 0`.

        `burr` takes ``c`` and ``d`` as shape parameters for :math:`c` and
        :math:`d`.

        This is the PDF corresponding to the third CDF given in Burr's list;
        specifically, it is equation (11) in Burr's paper [1]_. The distribution
        is also commonly referred to as the Dagum distribution [2]_. If the
        parameter :math:`c < 1` then the mean of the distribution does not
        exist and if :math:`c < 2` the variance does not exist [2]_.
        The PDF is finite at the left endpoint :math:`x = 0` if :math:`c * d >= 1`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``burr.pdf(x, c, d, loc, scale)`` is identically
        equivalent to ``burr.pdf(y, c, d) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Burr, I. W. "Cumulative frequency functions", Annals of
           Mathematical Statistics, 13(2), pp 215-232 (1942).
        .. [2] https://en.wikipedia.org/wiki/Dagum_distribution
        .. [3] Kleiber, Christian. "A guide to the Dagum distributions."
           Modeling Income Distributions and Lorenz Curves  pp 97-117 (2008).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import burr
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c, d = 10.5, 4.3
        >>> mean, var, skew, kurt = burr.stats(c, d, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(burr.ppf(0.01, c, d),
        ...                 burr.ppf(0.99, c, d), 100)
        >>> ax.plot(x, burr.pdf(x, c, d),
        ...        'r-', lw=5, alpha=0.6, label='burr pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = burr(c, d)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = burr.ppf([0.001, 0.5, 0.999], c, d)
        >>> np.allclose([0.001, 0.5, 0.999], burr.cdf(vals, c, d))
        True

        Generate random numbers:

        >>> r = burr.rvs(c, d, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    burr12 = <scipy.stats._continuous_distns.burr12_gen object>
        A Burr (Type XII) continuous random variable.

        As an instance of the `rv_continuous` class, `burr12` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, d, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, d, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, d, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, d, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, d, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, d, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, d, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, d, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, d, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, d, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, d, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, d, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c, d), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, d, loc=0, scale=1)
            Median of the distribution.
        mean(c, d, loc=0, scale=1)
            Mean of the distribution.
        var(c, d, loc=0, scale=1)
            Variance of the distribution.
        std(c, d, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, d, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        fisk : a special case of either `burr` or `burr12` with ``d=1``
        burr : Burr Type III distribution

        Notes
        -----
        The probability density function for `burr12` is:

        .. math::

            f(x; c, d) = c d \frac{x^{c-1}}
                                  {(1 + x^c)^{d + 1}}

        for :math:`x >= 0` and :math:`c, d > 0`.

        `burr12` takes ``c`` and ``d`` as shape parameters for :math:`c`
        and :math:`d`.

        This is the PDF corresponding to the twelfth CDF given in Burr's list;
        specifically, it is equation (20) in Burr's paper [1]_.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``burr12.pdf(x, c, d, loc, scale)`` is identically
        equivalent to ``burr12.pdf(y, c, d) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The Burr type 12 distribution is also sometimes referred to as
        the Singh-Maddala distribution from NIST [2]_.

        References
        ----------
        .. [1] Burr, I. W. "Cumulative frequency functions", Annals of
           Mathematical Statistics, 13(2), pp 215-232 (1942).

        .. [2] https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/b12pdf.htm

        .. [3] "Burr distribution",
           https://en.wikipedia.org/wiki/Burr_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import burr12
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c, d = 10, 4
        >>> mean, var, skew, kurt = burr12.stats(c, d, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(burr12.ppf(0.01, c, d),
        ...                 burr12.ppf(0.99, c, d), 100)
        >>> ax.plot(x, burr12.pdf(x, c, d),
        ...        'r-', lw=5, alpha=0.6, label='burr12 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = burr12(c, d)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = burr12.ppf([0.001, 0.5, 0.999], c, d)
        >>> np.allclose([0.001, 0.5, 0.999], burr12.cdf(vals, c, d))
        True

        Generate random numbers:

        >>> r = burr12.rvs(c, d, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    cauchy = <scipy.stats._continuous_distns.cauchy_gen object>
        A Cauchy continuous random variable.

        As an instance of the `rv_continuous` class, `cauchy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `cauchy` is

        .. math::

            f(x) = \frac{1}{\pi (1 + x^2)}

        for a real number :math:`x`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``cauchy.pdf(x, loc, scale)`` is identically
        equivalent to ``cauchy.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import cauchy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = cauchy.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(cauchy.ppf(0.01),
        ...                 cauchy.ppf(0.99), 100)
        >>> ax.plot(x, cauchy.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='cauchy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = cauchy()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = cauchy.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], cauchy.cdf(vals))
        True

        Generate random numbers:

        >>> r = cauchy.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    chi = <scipy.stats._continuous_distns.chi_gen object>
        A chi continuous random variable.

        As an instance of the `rv_continuous` class, `chi` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(df, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, df, loc=0, scale=1)
            Probability density function.
        logpdf(x, df, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, df, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, df, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, df, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, df, loc=0, scale=1)
            Log of the survival function.
        ppf(q, df, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, df, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, df, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(df, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(df, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(df,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(df, loc=0, scale=1)
            Median of the distribution.
        mean(df, loc=0, scale=1)
            Mean of the distribution.
        var(df, loc=0, scale=1)
            Variance of the distribution.
        std(df, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, df, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `chi` is:

        .. math::

            f(x, k) = \frac{1}{2^{k/2-1} \Gamma \left( k/2 \right)}
                       x^{k-1} \exp \left( -x^2/2 \right)

        for :math:`x >= 0` and :math:`k > 0` (degrees of freedom, denoted ``df``
        in the implementation). :math:`\Gamma` is the gamma function
        (`scipy.special.gamma`).

        Special cases of `chi` are:

            - ``chi(1, loc, scale)`` is equivalent to `halfnorm`
            - ``chi(2, 0, scale)`` is equivalent to `rayleigh`
            - ``chi(3, 0, scale)`` is equivalent to `maxwell`

        `chi` takes ``df`` as a shape parameter.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``chi.pdf(x, df, loc, scale)`` is identically
        equivalent to ``chi.pdf(y, df) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import chi
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> df = 78
        >>> mean, var, skew, kurt = chi.stats(df, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(chi.ppf(0.01, df),
        ...                 chi.ppf(0.99, df), 100)
        >>> ax.plot(x, chi.pdf(x, df),
        ...        'r-', lw=5, alpha=0.6, label='chi pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = chi(df)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = chi.ppf([0.001, 0.5, 0.999], df)
        >>> np.allclose([0.001, 0.5, 0.999], chi.cdf(vals, df))
        True

        Generate random numbers:

        >>> r = chi.rvs(df, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    chi2 = <scipy.stats._continuous_distns.chi2_gen object>
        A chi-squared continuous random variable.

        For the noncentral chi-square distribution, see `ncx2`.

        As an instance of the `rv_continuous` class, `chi2` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(df, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, df, loc=0, scale=1)
            Probability density function.
        logpdf(x, df, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, df, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, df, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, df, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, df, loc=0, scale=1)
            Log of the survival function.
        ppf(q, df, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, df, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, df, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(df, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(df, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(df,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(df, loc=0, scale=1)
            Median of the distribution.
        mean(df, loc=0, scale=1)
            Mean of the distribution.
        var(df, loc=0, scale=1)
            Variance of the distribution.
        std(df, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, df, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        ncx2

        Notes
        -----
        The probability density function for `chi2` is:

        .. math::

            f(x, k) = \frac{1}{2^{k/2} \Gamma \left( k/2 \right)}
                       x^{k/2-1} \exp \left( -x/2 \right)

        for :math:`x > 0`  and :math:`k > 0` (degrees of freedom, denoted ``df``
        in the implementation).

        `chi2` takes ``df`` as a shape parameter.

        The chi-squared distribution is a special case of the gamma
        distribution, with gamma parameters ``a = df/2``, ``loc = 0`` and
        ``scale = 2``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``chi2.pdf(x, df, loc, scale)`` is identically
        equivalent to ``chi2.pdf(y, df) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import chi2
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> df = 55
        >>> mean, var, skew, kurt = chi2.stats(df, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(chi2.ppf(0.01, df),
        ...                 chi2.ppf(0.99, df), 100)
        >>> ax.plot(x, chi2.pdf(x, df),
        ...        'r-', lw=5, alpha=0.6, label='chi2 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = chi2(df)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = chi2.ppf([0.001, 0.5, 0.999], df)
        >>> np.allclose([0.001, 0.5, 0.999], chi2.cdf(vals, df))
        True

        Generate random numbers:

        >>> r = chi2.rvs(df, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    cosine = <scipy.stats._continuous_distns.cosine_gen object>
        A cosine continuous random variable.

        As an instance of the `rv_continuous` class, `cosine` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The cosine distribution is an approximation to the normal distribution.
        The probability density function for `cosine` is:

        .. math::

            f(x) = \frac{1}{2\pi} (1+\cos(x))

        for :math:`-\pi \le x \le \pi`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``cosine.pdf(x, loc, scale)`` is identically
        equivalent to ``cosine.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import cosine
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = cosine.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(cosine.ppf(0.01),
        ...                 cosine.ppf(0.99), 100)
        >>> ax.plot(x, cosine.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='cosine pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = cosine()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = cosine.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], cosine.cdf(vals))
        True

        Generate random numbers:

        >>> r = cosine.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    crystalball = <scipy.stats._continuous_distns.crystalball_gen object>
        Crystalball distribution

        As an instance of the `rv_continuous` class, `crystalball` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(beta, m, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, beta, m, loc=0, scale=1)
            Probability density function.
        logpdf(x, beta, m, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, beta, m, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, beta, m, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, beta, m, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, beta, m, loc=0, scale=1)
            Log of the survival function.
        ppf(q, beta, m, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, beta, m, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, beta, m, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(beta, m, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(beta, m, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(beta, m), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(beta, m, loc=0, scale=1)
            Median of the distribution.
        mean(beta, m, loc=0, scale=1)
            Mean of the distribution.
        var(beta, m, loc=0, scale=1)
            Variance of the distribution.
        std(beta, m, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, beta, m, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `crystalball` is:

        .. math::

            f(x, \beta, m) =  \begin{cases}
                                N \exp(-x^2 / 2),  &\text{for } x > -\beta\\
                                N A (B - x)^{-m}  &\text{for } x \le -\beta
                              \end{cases}

        where :math:`A = (m / |\beta|)^m  \exp(-\beta^2 / 2)`,
        :math:`B = m/|\beta| - |\beta|` and :math:`N` is a normalisation constant.

        `crystalball` takes :math:`\beta > 0` and :math:`m > 1` as shape
        parameters.  :math:`\beta` defines the point where the pdf changes
        from a power-law to a Gaussian distribution.  :math:`m` is the power
        of the power-law tail.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``crystalball.pdf(x, beta, m, loc, scale)`` is identically
        equivalent to ``crystalball.pdf(y, beta, m) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        .. versionadded:: 0.19.0

        References
        ----------
        .. [1] "Crystal Ball Function",
               https://en.wikipedia.org/wiki/Crystal_Ball_function

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import crystalball
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> beta, m = 2, 3
        >>> mean, var, skew, kurt = crystalball.stats(beta, m, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(crystalball.ppf(0.01, beta, m),
        ...                 crystalball.ppf(0.99, beta, m), 100)
        >>> ax.plot(x, crystalball.pdf(x, beta, m),
        ...        'r-', lw=5, alpha=0.6, label='crystalball pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = crystalball(beta, m)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = crystalball.ppf([0.001, 0.5, 0.999], beta, m)
        >>> np.allclose([0.001, 0.5, 0.999], crystalball.cdf(vals, beta, m))
        True

        Generate random numbers:

        >>> r = crystalball.rvs(beta, m, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    dgamma = <scipy.stats._continuous_distns.dgamma_gen object>
        A double gamma continuous random variable.

        The double gamma distribution is also known as the reflected gamma
        distribution [1]_.

        As an instance of the `rv_continuous` class, `dgamma` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `dgamma` is:

        .. math::

            f(x, a) = \frac{1}{2\Gamma(a)} |x|^{a-1} \exp(-|x|)

        for a real number :math:`x` and :math:`a > 0`. :math:`\Gamma` is the
        gamma function (`scipy.special.gamma`).

        `dgamma` takes ``a`` as a shape parameter for :math:`a`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``dgamma.pdf(x, a, loc, scale)`` is identically
        equivalent to ``dgamma.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Johnson, Kotz, and Balakrishnan, "Continuous Univariate
               Distributions, Volume 1", Second Edition, John Wiley and Sons
               (1994).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import dgamma
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 1.1
        >>> mean, var, skew, kurt = dgamma.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(dgamma.ppf(0.01, a),
        ...                 dgamma.ppf(0.99, a), 100)
        >>> ax.plot(x, dgamma.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='dgamma pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = dgamma(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = dgamma.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], dgamma.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = dgamma.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    dirichlet = <scipy.stats._multivariate.dirichlet_gen object>
        A Dirichlet random variable.

        The ``alpha`` keyword specifies the concentration parameters of the
        distribution.

        .. versionadded:: 0.15.0

        Methods
        -------
        pdf(x, alpha)
            Probability density function.
        logpdf(x, alpha)
            Log of the probability density function.
        rvs(alpha, size=1, random_state=None)
            Draw random samples from a Dirichlet distribution.
        mean(alpha)
            The mean of the Dirichlet distribution
        var(alpha)
            The variance of the Dirichlet distribution
        cov(alpha)
            The covariance of the Dirichlet distribution
        entropy(alpha)
            Compute the differential entropy of the Dirichlet distribution.

        Parameters
        ----------
        alpha : array_like
            The concentration parameters. The number of entries determines the
            dimensionality of the distribution.
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        Each :math:`\alpha` entry must be positive. The distribution has only
        support on the simplex defined by

        .. math::
            \sum_{i=1}^{K} x_i = 1

        where :math:`0 < x_i < 1`.

        If the quantiles don't lie within the simplex, a ValueError is raised.

        The probability density function for `dirichlet` is

        .. math::

            f(x) = \frac{1}{\mathrm{B}(\boldsymbol\alpha)} \prod_{i=1}^K x_i^{\alpha_i - 1}

        where

        .. math::

            \mathrm{B}(\boldsymbol\alpha) = \frac{\prod_{i=1}^K \Gamma(\alpha_i)}
                                         {\Gamma\bigl(\sum_{i=1}^K \alpha_i\bigr)}

        and :math:`\boldsymbol\alpha=(\alpha_1,\ldots,\alpha_K)`, the
        concentration parameters and :math:`K` is the dimension of the space
        where :math:`x` takes values.

        Note that the `dirichlet` interface is somewhat inconsistent.
        The array returned by the rvs function is transposed
        with respect to the format expected by the pdf and logpdf.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import dirichlet

        Generate a dirichlet random variable

        >>> quantiles = np.array([0.2, 0.2, 0.6])  # specify quantiles
        >>> alpha = np.array([0.4, 5, 15])  # specify concentration parameters
        >>> dirichlet.pdf(quantiles, alpha)
        0.2843831684937255

        The same PDF but following a log scale

        >>> dirichlet.logpdf(quantiles, alpha)
        -1.2574327653159187

        Once we specify the dirichlet distribution
        we can then calculate quantities of interest

        >>> dirichlet.mean(alpha)  # get the mean of the distribution
        array([0.01960784, 0.24509804, 0.73529412])
        >>> dirichlet.var(alpha) # get variance
        array([0.00089829, 0.00864603, 0.00909517])
        >>> dirichlet.entropy(alpha)  # calculate the differential entropy
        -4.3280162474082715

        We can also return random samples from the distribution

        >>> dirichlet.rvs(alpha, size=1, random_state=1)
        array([[0.00766178, 0.24670518, 0.74563305]])
        >>> dirichlet.rvs(alpha, size=2, random_state=2)
        array([[0.01639427, 0.1292273 , 0.85437844],
               [0.00156917, 0.19033695, 0.80809388]])

        Alternatively, the object may be called (as a function) to fix
        concentration parameters, returning a "frozen" Dirichlet
        random variable:

        >>> rv = dirichlet(alpha)
        >>> # Frozen object with the same methods but holding the given
        >>> # concentration parameters fixed.

    dirichlet_multinomial = <scipy.stats._multivariate.dirichlet_multinomi...
        A Dirichlet multinomial random variable.

        The Dirichlet multinomial distribution is a compound probability
        distribution: it is the multinomial distribution with number of trials
        `n` and class probabilities ``p`` randomly sampled from a Dirichlet
        distribution with concentration parameters ``alpha``.

        Methods
        -------
        logpmf(x, alpha, n):
            Log of the probability mass function.
        pmf(x, alpha, n):
            Probability mass function.
        mean(alpha, n):
            Mean of the Dirichlet multinomial distribution.
        var(alpha, n):
            Variance of the Dirichlet multinomial distribution.
        cov(alpha, n):
            The covariance of the Dirichlet multinomial distribution.

        Parameters
        ----------
        alpha : array_like
            The concentration parameters. The number of entries along the last axis
            determines the dimensionality of the distribution. Each entry must be
            strictly positive.
        n : int or array_like
            The number of trials. Each element must be a strictly positive integer.
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        See Also
        --------
        scipy.stats.dirichlet : The dirichlet distribution.
        scipy.stats.multinomial : The multinomial distribution.

        References
        ----------
        .. [1] Dirichlet-multinomial distribution, Wikipedia,
               https://www.wikipedia.org/wiki/Dirichlet-multinomial_distribution

        Examples
        --------
        >>> from scipy.stats import dirichlet_multinomial

        Get the PMF

        >>> n = 6  # number of trials
        >>> alpha = [3, 4, 5]  # concentration parameters
        >>> x = [1, 2, 3]  # counts
        >>> dirichlet_multinomial.pmf(x, alpha, n)
        0.08484162895927604

        If the sum of category counts does not equal the number of trials,
        the probability mass is zero.

        >>> dirichlet_multinomial.pmf(x, alpha, n=7)
        0.0

        Get the log of the PMF

        >>> dirichlet_multinomial.logpmf(x, alpha, n)
        -2.4669689491013327

        Get the mean

        >>> dirichlet_multinomial.mean(alpha, n)
        array([1.5, 2. , 2.5])

        Get the variance

        >>> dirichlet_multinomial.var(alpha, n)
        array([1.55769231, 1.84615385, 2.01923077])

        Get the covariance

        >>> dirichlet_multinomial.cov(alpha, n)
        array([[ 1.55769231, -0.69230769, -0.86538462],
               [-0.69230769,  1.84615385, -1.15384615],
               [-0.86538462, -1.15384615,  2.01923077]])

        Alternatively, the object may be called (as a function) to fix the
        `alpha` and `n` parameters, returning a "frozen" Dirichlet multinomial
        random variable.

        >>> dm = dirichlet_multinomial(alpha, n)
        >>> dm.pmf(x)
        0.08484162895927579

        All methods are fully vectorized. Each element of `x` and `alpha` is
        a vector (along the last axis), each element of `n` is an
        integer (scalar), and the result is computed element-wise.

        >>> x = [[1, 2, 3], [4, 5, 6]]
        >>> alpha = [[1, 2, 3], [4, 5, 6]]
        >>> n = [6, 15]
        >>> dirichlet_multinomial.pmf(x, alpha, n)
        array([0.06493506, 0.02626937])

        >>> dirichlet_multinomial.cov(alpha, n).shape  # both covariance matrices
        (2, 3, 3)

        Broadcasting according to standard NumPy conventions is supported. Here,
        we have four sets of concentration parameters (each a two element vector)
        for each of three numbers of trials (each a scalar).

        >>> alpha = [[3, 4], [4, 5], [5, 6], [6, 7]]
        >>> n = [[6], [7], [8]]
        >>> dirichlet_multinomial.mean(alpha, n).shape
        (3, 4, 2)

    dlaplace = <scipy.stats._discrete_distns.dlaplace_gen object>
        A  Laplacian discrete random variable.

        As an instance of the `rv_discrete` class, `dlaplace` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, a, loc=0)
            Probability mass function.
        logpmf(k, a, loc=0)
            Log of the probability mass function.
        cdf(k, a, loc=0)
            Cumulative distribution function.
        logcdf(k, a, loc=0)
            Log of the cumulative distribution function.
        sf(k, a, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, a, loc=0)
            Log of the survival function.
        ppf(q, a, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(a, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(a,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0)
            Median of the distribution.
        mean(a, loc=0)
            Mean of the distribution.
        var(a, loc=0)
            Variance of the distribution.
        std(a, loc=0)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `dlaplace` is:

        .. math::

            f(k) = \tanh(a/2) \exp(-a |k|)

        for integers :math:`k` and :math:`a > 0`.

        `dlaplace` takes :math:`a` as shape parameter.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``dlaplace.pmf(k, a, loc)`` is identically
        equivalent to ``dlaplace.pmf(k - loc, a)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import dlaplace
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 0.8
        >>> mean, var, skew, kurt = dlaplace.stats(a, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(dlaplace.ppf(0.01, a),
        ...               dlaplace.ppf(0.99, a))
        >>> ax.plot(x, dlaplace.pmf(x, a), 'bo', ms=8, label='dlaplace pmf')
        >>> ax.vlines(x, 0, dlaplace.pmf(x, a), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = dlaplace(a)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = dlaplace.cdf(x, a)
        >>> np.allclose(x, dlaplace.ppf(prob, a))
        True

        Generate random numbers:

        >>> r = dlaplace.rvs(a, size=1000)

    dweibull = <scipy.stats._continuous_distns.dweibull_gen object>
        A double Weibull continuous random variable.

        As an instance of the `rv_continuous` class, `dweibull` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `dweibull` is given by

        .. math::

            f(x, c) = c / 2 |x|^{c-1} \exp(-|x|^c)

        for a real number :math:`x` and :math:`c > 0`.

        `dweibull` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``dweibull.pdf(x, c, loc, scale)`` is identically
        equivalent to ``dweibull.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import dweibull
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 2.07
        >>> mean, var, skew, kurt = dweibull.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(dweibull.ppf(0.01, c),
        ...                 dweibull.ppf(0.99, c), 100)
        >>> ax.plot(x, dweibull.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='dweibull pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = dweibull(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = dweibull.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], dweibull.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = dweibull.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    erlang = <scipy.stats._continuous_distns.erlang_gen object>
        An Erlang continuous random variable.

        As an instance of the `rv_continuous` class, `erlang` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gamma

        Notes
        -----
        The Erlang distribution is a special case of the Gamma distribution, with
        the shape parameter `a` an integer.  Note that this restriction is not
        enforced by `erlang`. It will, however, generate a warning the first time
        a non-integer value is used for the shape parameter.

        Refer to `gamma` for examples.

    expon = <scipy.stats._continuous_distns.expon_gen object>
        An exponential continuous random variable.

        As an instance of the `rv_continuous` class, `expon` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `expon` is:

        .. math::

            f(x) = \exp(-x)

        for :math:`x \ge 0`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``expon.pdf(x, loc, scale)`` is identically
        equivalent to ``expon.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        A common parameterization for `expon` is in terms of the rate parameter
        ``lambda``, such that ``pdf = lambda * exp(-lambda * x)``. This
        parameterization corresponds to using ``scale = 1 / lambda``.

        The exponential distribution is a special case of the gamma
        distributions, with gamma shape parameter ``a = 1``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import expon
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = expon.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(expon.ppf(0.01),
        ...                 expon.ppf(0.99), 100)
        >>> ax.plot(x, expon.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='expon pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = expon()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = expon.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], expon.cdf(vals))
        True

        Generate random numbers:

        >>> r = expon.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    exponnorm = <scipy.stats._continuous_distns.exponnorm_gen object>
        An exponentially modified Normal continuous random variable.

        Also known as the exponentially modified Gaussian distribution [1]_.

        As an instance of the `rv_continuous` class, `exponnorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(K, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, K, loc=0, scale=1)
            Probability density function.
        logpdf(x, K, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, K, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, K, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, K, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, K, loc=0, scale=1)
            Log of the survival function.
        ppf(q, K, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, K, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, K, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(K, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(K, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(K,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(K, loc=0, scale=1)
            Median of the distribution.
        mean(K, loc=0, scale=1)
            Mean of the distribution.
        var(K, loc=0, scale=1)
            Variance of the distribution.
        std(K, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, K, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `exponnorm` is:

        .. math::

            f(x, K) = \frac{1}{2K} \exp\left(\frac{1}{2 K^2} - x / K \right)
                      \text{erfc}\left(-\frac{x - 1/K}{\sqrt{2}}\right)

        where :math:`x` is a real number and :math:`K > 0`.

        It can be thought of as the sum of a standard normal random variable
        and an independent exponentially distributed random variable with rate
        ``1/K``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``exponnorm.pdf(x, K, loc, scale)`` is identically
        equivalent to ``exponnorm.pdf(y, K) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        An alternative parameterization of this distribution (for example, in
        the Wikipedia article [1]_) involves three parameters, :math:`\mu`,
        :math:`\lambda` and :math:`\sigma`.

        In the present parameterization this corresponds to having ``loc`` and
        ``scale`` equal to :math:`\mu` and :math:`\sigma`, respectively, and
        shape parameter :math:`K = 1/(\sigma\lambda)`.

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] Exponentially modified Gaussian distribution, Wikipedia,
               https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import exponnorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> K = 1.5
        >>> mean, var, skew, kurt = exponnorm.stats(K, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(exponnorm.ppf(0.01, K),
        ...                 exponnorm.ppf(0.99, K), 100)
        >>> ax.plot(x, exponnorm.pdf(x, K),
        ...        'r-', lw=5, alpha=0.6, label='exponnorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = exponnorm(K)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = exponnorm.ppf([0.001, 0.5, 0.999], K)
        >>> np.allclose([0.001, 0.5, 0.999], exponnorm.cdf(vals, K))
        True

        Generate random numbers:

        >>> r = exponnorm.rvs(K, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    exponpow = <scipy.stats._continuous_distns.exponpow_gen object>
        An exponential power continuous random variable.

        As an instance of the `rv_continuous` class, `exponpow` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(b,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(b, loc=0, scale=1)
            Median of the distribution.
        mean(b, loc=0, scale=1)
            Mean of the distribution.
        var(b, loc=0, scale=1)
            Variance of the distribution.
        std(b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `exponpow` is:

        .. math::

            f(x, b) = b x^{b-1} \exp(1 + x^b - \exp(x^b))

        for :math:`x \ge 0`, :math:`b > 0`.  Note that this is a different
        distribution from the exponential power distribution that is also known
        under the names "generalized normal" or "generalized Gaussian".

        `exponpow` takes ``b`` as a shape parameter for :math:`b`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``exponpow.pdf(x, b, loc, scale)`` is identically
        equivalent to ``exponpow.pdf(y, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        http://www.math.wm.edu/~leemis/chart/UDR/PDFs/Exponentialpower.pdf

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import exponpow
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> b = 2.7
        >>> mean, var, skew, kurt = exponpow.stats(b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(exponpow.ppf(0.01, b),
        ...                 exponpow.ppf(0.99, b), 100)
        >>> ax.plot(x, exponpow.pdf(x, b),
        ...        'r-', lw=5, alpha=0.6, label='exponpow pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = exponpow(b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = exponpow.ppf([0.001, 0.5, 0.999], b)
        >>> np.allclose([0.001, 0.5, 0.999], exponpow.cdf(vals, b))
        True

        Generate random numbers:

        >>> r = exponpow.rvs(b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    exponweib = <scipy.stats._continuous_distns.exponweib_gen object>
        An exponentiated Weibull continuous random variable.

        As an instance of the `rv_continuous` class, `exponweib` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, c), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, c, loc=0, scale=1)
            Median of the distribution.
        mean(a, c, loc=0, scale=1)
            Mean of the distribution.
        var(a, c, loc=0, scale=1)
            Variance of the distribution.
        std(a, c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        weibull_min, numpy.random.Generator.weibull

        Notes
        -----
        The probability density function for `exponweib` is:

        .. math::

            f(x, a, c) = a c [1-\exp(-x^c)]^{a-1} \exp(-x^c) x^{c-1}

        and its cumulative distribution function is:

        .. math::

            F(x, a, c) = [1-\exp(-x^c)]^a

        for :math:`x > 0`, :math:`a > 0`, :math:`c > 0`.

        `exponweib` takes :math:`a` and :math:`c` as shape parameters:

        * :math:`a` is the exponentiation parameter,
          with the special case :math:`a=1` corresponding to the
          (non-exponentiated) Weibull distribution `weibull_min`.
        * :math:`c` is the shape parameter of the non-exponentiated Weibull law.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``exponweib.pdf(x, a, c, loc, scale)`` is identically
        equivalent to ``exponweib.pdf(y, a, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        https://en.wikipedia.org/wiki/Exponentiated_Weibull_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import exponweib
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, c = 2.89, 1.95
        >>> mean, var, skew, kurt = exponweib.stats(a, c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(exponweib.ppf(0.01, a, c),
        ...                 exponweib.ppf(0.99, a, c), 100)
        >>> ax.plot(x, exponweib.pdf(x, a, c),
        ...        'r-', lw=5, alpha=0.6, label='exponweib pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = exponweib(a, c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = exponweib.ppf([0.001, 0.5, 0.999], a, c)
        >>> np.allclose([0.001, 0.5, 0.999], exponweib.cdf(vals, a, c))
        True

        Generate random numbers:

        >>> r = exponweib.rvs(a, c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    f = <scipy.stats._continuous_distns.f_gen object>
        An F continuous random variable.

        For the noncentral F distribution, see `ncf`.

        As an instance of the `rv_continuous` class, `f` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(dfn, dfd, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, dfn, dfd, loc=0, scale=1)
            Probability density function.
        logpdf(x, dfn, dfd, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, dfn, dfd, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, dfn, dfd, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, dfn, dfd, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, dfn, dfd, loc=0, scale=1)
            Log of the survival function.
        ppf(q, dfn, dfd, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, dfn, dfd, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, dfn, dfd, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(dfn, dfd, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(dfn, dfd, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(dfn, dfd), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(dfn, dfd, loc=0, scale=1)
            Median of the distribution.
        mean(dfn, dfd, loc=0, scale=1)
            Mean of the distribution.
        var(dfn, dfd, loc=0, scale=1)
            Variance of the distribution.
        std(dfn, dfd, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, dfn, dfd, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        ncf

        Notes
        -----
        The F distribution with :math:`df_1 > 0` and :math:`df_2 > 0` degrees of freedom is
        the distribution of the ratio of two independent chi-squared distributions with
        :math:`df_1` and :math:`df_2` degrees of freedom, after rescaling by
        :math:`df_2 / df_1`.

        The probability density function for `f` is:

        .. math::

            f(x, df_1, df_2) = \frac{df_2^{df_2/2} df_1^{df_1/2} x^{df_1 / 2-1}}
                                    {(df_2+df_1 x)^{(df_1+df_2)/2}
                                     B(df_1/2, df_2/2)}

        for :math:`x > 0`.

        `f` accepts shape parameters ``dfn`` and ``dfd`` for :math:`df_1`, the degrees of
        freedom of the chi-squared distribution in the numerator, and :math:`df_2`, the
        degrees of freedom of the chi-squared distribution in the denominator, respectively.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``f.pdf(x, dfn, dfd, loc, scale)`` is identically
        equivalent to ``f.pdf(y, dfn, dfd) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import f
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> dfn, dfd = 29, 18
        >>> mean, var, skew, kurt = f.stats(dfn, dfd, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(f.ppf(0.01, dfn, dfd),
        ...                 f.ppf(0.99, dfn, dfd), 100)
        >>> ax.plot(x, f.pdf(x, dfn, dfd),
        ...        'r-', lw=5, alpha=0.6, label='f pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = f(dfn, dfd)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = f.ppf([0.001, 0.5, 0.999], dfn, dfd)
        >>> np.allclose([0.001, 0.5, 0.999], f.cdf(vals, dfn, dfd))
        True

        Generate random numbers:

        >>> r = f.rvs(dfn, dfd, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    fatiguelife = <scipy.stats._continuous_distns.fatiguelife_gen object>
        A fatigue-life (Birnbaum-Saunders) continuous random variable.

        As an instance of the `rv_continuous` class, `fatiguelife` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `fatiguelife` is:

        .. math::

            f(x, c) = \frac{x+1}{2c\sqrt{2\pi x^3}} \exp(-\frac{(x-1)^2}{2x c^2})

        for :math:`x >= 0` and :math:`c > 0`.

        `fatiguelife` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``fatiguelife.pdf(x, c, loc, scale)`` is identically
        equivalent to ``fatiguelife.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] "Birnbaum-Saunders distribution",
               https://en.wikipedia.org/wiki/Birnbaum-Saunders_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import fatiguelife
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 29
        >>> mean, var, skew, kurt = fatiguelife.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(fatiguelife.ppf(0.01, c),
        ...                 fatiguelife.ppf(0.99, c), 100)
        >>> ax.plot(x, fatiguelife.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='fatiguelife pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = fatiguelife(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = fatiguelife.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], fatiguelife.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = fatiguelife.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    fisk = <scipy.stats._continuous_distns.fisk_gen object>
        A Fisk continuous random variable.

        The Fisk distribution is also known as the log-logistic distribution.

        As an instance of the `rv_continuous` class, `fisk` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        burr

        Notes
        -----
        The probability density function for `fisk` is:

        .. math::

            f(x, c) = \frac{c x^{c-1}}
                           {(1 + x^c)^2}

        for :math:`x >= 0` and :math:`c > 0`.

        Please note that the above expression can be transformed into the following
        one, which is also commonly used:

        .. math::

            f(x, c) = \frac{c x^{-c-1}}
                           {(1 + x^{-c})^2}

        `fisk` takes ``c`` as a shape parameter for :math:`c`.

        `fisk` is a special case of `burr` or `burr12` with ``d=1``.

        Suppose ``X`` is a logistic random variable with location ``l``
        and scale ``s``. Then ``Y = exp(X)`` is a Fisk (log-logistic)
        random variable with ``scale = exp(l)`` and shape ``c = 1/s``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``fisk.pdf(x, c, loc, scale)`` is identically
        equivalent to ``fisk.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import fisk
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 3.09
        >>> mean, var, skew, kurt = fisk.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(fisk.ppf(0.01, c),
        ...                 fisk.ppf(0.99, c), 100)
        >>> ax.plot(x, fisk.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='fisk pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = fisk(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = fisk.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], fisk.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = fisk.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    foldcauchy = <scipy.stats._continuous_distns.foldcauchy_gen object>
        A folded Cauchy continuous random variable.

        As an instance of the `rv_continuous` class, `foldcauchy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `foldcauchy` is:

        .. math::

            f(x, c) = \frac{1}{\pi (1+(x-c)^2)} + \frac{1}{\pi (1+(x+c)^2)}

        for :math:`x \ge 0` and :math:`c \ge 0`.

        `foldcauchy` takes ``c`` as a shape parameter for :math:`c`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import foldcauchy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 4.72
        >>> mean, var, skew, kurt = foldcauchy.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(foldcauchy.ppf(0.01, c),
        ...                 foldcauchy.ppf(0.99, c), 100)
        >>> ax.plot(x, foldcauchy.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='foldcauchy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = foldcauchy(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = foldcauchy.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], foldcauchy.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = foldcauchy.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    foldnorm = <scipy.stats._continuous_distns.foldnorm_gen object>
        A folded normal continuous random variable.

        As an instance of the `rv_continuous` class, `foldnorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `foldnorm` is:

        .. math::

            f(x, c) = \sqrt{2/\pi} cosh(c x) \exp(-\frac{x^2+c^2}{2})

        for :math:`x \ge 0` and :math:`c \ge 0`.

        `foldnorm` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``foldnorm.pdf(x, c, loc, scale)`` is identically
        equivalent to ``foldnorm.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import foldnorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 1.95
        >>> mean, var, skew, kurt = foldnorm.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(foldnorm.ppf(0.01, c),
        ...                 foldnorm.ppf(0.99, c), 100)
        >>> ax.plot(x, foldnorm.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='foldnorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = foldnorm(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = foldnorm.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], foldnorm.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = foldnorm.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gamma = <scipy.stats._continuous_distns.gamma_gen object>
        A gamma continuous random variable.

        As an instance of the `rv_continuous` class, `gamma` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        erlang, expon

        Notes
        -----
        The probability density function for `gamma` is:

        .. math::

            f(x, a) = \frac{x^{a-1} e^{-x}}{\Gamma(a)}

        for :math:`x \ge 0`, :math:`a > 0`. Here :math:`\Gamma(a)` refers to the
        gamma function.

        `gamma` takes ``a`` as a shape parameter for :math:`a`.

        When :math:`a` is an integer, `gamma` reduces to the Erlang
        distribution, and when :math:`a=1` to the exponential distribution.

        Gamma distributions are sometimes parameterized with two variables,
        with a probability density function of:

        .. math::

            f(x, \alpha, \beta) =
            \frac{\beta^\alpha x^{\alpha - 1} e^{-\beta x }}{\Gamma(\alpha)}

        Note that this parameterization is equivalent to the above, with
        ``scale = 1 / beta``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gamma.pdf(x, a, loc, scale)`` is identically
        equivalent to ``gamma.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gamma
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 1.99
        >>> mean, var, skew, kurt = gamma.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gamma.ppf(0.01, a),
        ...                 gamma.ppf(0.99, a), 100)
        >>> ax.plot(x, gamma.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='gamma pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gamma(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gamma.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], gamma.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = gamma.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gausshyper = <scipy.stats._continuous_distns.gausshyper_gen object>
        A Gauss hypergeometric continuous random variable.

        As an instance of the `rv_continuous` class, `gausshyper` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, c, z, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, c, z, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, c, z, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, c, z, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, c, z, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, c, z, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, c, z, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, c, z, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, c, z, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, c, z, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, c, z, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, c, z, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b, c, z), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, c, z, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, c, z, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, c, z, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, c, z, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, c, z, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `gausshyper` is:

        .. math::

            f(x, a, b, c, z) = C x^{a-1} (1-x)^{b-1} (1+zx)^{-c}

        for :math:`0 \le x \le 1`, :math:`a,b > 0`, :math:`c` a real number,
        :math:`z > -1`, and :math:`C = \frac{1}{B(a, b) F[2, 1](c, a; a+b; -z)}`.
        :math:`F[2, 1]` is the Gauss hypergeometric function
        `scipy.special.hyp2f1`.

        `gausshyper` takes :math:`a`, :math:`b`, :math:`c` and :math:`z` as shape
        parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gausshyper.pdf(x, a, b, c, z, loc, scale)`` is identically
        equivalent to ``gausshyper.pdf(y, a, b, c, z) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Armero, C., and M. J. Bayarri. "Prior Assessments for Prediction in
               Queues." *Journal of the Royal Statistical Society*. Series D (The
               Statistician) 43, no. 1 (1994): 139-53. doi:10.2307/2348939

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gausshyper
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b, c, z = 13.8, 3.12, 2.51, 5.18
        >>> mean, var, skew, kurt = gausshyper.stats(a, b, c, z, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gausshyper.ppf(0.01, a, b, c, z),
        ...                 gausshyper.ppf(0.99, a, b, c, z), 100)
        >>> ax.plot(x, gausshyper.pdf(x, a, b, c, z),
        ...        'r-', lw=5, alpha=0.6, label='gausshyper pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gausshyper(a, b, c, z)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gausshyper.ppf([0.001, 0.5, 0.999], a, b, c, z)
        >>> np.allclose([0.001, 0.5, 0.999], gausshyper.cdf(vals, a, b, c, z))
        True

        Generate random numbers:

        >>> r = gausshyper.rvs(a, b, c, z, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genexpon = <scipy.stats._continuous_distns.genexpon_gen object>
        A generalized exponential continuous random variable.

        As an instance of the `rv_continuous` class, `genexpon` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b, c), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, c, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, c, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, c, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `genexpon` is:

        .. math::

            f(x, a, b, c) = (a + b (1 - \exp(-c x)))
                            \exp(-a x - b x + \frac{b}{c}  (1-\exp(-c x)))

        for :math:`x \ge 0`, :math:`a, b, c > 0`.

        `genexpon` takes :math:`a`, :math:`b` and :math:`c` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genexpon.pdf(x, a, b, c, loc, scale)`` is identically
        equivalent to ``genexpon.pdf(y, a, b, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        H.K. Ryu, "An Extension of Marshall and Olkin's Bivariate Exponential
        Distribution", Journal of the American Statistical Association, 1993.

        N. Balakrishnan, Asit P. Basu (editors), *The Exponential Distribution:
        Theory, Methods and Applications*, Gordon and Breach, 1995.
        ISBN 10: 2884491929

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genexpon
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b, c = 9.13, 16.2, 3.28
        >>> mean, var, skew, kurt = genexpon.stats(a, b, c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genexpon.ppf(0.01, a, b, c),
        ...                 genexpon.ppf(0.99, a, b, c), 100)
        >>> ax.plot(x, genexpon.pdf(x, a, b, c),
        ...        'r-', lw=5, alpha=0.6, label='genexpon pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genexpon(a, b, c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genexpon.ppf([0.001, 0.5, 0.999], a, b, c)
        >>> np.allclose([0.001, 0.5, 0.999], genexpon.cdf(vals, a, b, c))
        True

        Generate random numbers:

        >>> r = genexpon.rvs(a, b, c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genextreme = <scipy.stats._continuous_distns.genextreme_gen object>
        A generalized extreme value continuous random variable.

        As an instance of the `rv_continuous` class, `genextreme` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gumbel_r

        Notes
        -----
        For :math:`c=0`, `genextreme` is equal to `gumbel_r` with
        probability density function

        .. math::

            f(x) = \exp(-\exp(-x)) \exp(-x),

        where :math:`-\infty < x < \infty`.

        For :math:`c \ne 0`, the probability density function for `genextreme` is:

        .. math::

            f(x, c) = \exp(-(1-c x)^{1/c}) (1-c x)^{1/c-1},

        where :math:`-\infty < x \le 1/c` if :math:`c > 0` and
        :math:`1/c \le x < \infty` if :math:`c < 0`.

        Note that several sources and software packages use the opposite
        convention for the sign of the shape parameter :math:`c`.

        `genextreme` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genextreme.pdf(x, c, loc, scale)`` is identically
        equivalent to ``genextreme.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genextreme
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = -0.1
        >>> mean, var, skew, kurt = genextreme.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genextreme.ppf(0.01, c),
        ...                 genextreme.ppf(0.99, c), 100)
        >>> ax.plot(x, genextreme.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='genextreme pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genextreme(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genextreme.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], genextreme.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = genextreme.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gengamma = <scipy.stats._continuous_distns.gengamma_gen object>
        A generalized gamma continuous random variable.

        As an instance of the `rv_continuous` class, `gengamma` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, c), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, c, loc=0, scale=1)
            Median of the distribution.
        mean(a, c, loc=0, scale=1)
            Mean of the distribution.
        var(a, c, loc=0, scale=1)
            Variance of the distribution.
        std(a, c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gamma, invgamma, weibull_min

        Notes
        -----
        The probability density function for `gengamma` is ([1]_):

        .. math::

            f(x, a, c) = \frac{|c| x^{c a-1} \exp(-x^c)}{\Gamma(a)}

        for :math:`x \ge 0`, :math:`a > 0`, and :math:`c \ne 0`.
        :math:`\Gamma` is the gamma function (`scipy.special.gamma`).

        `gengamma` takes :math:`a` and :math:`c` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gengamma.pdf(x, a, c, loc, scale)`` is identically
        equivalent to ``gengamma.pdf(y, a, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] E.W. Stacy, "A Generalization of the Gamma Distribution",
           Annals of Mathematical Statistics, Vol 33(3), pp. 1187--1192.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gengamma
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, c = 4.42, -3.12
        >>> mean, var, skew, kurt = gengamma.stats(a, c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gengamma.ppf(0.01, a, c),
        ...                 gengamma.ppf(0.99, a, c), 100)
        >>> ax.plot(x, gengamma.pdf(x, a, c),
        ...        'r-', lw=5, alpha=0.6, label='gengamma pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gengamma(a, c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gengamma.ppf([0.001, 0.5, 0.999], a, c)
        >>> np.allclose([0.001, 0.5, 0.999], gengamma.cdf(vals, a, c))
        True

        Generate random numbers:

        >>> r = gengamma.rvs(a, c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genhalflogistic = <scipy.stats._continuous_distns.genhalflogistic_gen ...
        A generalized half-logistic continuous random variable.

        As an instance of the `rv_continuous` class, `genhalflogistic` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `genhalflogistic` is:

        .. math::

            f(x, c) = \frac{2 (1 - c x)^{1/(c-1)}}{[1 + (1 - c x)^{1/c}]^2}

        for :math:`0 \le x \le 1/c`, and :math:`c > 0`.

        `genhalflogistic` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genhalflogistic.pdf(x, c, loc, scale)`` is identically
        equivalent to ``genhalflogistic.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genhalflogistic
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.773
        >>> mean, var, skew, kurt = genhalflogistic.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genhalflogistic.ppf(0.01, c),
        ...                 genhalflogistic.ppf(0.99, c), 100)
        >>> ax.plot(x, genhalflogistic.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='genhalflogistic pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genhalflogistic(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genhalflogistic.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], genhalflogistic.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = genhalflogistic.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genhyperbolic = <scipy.stats._continuous_distns.genhyperbolic_gen obje...
        A generalized hyperbolic continuous random variable.

        As an instance of the `rv_continuous` class, `genhyperbolic` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(p, a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, p, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, p, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, p, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, p, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, p, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, p, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, p, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, p, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, p, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(p, a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(p, a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(p, a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(p, a, b, loc=0, scale=1)
            Median of the distribution.
        mean(p, a, b, loc=0, scale=1)
            Mean of the distribution.
        var(p, a, b, loc=0, scale=1)
            Variance of the distribution.
        std(p, a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, p, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        t, norminvgauss, geninvgauss, laplace, cauchy

        Notes
        -----
        The probability density function for `genhyperbolic` is:

        .. math::

            f(x, p, a, b) =
                \frac{(a^2 - b^2)^{p/2}}
                {\sqrt{2\pi}a^{p-1/2}
                K_p\Big(\sqrt{a^2 - b^2}\Big)}
                e^{bx} \times \frac{K_{p - 1/2}
                (a \sqrt{1 + x^2})}
                {(\sqrt{1 + x^2})^{1/2 - p}}

        for :math:`x, p \in ( - \infty; \infty)`,
        :math:`|b| < a` if :math:`p \ge 0`,
        :math:`|b| \le a` if :math:`p < 0`.
        :math:`K_{p}(.)` denotes the modified Bessel function of the second
        kind and order :math:`p` (`scipy.special.kv`)

        `genhyperbolic` takes ``p`` as a tail parameter,
        ``a`` as a shape parameter,
        ``b`` as a skewness parameter.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genhyperbolic.pdf(x, p, a, b, loc, scale)`` is identically
        equivalent to ``genhyperbolic.pdf(y, p, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The original parameterization of the Generalized Hyperbolic Distribution
        is found in [1]_ as follows

        .. math::

            f(x, \lambda, \alpha, \beta, \delta, \mu) =
               \frac{(\gamma/\delta)^\lambda}{\sqrt{2\pi}K_\lambda(\delta \gamma)}
               e^{\beta (x - \mu)} \times \frac{K_{\lambda - 1/2}
               (\alpha \sqrt{\delta^2 + (x - \mu)^2})}
               {(\sqrt{\delta^2 + (x - \mu)^2} / \alpha)^{1/2 - \lambda}}

        for :math:`x \in ( - \infty; \infty)`,
        :math:`\gamma := \sqrt{\alpha^2 - \beta^2}`,
        :math:`\lambda, \mu \in ( - \infty; \infty)`,
        :math:`\delta \ge 0, |\beta| < \alpha` if :math:`\lambda \ge 0`,
        :math:`\delta > 0, |\beta| \le \alpha` if :math:`\lambda < 0`.

        The location-scale-based parameterization implemented in
        SciPy is based on [2]_, where :math:`a = \alpha\delta`,
        :math:`b = \beta\delta`, :math:`p = \lambda`,
        :math:`scale=\delta` and :math:`loc=\mu`

        Moments are implemented based on [3]_ and [4]_.

        For the distributions that are a special case such as Student's t,
        it is not recommended to rely on the implementation of genhyperbolic.
        To avoid potential numerical problems and for performance reasons,
        the methods of the specific distributions should be used.

        References
        ----------
        .. [1] O. Barndorff-Nielsen, "Hyperbolic Distributions and Distributions
           on Hyperbolae", Scandinavian Journal of Statistics, Vol. 5(3),
           pp. 151-157, 1978. https://www.jstor.org/stable/4615705

        .. [2] Eberlein E., Prause K. (2002) The Generalized Hyperbolic Model:
            Financial Derivatives and Risk Measures. In: Geman H., Madan D.,
            Pliska S.R., Vorst T. (eds) Mathematical Finance - Bachelier
            Congress 2000. Springer Finance. Springer, Berlin, Heidelberg.
            :doi:`10.1007/978-3-662-12429-1_12`

        .. [3] Scott, David J, Würtz, Diethelm, Dong, Christine and Tran,
           Thanh Tam, (2009), Moments of the generalized hyperbolic
           distribution, MPRA Paper, University Library of Munich, Germany,
           https://EconPapers.repec.org/RePEc:pra:mprapa:19081.

        .. [4] E. Eberlein and E. A. von Hammerstein. Generalized hyperbolic
           and inverse Gaussian distributions: Limiting cases and approximation
           of processes. FDM Preprint 80, April 2003. University of Freiburg.
           https://freidok.uni-freiburg.de/fedora/objects/freidok:7974/datastreams/FILE1/content

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genhyperbolic
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> p, a, b = 0.5, 1.5, -0.5
        >>> mean, var, skew, kurt = genhyperbolic.stats(p, a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genhyperbolic.ppf(0.01, p, a, b),
        ...                 genhyperbolic.ppf(0.99, p, a, b), 100)
        >>> ax.plot(x, genhyperbolic.pdf(x, p, a, b),
        ...        'r-', lw=5, alpha=0.6, label='genhyperbolic pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genhyperbolic(p, a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genhyperbolic.ppf([0.001, 0.5, 0.999], p, a, b)
        >>> np.allclose([0.001, 0.5, 0.999], genhyperbolic.cdf(vals, p, a, b))
        True

        Generate random numbers:

        >>> r = genhyperbolic.rvs(p, a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    geninvgauss = <scipy.stats._continuous_distns.geninvgauss_gen object>
        A Generalized Inverse Gaussian continuous random variable.

        As an instance of the `rv_continuous` class, `geninvgauss` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(p, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, p, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, p, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, p, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, p, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, p, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, p, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, p, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, p, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, p, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(p, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(p, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(p, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(p, b, loc=0, scale=1)
            Median of the distribution.
        mean(p, b, loc=0, scale=1)
            Mean of the distribution.
        var(p, b, loc=0, scale=1)
            Variance of the distribution.
        std(p, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, p, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `geninvgauss` is:

        .. math::

            f(x, p, b) = x^{p-1} \exp(-b (x + 1/x) / 2) / (2 K_p(b))

        where `x > 0`, `p` is a real number and `b > 0`\([1]_).
        :math:`K_p` is the modified Bessel function of second kind of order `p`
        (`scipy.special.kv`).

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``geninvgauss.pdf(x, p, b, loc, scale)`` is identically
        equivalent to ``geninvgauss.pdf(y, p, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The inverse Gaussian distribution `stats.invgauss(mu)` is a special case of
        `geninvgauss` with `p = -1/2`, `b = 1 / mu` and `scale = mu`.

        Generating random variates is challenging for this distribution. The
        implementation is based on [2]_.

        References
        ----------
        .. [1] O. Barndorff-Nielsen, P. Blaesild, C. Halgreen, "First hitting time
           models for the generalized inverse gaussian distribution",
           Stochastic Processes and their Applications 7, pp. 49--54, 1978.

        .. [2] W. Hoermann and J. Leydold, "Generating generalized inverse Gaussian
           random variates", Statistics and Computing, 24(4), p. 547--557, 2014.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import geninvgauss
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> p, b = 2.3, 1.5
        >>> mean, var, skew, kurt = geninvgauss.stats(p, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(geninvgauss.ppf(0.01, p, b),
        ...                 geninvgauss.ppf(0.99, p, b), 100)
        >>> ax.plot(x, geninvgauss.pdf(x, p, b),
        ...        'r-', lw=5, alpha=0.6, label='geninvgauss pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = geninvgauss(p, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = geninvgauss.ppf([0.001, 0.5, 0.999], p, b)
        >>> np.allclose([0.001, 0.5, 0.999], geninvgauss.cdf(vals, p, b))
        True

        Generate random numbers:

        >>> r = geninvgauss.rvs(p, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genlogistic = <scipy.stats._continuous_distns.genlogistic_gen object>
        A generalized logistic continuous random variable.

        As an instance of the `rv_continuous` class, `genlogistic` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `genlogistic` is:

        .. math::

            f(x, c) = c \frac{\exp(-x)}
                             {(1 + \exp(-x))^{c+1}}

        for real :math:`x` and :math:`c > 0`. In literature, different
        generalizations of the logistic distribution can be found. This is the type 1
        generalized logistic distribution according to [1]_. It is also referred to
        as the skew-logistic distribution [2]_.

        `genlogistic` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genlogistic.pdf(x, c, loc, scale)`` is identically
        equivalent to ``genlogistic.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Johnson et al. "Continuous Univariate Distributions", Volume 2,
               Wiley. 1995.
        .. [2] "Generalized Logistic Distribution", Wikipedia,
               https://en.wikipedia.org/wiki/Generalized_logistic_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genlogistic
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.412
        >>> mean, var, skew, kurt = genlogistic.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genlogistic.ppf(0.01, c),
        ...                 genlogistic.ppf(0.99, c), 100)
        >>> ax.plot(x, genlogistic.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='genlogistic pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genlogistic(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genlogistic.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], genlogistic.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = genlogistic.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gennorm = <scipy.stats._continuous_distns.gennorm_gen object>
        A generalized normal continuous random variable.

        As an instance of the `rv_continuous` class, `gennorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(beta, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, beta, loc=0, scale=1)
            Probability density function.
        logpdf(x, beta, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, beta, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, beta, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, beta, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, beta, loc=0, scale=1)
            Log of the survival function.
        ppf(q, beta, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, beta, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, beta, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(beta, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(beta, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(beta,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(beta, loc=0, scale=1)
            Median of the distribution.
        mean(beta, loc=0, scale=1)
            Mean of the distribution.
        var(beta, loc=0, scale=1)
            Variance of the distribution.
        std(beta, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, beta, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        laplace : Laplace distribution
        norm : normal distribution

        Notes
        -----
        The probability density function for `gennorm` is [1]_:

        .. math::

            f(x, \beta) = \frac{\beta}{2 \Gamma(1/\beta)} \exp(-|x|^\beta),

        where :math:`x` is a real number, :math:`\beta > 0` and
        :math:`\Gamma` is the gamma function (`scipy.special.gamma`).

        `gennorm` takes ``beta`` as a shape parameter for :math:`\beta`.
        For :math:`\beta = 1`, it is identical to a Laplace distribution.
        For :math:`\beta = 2`, it is identical to a normal distribution
        (with ``scale=1/sqrt(2)``).

        References
        ----------

        .. [1] "Generalized normal distribution, Version 1",
               https://en.wikipedia.org/wiki/Generalized_normal_distribution#Version_1

        .. [2] Nardon, Martina, and Paolo Pianca. "Simulation techniques for
               generalized Gaussian densities." Journal of Statistical
               Computation and Simulation 79.11 (2009): 1317-1329

        .. [3] Wicklin, Rick. "Simulate data from a generalized Gaussian
               distribution" in The DO Loop blog, September 21, 2016,
               https://blogs.sas.com/content/iml/2016/09/21/simulate-generalized-gaussian-sas.html

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gennorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> beta = 1.3
        >>> mean, var, skew, kurt = gennorm.stats(beta, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gennorm.ppf(0.01, beta),
        ...                 gennorm.ppf(0.99, beta), 100)
        >>> ax.plot(x, gennorm.pdf(x, beta),
        ...        'r-', lw=5, alpha=0.6, label='gennorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gennorm(beta)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gennorm.ppf([0.001, 0.5, 0.999], beta)
        >>> np.allclose([0.001, 0.5, 0.999], gennorm.cdf(vals, beta))
        True

        Generate random numbers:

        >>> r = gennorm.rvs(beta, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    genpareto = <scipy.stats._continuous_distns.genpareto_gen object>
        A generalized Pareto continuous random variable.

        As an instance of the `rv_continuous` class, `genpareto` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `genpareto` is:

        .. math::

            f(x, c) = (1 + c x)^{-1 - 1/c}

        defined for :math:`x \ge 0` if :math:`c \ge 0`, and for
        :math:`0 \le x \le -1/c` if :math:`c < 0`.

        `genpareto` takes ``c`` as a shape parameter for :math:`c`.

        For :math:`c=0`, `genpareto` reduces to the exponential
        distribution, `expon`:

        .. math::

            f(x, 0) = \exp(-x)

        For :math:`c=-1`, `genpareto` is uniform on ``[0, 1]``:

        .. math::

            f(x, -1) = 1

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``genpareto.pdf(x, c, loc, scale)`` is identically
        equivalent to ``genpareto.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import genpareto
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.1
        >>> mean, var, skew, kurt = genpareto.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(genpareto.ppf(0.01, c),
        ...                 genpareto.ppf(0.99, c), 100)
        >>> ax.plot(x, genpareto.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='genpareto pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = genpareto(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = genpareto.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], genpareto.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = genpareto.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    geom = <scipy.stats._discrete_distns.geom_gen object>
        A geometric discrete random variable.

        As an instance of the `rv_discrete` class, `geom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(p, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, p, loc=0)
            Probability mass function.
        logpmf(k, p, loc=0)
            Log of the probability mass function.
        cdf(k, p, loc=0)
            Cumulative distribution function.
        logcdf(k, p, loc=0)
            Log of the cumulative distribution function.
        sf(k, p, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, p, loc=0)
            Log of the survival function.
        ppf(q, p, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, p, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(p, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(p, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(p,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(p, loc=0)
            Median of the distribution.
        mean(p, loc=0)
            Mean of the distribution.
        var(p, loc=0)
            Variance of the distribution.
        std(p, loc=0)
            Standard deviation of the distribution.
        interval(confidence, p, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `geom` is:

        .. math::

            f(k) = (1-p)^{k-1} p

        for :math:`k \ge 1`, :math:`0 < p \leq 1`

        `geom` takes :math:`p` as shape parameter,
        where :math:`p` is the probability of a single success
        and :math:`1-p` is the probability of a single failure.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``geom.pmf(k, p, loc)`` is identically
        equivalent to ``geom.pmf(k - loc, p)``.

        See Also
        --------
        planck

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import geom
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> p = 0.5
        >>> mean, var, skew, kurt = geom.stats(p, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(geom.ppf(0.01, p),
        ...               geom.ppf(0.99, p))
        >>> ax.plot(x, geom.pmf(x, p), 'bo', ms=8, label='geom pmf')
        >>> ax.vlines(x, 0, geom.pmf(x, p), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = geom(p)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = geom.cdf(x, p)
        >>> np.allclose(x, geom.ppf(prob, p))
        True

        Generate random numbers:

        >>> r = geom.rvs(p, size=1000)

    gibrat = <scipy.stats._continuous_distns.gibrat_gen object>
        A Gibrat continuous random variable.

        As an instance of the `rv_continuous` class, `gibrat` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `gibrat` is:

        .. math::

            f(x) = \frac{1}{x \sqrt{2\pi}} \exp(-\frac{1}{2} (\log(x))^2)

        `gibrat` is a special case of `lognorm` with ``s=1``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gibrat.pdf(x, loc, scale)`` is identically
        equivalent to ``gibrat.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gibrat
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = gibrat.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gibrat.ppf(0.01),
        ...                 gibrat.ppf(0.99), 100)
        >>> ax.plot(x, gibrat.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='gibrat pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gibrat()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gibrat.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], gibrat.cdf(vals))
        True

        Generate random numbers:

        >>> r = gibrat.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gompertz = <scipy.stats._continuous_distns.gompertz_gen object>
        A Gompertz (or truncated Gumbel) continuous random variable.

        As an instance of the `rv_continuous` class, `gompertz` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `gompertz` is:

        .. math::

            f(x, c) = c \exp(x) \exp(-c (e^x-1))

        for :math:`x \ge 0`, :math:`c > 0`.

        `gompertz` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gompertz.pdf(x, c, loc, scale)`` is identically
        equivalent to ``gompertz.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gompertz
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.947
        >>> mean, var, skew, kurt = gompertz.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gompertz.ppf(0.01, c),
        ...                 gompertz.ppf(0.99, c), 100)
        >>> ax.plot(x, gompertz.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='gompertz pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gompertz(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gompertz.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], gompertz.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = gompertz.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gumbel_l = <scipy.stats._continuous_distns.gumbel_l_gen object>
        A left-skewed Gumbel continuous random variable.

        As an instance of the `rv_continuous` class, `gumbel_l` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gumbel_r, gompertz, genextreme

        Notes
        -----
        The probability density function for `gumbel_l` is:

        .. math::

            f(x) = \exp(x - e^x)

        The Gumbel distribution is sometimes referred to as a type I Fisher-Tippett
        distribution.  It is also related to the extreme value distribution,
        log-Weibull and Gompertz distributions.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gumbel_l.pdf(x, loc, scale)`` is identically
        equivalent to ``gumbel_l.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gumbel_l
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = gumbel_l.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gumbel_l.ppf(0.01),
        ...                 gumbel_l.ppf(0.99), 100)
        >>> ax.plot(x, gumbel_l.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='gumbel_l pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gumbel_l()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gumbel_l.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], gumbel_l.cdf(vals))
        True

        Generate random numbers:

        >>> r = gumbel_l.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    gumbel_r = <scipy.stats._continuous_distns.gumbel_r_gen object>
        A right-skewed Gumbel continuous random variable.

        As an instance of the `rv_continuous` class, `gumbel_r` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gumbel_l, gompertz, genextreme

        Notes
        -----
        The probability density function for `gumbel_r` is:

        .. math::

            f(x) = \exp(-(x + e^{-x}))

        The Gumbel distribution is sometimes referred to as a type I Fisher-Tippett
        distribution.  It is also related to the extreme value distribution,
        log-Weibull and Gompertz distributions.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``gumbel_r.pdf(x, loc, scale)`` is identically
        equivalent to ``gumbel_r.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import gumbel_r
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = gumbel_r.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(gumbel_r.ppf(0.01),
        ...                 gumbel_r.ppf(0.99), 100)
        >>> ax.plot(x, gumbel_r.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='gumbel_r pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = gumbel_r()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = gumbel_r.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], gumbel_r.cdf(vals))
        True

        Generate random numbers:

        >>> r = gumbel_r.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    halfcauchy = <scipy.stats._continuous_distns.halfcauchy_gen object>
        A Half-Cauchy continuous random variable.

        As an instance of the `rv_continuous` class, `halfcauchy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `halfcauchy` is:

        .. math::

            f(x) = \frac{2}{\pi (1 + x^2)}

        for :math:`x \ge 0`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``halfcauchy.pdf(x, loc, scale)`` is identically
        equivalent to ``halfcauchy.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import halfcauchy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = halfcauchy.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(halfcauchy.ppf(0.01),
        ...                 halfcauchy.ppf(0.99), 100)
        >>> ax.plot(x, halfcauchy.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='halfcauchy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = halfcauchy()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = halfcauchy.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], halfcauchy.cdf(vals))
        True

        Generate random numbers:

        >>> r = halfcauchy.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    halfgennorm = <scipy.stats._continuous_distns.halfgennorm_gen object>
        The upper half of a generalized normal continuous random variable.

        As an instance of the `rv_continuous` class, `halfgennorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(beta, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, beta, loc=0, scale=1)
            Probability density function.
        logpdf(x, beta, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, beta, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, beta, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, beta, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, beta, loc=0, scale=1)
            Log of the survival function.
        ppf(q, beta, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, beta, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, beta, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(beta, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(beta, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(beta,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(beta, loc=0, scale=1)
            Median of the distribution.
        mean(beta, loc=0, scale=1)
            Mean of the distribution.
        var(beta, loc=0, scale=1)
            Variance of the distribution.
        std(beta, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, beta, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        gennorm : generalized normal distribution
        expon : exponential distribution
        halfnorm : half normal distribution

        Notes
        -----
        The probability density function for `halfgennorm` is:

        .. math::

            f(x, \beta) = \frac{\beta}{\Gamma(1/\beta)} \exp(-|x|^\beta)

        for :math:`x, \beta > 0`. :math:`\Gamma` is the gamma function
        (`scipy.special.gamma`).

        `halfgennorm` takes ``beta`` as a shape parameter for :math:`\beta`.
        For :math:`\beta = 1`, it is identical to an exponential distribution.
        For :math:`\beta = 2`, it is identical to a half normal distribution
        (with ``scale=1/sqrt(2)``).

        References
        ----------

        .. [1] "Generalized normal distribution, Version 1",
               https://en.wikipedia.org/wiki/Generalized_normal_distribution#Version_1

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import halfgennorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> beta = 0.675
        >>> mean, var, skew, kurt = halfgennorm.stats(beta, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(halfgennorm.ppf(0.01, beta),
        ...                 halfgennorm.ppf(0.99, beta), 100)
        >>> ax.plot(x, halfgennorm.pdf(x, beta),
        ...        'r-', lw=5, alpha=0.6, label='halfgennorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = halfgennorm(beta)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = halfgennorm.ppf([0.001, 0.5, 0.999], beta)
        >>> np.allclose([0.001, 0.5, 0.999], halfgennorm.cdf(vals, beta))
        True

        Generate random numbers:

        >>> r = halfgennorm.rvs(beta, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    halflogistic = <scipy.stats._continuous_distns.halflogistic_gen object...
        A half-logistic continuous random variable.

        As an instance of the `rv_continuous` class, `halflogistic` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `halflogistic` is:

        .. math::

            f(x) = \frac{ 2 e^{-x} }{ (1+e^{-x})^2 }
                 = \frac{1}{2} \text{sech}(x/2)^2

        for :math:`x \ge 0`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``halflogistic.pdf(x, loc, scale)`` is identically
        equivalent to ``halflogistic.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Asgharzadeh et al (2011). "Comparisons of Methods of Estimation for the
               Half-Logistic Distribution". Selcuk J. Appl. Math. 93-108.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import halflogistic
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = halflogistic.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(halflogistic.ppf(0.01),
        ...                 halflogistic.ppf(0.99), 100)
        >>> ax.plot(x, halflogistic.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='halflogistic pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = halflogistic()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = halflogistic.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], halflogistic.cdf(vals))
        True

        Generate random numbers:

        >>> r = halflogistic.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    halfnorm = <scipy.stats._continuous_distns.halfnorm_gen object>
        A half-normal continuous random variable.

        As an instance of the `rv_continuous` class, `halfnorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `halfnorm` is:

        .. math::

            f(x) = \sqrt{2/\pi} \exp(-x^2 / 2)

        for :math:`x >= 0`.

        `halfnorm` is a special case of `chi` with ``df=1``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``halfnorm.pdf(x, loc, scale)`` is identically
        equivalent to ``halfnorm.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import halfnorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = halfnorm.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(halfnorm.ppf(0.01),
        ...                 halfnorm.ppf(0.99), 100)
        >>> ax.plot(x, halfnorm.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='halfnorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = halfnorm()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = halfnorm.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], halfnorm.cdf(vals))
        True

        Generate random numbers:

        >>> r = halfnorm.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    hypergeom = <scipy.stats._discrete_distns.hypergeom_gen object>
        A hypergeometric discrete random variable.

        The hypergeometric distribution models drawing objects from a bin.
        `M` is the total number of objects, `n` is total number of Type I objects.
        The random variate represents the number of Type I objects in `N` drawn
        without replacement from the total population.

        As an instance of the `rv_discrete` class, `hypergeom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(M, n, N, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, M, n, N, loc=0)
            Probability mass function.
        logpmf(k, M, n, N, loc=0)
            Log of the probability mass function.
        cdf(k, M, n, N, loc=0)
            Cumulative distribution function.
        logcdf(k, M, n, N, loc=0)
            Log of the cumulative distribution function.
        sf(k, M, n, N, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, M, n, N, loc=0)
            Log of the survival function.
        ppf(q, M, n, N, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, M, n, N, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(M, n, N, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(M, n, N, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(M, n, N), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(M, n, N, loc=0)
            Median of the distribution.
        mean(M, n, N, loc=0)
            Mean of the distribution.
        var(M, n, N, loc=0)
            Variance of the distribution.
        std(M, n, N, loc=0)
            Standard deviation of the distribution.
        interval(confidence, M, n, N, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The symbols used to denote the shape parameters (`M`, `n`, and `N`) are not
        universally accepted.  See the Examples for a clarification of the
        definitions used here.

        The probability mass function is defined as,

        .. math:: p(k, M, n, N) = \frac{\binom{n}{k} \binom{M - n}{N - k}}
                                       {\binom{M}{N}}

        for :math:`k \in [\max(0, N - M + n), \min(n, N)]`, where the binomial
        coefficients are defined as,

        .. math:: \binom{n}{k} \equiv \frac{n!}{k! (n - k)!}.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``hypergeom.pmf(k, M, n, N, loc)`` is identically
        equivalent to ``hypergeom.pmf(k - loc, M, n, N)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import hypergeom
        >>> import matplotlib.pyplot as plt

        Suppose we have a collection of 20 animals, of which 7 are dogs.  Then if
        we want to know the probability of finding a given number of dogs if we
        choose at random 12 of the 20 animals, we can initialize a frozen
        distribution and plot the probability mass function:

        >>> [M, n, N] = [20, 7, 12]
        >>> rv = hypergeom(M, n, N)
        >>> x = np.arange(0, n+1)
        >>> pmf_dogs = rv.pmf(x)

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, pmf_dogs, 'bo')
        >>> ax.vlines(x, 0, pmf_dogs, lw=2)
        >>> ax.set_xlabel('# of dogs in our group of chosen animals')
        >>> ax.set_ylabel('hypergeom PMF')
        >>> plt.show()

        Instead of using a frozen distribution we can also use `hypergeom`
        methods directly.  To for example obtain the cumulative distribution
        function, use:

        >>> prb = hypergeom.cdf(x, M, n, N)

        And to generate random numbers:

        >>> R = hypergeom.rvs(M, n, N, size=10)

        See Also
        --------
        nhypergeom, binom, nbinom

    hypsecant = <scipy.stats._continuous_distns.hypsecant_gen object>
        A hyperbolic secant continuous random variable.

        As an instance of the `rv_continuous` class, `hypsecant` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `hypsecant` is:

        .. math::

            f(x) = \frac{1}{\pi} \text{sech}(x)

        for a real number :math:`x`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``hypsecant.pdf(x, loc, scale)`` is identically
        equivalent to ``hypsecant.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import hypsecant
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = hypsecant.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(hypsecant.ppf(0.01),
        ...                 hypsecant.ppf(0.99), 100)
        >>> ax.plot(x, hypsecant.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='hypsecant pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = hypsecant()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = hypsecant.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], hypsecant.cdf(vals))
        True

        Generate random numbers:

        >>> r = hypsecant.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    invgamma = <scipy.stats._continuous_distns.invgamma_gen object>
        An inverted gamma continuous random variable.

        As an instance of the `rv_continuous` class, `invgamma` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `invgamma` is:

        .. math::

            f(x, a) = \frac{x^{-a-1}}{\Gamma(a)} \exp(-\frac{1}{x})

        for :math:`x >= 0`, :math:`a > 0`. :math:`\Gamma` is the gamma function
        (`scipy.special.gamma`).

        `invgamma` takes ``a`` as a shape parameter for :math:`a`.

        `invgamma` is a special case of `gengamma` with ``c=-1``, and it is a
        different parameterization of the scaled inverse chi-squared distribution.
        Specifically, if the scaled inverse chi-squared distribution is
        parameterized with degrees of freedom :math:`\nu` and scaling parameter
        :math:`\tau^2`, then it can be modeled using `invgamma` with
        ``a=`` :math:`\nu/2` and ``scale=`` :math:`\nu \tau^2/2`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``invgamma.pdf(x, a, loc, scale)`` is identically
        equivalent to ``invgamma.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import invgamma
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 4.07
        >>> mean, var, skew, kurt = invgamma.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(invgamma.ppf(0.01, a),
        ...                 invgamma.ppf(0.99, a), 100)
        >>> ax.plot(x, invgamma.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='invgamma pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = invgamma(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = invgamma.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], invgamma.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = invgamma.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    invgauss = <scipy.stats._continuous_distns.invgauss_gen object>
        An inverse Gaussian continuous random variable.

        As an instance of the `rv_continuous` class, `invgauss` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(mu, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, mu, loc=0, scale=1)
            Probability density function.
        logpdf(x, mu, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, mu, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, mu, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, mu, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, mu, loc=0, scale=1)
            Log of the survival function.
        ppf(q, mu, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, mu, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, mu, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(mu, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(mu, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(mu,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(mu, loc=0, scale=1)
            Median of the distribution.
        mean(mu, loc=0, scale=1)
            Mean of the distribution.
        var(mu, loc=0, scale=1)
            Variance of the distribution.
        std(mu, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, mu, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `invgauss` is:

        .. math::

            f(x; \mu) = \frac{1}{\sqrt{2 \pi x^3}}
                        \exp\left(-\frac{(x-\mu)^2}{2 \mu^2 x}\right)

        for :math:`x \ge 0` and :math:`\mu > 0`.

        `invgauss` takes ``mu`` as a shape parameter for :math:`\mu`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``invgauss.pdf(x, mu, loc, scale)`` is identically
        equivalent to ``invgauss.pdf(y, mu) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        A common shape-scale parameterization of the inverse Gaussian distribution
        has density

        .. math::

            f(x; \nu, \lambda) = \sqrt{\frac{\lambda}{2 \pi x^3}}
                        \exp\left( -\frac{\lambda(x-\nu)^2}{2 \nu^2 x}\right)

        Using ``nu`` for :math:`\nu` and ``lam`` for :math:`\lambda`, this
        parameterization is equivalent to the one above with ``mu = nu/lam``,
        ``loc = 0``, and ``scale = lam``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import invgauss
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mu = 0.145
        >>> mean, var, skew, kurt = invgauss.stats(mu, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(invgauss.ppf(0.01, mu),
        ...                 invgauss.ppf(0.99, mu), 100)
        >>> ax.plot(x, invgauss.pdf(x, mu),
        ...        'r-', lw=5, alpha=0.6, label='invgauss pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = invgauss(mu)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = invgauss.ppf([0.001, 0.5, 0.999], mu)
        >>> np.allclose([0.001, 0.5, 0.999], invgauss.cdf(vals, mu))
        True

        Generate random numbers:

        >>> r = invgauss.rvs(mu, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    invweibull = <scipy.stats._continuous_distns.invweibull_gen object>
        An inverted Weibull continuous random variable.

        This distribution is also known as the Fréchet distribution or the
        type II extreme value distribution.

        As an instance of the `rv_continuous` class, `invweibull` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `invweibull` is:

        .. math::

            f(x, c) = c x^{-c-1} \exp(-x^{-c})

        for :math:`x > 0`, :math:`c > 0`.

        `invweibull` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``invweibull.pdf(x, c, loc, scale)`` is identically
        equivalent to ``invweibull.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        F.R.S. de Gusmao, E.M.M Ortega and G.M. Cordeiro, "The generalized inverse
        Weibull distribution", Stat. Papers, vol. 52, pp. 591-619, 2011.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import invweibull
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 10.6
        >>> mean, var, skew, kurt = invweibull.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(invweibull.ppf(0.01, c),
        ...                 invweibull.ppf(0.99, c), 100)
        >>> ax.plot(x, invweibull.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='invweibull pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = invweibull(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = invweibull.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], invweibull.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = invweibull.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    invwishart = <scipy.stats._multivariate.invwishart_gen object>
        An inverse Wishart random variable.

        The `df` keyword specifies the degrees of freedom. The `scale` keyword
        specifies the scale matrix, which must be symmetric and positive definite.
        In this context, the scale matrix is often interpreted in terms of a
        multivariate normal covariance matrix.

        Methods
        -------
        pdf(x, df, scale)
            Probability density function.
        logpdf(x, df, scale)
            Log of the probability density function.
        rvs(df, scale, size=1, random_state=None)
            Draw random samples from an inverse Wishart distribution.
        entropy(df, scale)
            Differential entropy of the distribution.

        Parameters
        ----------
        df : int
            Degrees of freedom, must be greater than or equal to dimension of the
            scale matrix
        scale : array_like
            Symmetric positive definite scale matrix of the distribution
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Raises
        ------
        scipy.linalg.LinAlgError
            If the scale matrix `scale` is not positive definite.

        See Also
        --------
        wishart

        Notes
        -----


        The scale matrix `scale` must be a symmetric positive definite
        matrix. Singular matrices, including the symmetric positive semi-definite
        case, are not supported. Symmetry is not checked; only the lower triangular
        portion is used.

        The inverse Wishart distribution is often denoted

        .. math::

            W_p^{-1}(\nu, \Psi)

        where :math:`\nu` is the degrees of freedom and :math:`\Psi` is the
        :math:`p \times p` scale matrix.

        The probability density function for `invwishart` has support over positive
        definite matrices :math:`S`; if :math:`S \sim W^{-1}_p(\nu, \Sigma)`,
        then its PDF is given by:

        .. math::

            f(S) = \frac{|\Sigma|^\frac{\nu}{2}}{2^{ \frac{\nu p}{2} }
                   |S|^{\frac{\nu + p + 1}{2}} \Gamma_p \left(\frac{\nu}{2} \right)}
                   \exp\left( -tr(\Sigma S^{-1}) / 2 \right)

        If :math:`S \sim W_p^{-1}(\nu, \Psi)` (inverse Wishart) then
        :math:`S^{-1} \sim W_p(\nu, \Psi^{-1})` (Wishart).

        If the scale matrix is 1-dimensional and equal to one, then the inverse
        Wishart distribution :math:`W_1(\nu, 1)` collapses to the
        inverse Gamma distribution with parameters shape = :math:`\frac{\nu}{2}`
        and scale = :math:`\frac{1}{2}`.

        Instead of inverting a randomly generated Wishart matrix as described in [2],
        here the algorithm in [4] is used to directly generate a random inverse-Wishart
        matrix without inversion.

        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] M.L. Eaton, "Multivariate Statistics: A Vector Space Approach",
               Wiley, 1983.
        .. [2] M.C. Jones, "Generating Inverse Wishart Matrices", Communications
               in Statistics - Simulation and Computation, vol. 14.2, pp.511-514,
               1985.
        .. [3] Gupta, M. and Srivastava, S. "Parametric Bayesian Estimation of
               Differential Entropy and Relative Entropy". Entropy 12, 818 - 843.
               2010.
        .. [4] S.D. Axen, "Efficiently generating inverse-Wishart matrices and
               their Cholesky factors", :arXiv:`2310.15884v1`. 2023.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import invwishart, invgamma
        >>> x = np.linspace(0.01, 1, 100)
        >>> iw = invwishart.pdf(x, df=6, scale=1)
        >>> iw[:3]
        array([  1.20546865e-15,   5.42497807e-06,   4.45813929e-03])
        >>> ig = invgamma.pdf(x, 6/2., scale=1./2)
        >>> ig[:3]
        array([  1.20546865e-15,   5.42497807e-06,   4.45813929e-03])
        >>> plt.plot(x, iw)
        >>> plt.show()

        The input quantiles can be any shape of array, as long as the last
        axis labels the components.

        Alternatively, the object may be called (as a function) to fix the degrees
        of freedom and scale parameters, returning a "frozen" inverse Wishart
        random variable:

        >>> rv = invwishart(df=1, scale=1)
        >>> # Frozen object with the same methods but holding the given
        >>> # degrees of freedom and scale fixed.

    irwinhall = <scipy.stats._continuous_distns.irwinhall_gen object>
        An Irwin-Hall (Uniform Sum) continuous random variable.

        An `Irwin-Hall <https://en.wikipedia.org/wiki/Irwin-Hall_distribution/>`_
        continuous random variable is the sum of :math:`n` independent
        standard uniform random variables [1]_ [2]_.

        As an instance of the `rv_continuous` class, `irwinhall` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, n, loc=0, scale=1)
            Probability density function.
        logpdf(x, n, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, n, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, n, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, n, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, n, loc=0, scale=1)
            Log of the survival function.
        ppf(q, n, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, n, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(n, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(n,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, loc=0, scale=1)
            Median of the distribution.
        mean(n, loc=0, scale=1)
            Mean of the distribution.
        var(n, loc=0, scale=1)
            Variance of the distribution.
        std(n, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, n, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        Applications include `Rao's Spacing Test
        <https://jammalam.faculty.pstat.ucsb.edu/html/favorite/test.htm>`_,
        a more powerful alternative to the Rayleigh test
        when the data are not unimodal, and radar [3]_.

        Conveniently, the pdf and cdf are the :math:`n`-fold convolution of
        the ones for the standard uniform distribution, which is also the
        definition of the cardinal B-splines of degree :math:`n-1`
        having knots evenly spaced from :math:`1` to :math:`n` [4]_ [5]_.

        The Bates distribution, which represents the *mean* of statistically
        independent, uniformly distributed random variables, is simply the
        Irwin-Hall distribution scaled by :math:`1/n`. For example, the frozen
        distribution ``bates = irwinhall(10, scale=1/10)`` represents the
        distribution of the mean of 10 uniformly distributed random variables.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``irwinhall.pdf(x, n, loc, scale)`` is identically
        equivalent to ``irwinhall.pdf(y, n) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] P. Hall, "The distribution of means for samples of size N drawn
                from a population in which the variate takes values between 0 and 1,
                all such values being equally probable",
                Biometrika, Volume 19, Issue 3-4, December 1927, Pages 240-244,
                :doi:`10.1093/biomet/19.3-4.240`.
        .. [2] J. O. Irwin, "On the frequency distribution of the means of samples
                from a population having any law of frequency with finite moments,
                with special reference to Pearson's Type II,
                Biometrika, Volume 19, Issue 3-4, December 1927, Pages 225-239,
                :doi:`0.1093/biomet/19.3-4.225`.
        .. [3] K. Buchanan, T. Adeyemi, C. Flores-Molina, S. Wheeland and D. Overturf,
                "Sidelobe behavior and bandwidth characteristics
                of distributed antenna arrays,"
                2018 United States National Committee of
                URSI National Radio Science Meeting (USNC-URSI NRSM),
                Boulder, CO, USA, 2018, pp. 1-2.
                https://www.usnc-ursi-archive.org/nrsm/2018/papers/B15-9.pdf.
        .. [4] Amos Ron, "Lecture 1: Cardinal B-splines and convolution operators", p. 1
                https://pages.cs.wisc.edu/~deboor/887/lec1new.pdf.
        .. [5] Trefethen, N. (2012, July). B-splines and convolution. Chebfun.
                Retrieved April 30, 2024, from http://www.chebfun.org/examples/approx/BSplineConv.html.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import irwinhall
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> n = 10
        >>> mean, var, skew, kurt = irwinhall.stats(n, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(irwinhall.ppf(0.01, n),
        ...                 irwinhall.ppf(0.99, n), 100)
        >>> ax.plot(x, irwinhall.pdf(x, n),
        ...        'r-', lw=5, alpha=0.6, label='irwinhall pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = irwinhall(n)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = irwinhall.ppf([0.001, 0.5, 0.999], n)
        >>> np.allclose([0.001, 0.5, 0.999], irwinhall.cdf(vals, n))
        True

        Generate random numbers:

        >>> r = irwinhall.rvs(n, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    jf_skew_t = <scipy.stats._continuous_distns.jf_skew_t_gen object>
        Jones and Faddy skew-t distribution.

        As an instance of the `rv_continuous` class, `jf_skew_t` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `jf_skew_t` is:

        .. math::

            f(x; a, b) = C_{a,b}^{-1}
                        \left(1+\frac{x}{\left(a+b+x^2\right)^{1/2}}\right)^{a+1/2}
                        \left(1-\frac{x}{\left(a+b+x^2\right)^{1/2}}\right)^{b+1/2}

        for real numbers :math:`a>0` and :math:`b>0`, where
        :math:`C_{a,b} = 2^{a+b-1}B(a,b)(a+b)^{1/2}`, and :math:`B` denotes the
        beta function (`scipy.special.beta`).

        When :math:`a<b`, the distribution is negatively skewed, and when
        :math:`a>b`, the distribution is positively skewed. If :math:`a=b`, then
        we recover the `t` distribution with :math:`2a` degrees of freedom.

        `jf_skew_t` takes :math:`a` and :math:`b` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``jf_skew_t.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``jf_skew_t.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] M.C. Jones and M.J. Faddy. "A skew extension of the t distribution,
               with applications" *Journal of the Royal Statistical Society*.
               Series B (Statistical Methodology) 65, no. 1 (2003): 159-174.
               :doi:`10.1111/1467-9868.00378`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import jf_skew_t
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 8, 4
        >>> mean, var, skew, kurt = jf_skew_t.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(jf_skew_t.ppf(0.01, a, b),
        ...                 jf_skew_t.ppf(0.99, a, b), 100)
        >>> ax.plot(x, jf_skew_t.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='jf_skew_t pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = jf_skew_t(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = jf_skew_t.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], jf_skew_t.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = jf_skew_t.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    johnsonsb = <scipy.stats._continuous_distns.johnsonsb_gen object>
        A Johnson SB continuous random variable.

        As an instance of the `rv_continuous` class, `johnsonsb` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        johnsonsu

        Notes
        -----
        The probability density function for `johnsonsb` is:

        .. math::

            f(x, a, b) = \frac{b}{x(1-x)}  \phi(a + b \log \frac{x}{1-x} )

        where :math:`x`, :math:`a`, and :math:`b` are real scalars; :math:`b > 0`
        and :math:`x \in [0,1]`.  :math:`\phi` is the pdf of the normal
        distribution.

        `johnsonsb` takes :math:`a` and :math:`b` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``johnsonsb.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``johnsonsb.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import johnsonsb
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 4.32, 3.18
        >>> mean, var, skew, kurt = johnsonsb.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(johnsonsb.ppf(0.01, a, b),
        ...                 johnsonsb.ppf(0.99, a, b), 100)
        >>> ax.plot(x, johnsonsb.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='johnsonsb pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = johnsonsb(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = johnsonsb.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], johnsonsb.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = johnsonsb.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    johnsonsu = <scipy.stats._continuous_distns.johnsonsu_gen object>
        A Johnson SU continuous random variable.

        As an instance of the `rv_continuous` class, `johnsonsu` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        johnsonsb

        Notes
        -----
        The probability density function for `johnsonsu` is:

        .. math::

            f(x, a, b) = \frac{b}{\sqrt{x^2 + 1}}
                         \phi(a + b \log(x + \sqrt{x^2 + 1}))

        where :math:`x`, :math:`a`, and :math:`b` are real scalars; :math:`b > 0`.
        :math:`\phi` is the pdf of the normal distribution.

        `johnsonsu` takes :math:`a` and :math:`b` as shape parameters.

        The first four central moments are calculated according to the formulas
        in [1]_.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``johnsonsu.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``johnsonsu.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Taylor Enterprises. "Johnson Family of Distributions".
           https://variation.com/wp-content/distribution_analyzer_help/hs126.htm

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import johnsonsu
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 2.55, 2.25
        >>> mean, var, skew, kurt = johnsonsu.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(johnsonsu.ppf(0.01, a, b),
        ...                 johnsonsu.ppf(0.99, a, b), 100)
        >>> ax.plot(x, johnsonsu.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='johnsonsu pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = johnsonsu(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = johnsonsu.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], johnsonsu.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = johnsonsu.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    kappa3 = <scipy.stats._continuous_distns.kappa3_gen object>
        Kappa 3 parameter distribution.

        As an instance of the `rv_continuous` class, `kappa3` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `kappa3` is:

        .. math::

            f(x, a) = a (a + x^a)^{-(a + 1)/a}

        for :math:`x > 0` and :math:`a > 0`.

        `kappa3` takes ``a`` as a shape parameter for :math:`a`.

        References
        ----------
        P.W. Mielke and E.S. Johnson, "Three-Parameter Kappa Distribution Maximum
        Likelihood and Likelihood Ratio Tests", Methods in Weather Research,
        701-707, (September, 1973),
        :doi:`10.1175/1520-0493(1973)101<0701:TKDMLE>2.3.CO;2`

        B. Kumphon, "Maximum Entropy and Maximum Likelihood Estimation for the
        Three-Parameter Kappa Distribution", Open Journal of Statistics, vol 2,
        415-419 (2012), :doi:`10.4236/ojs.2012.24050`

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``kappa3.pdf(x, a, loc, scale)`` is identically
        equivalent to ``kappa3.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import kappa3
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 1
        >>> mean, var, skew, kurt = kappa3.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(kappa3.ppf(0.01, a),
        ...                 kappa3.ppf(0.99, a), 100)
        >>> ax.plot(x, kappa3.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='kappa3 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = kappa3(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = kappa3.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], kappa3.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = kappa3.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    kappa4 = <scipy.stats._continuous_distns.kappa4_gen object>
        Kappa 4 parameter distribution.

        As an instance of the `rv_continuous` class, `kappa4` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(h, k, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, h, k, loc=0, scale=1)
            Probability density function.
        logpdf(x, h, k, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, h, k, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, h, k, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, h, k, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, h, k, loc=0, scale=1)
            Log of the survival function.
        ppf(q, h, k, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, h, k, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, h, k, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(h, k, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(h, k, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(h, k), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(h, k, loc=0, scale=1)
            Median of the distribution.
        mean(h, k, loc=0, scale=1)
            Mean of the distribution.
        var(h, k, loc=0, scale=1)
            Variance of the distribution.
        std(h, k, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, h, k, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for kappa4 is:

        .. math::

            f(x, h, k) = (1 - k x)^{1/k - 1} (1 - h (1 - k x)^{1/k})^{1/h-1}

        if :math:`h` and :math:`k` are not equal to 0.

        If :math:`h` or :math:`k` are zero then the pdf can be simplified:

        h = 0 and k != 0::

            kappa4.pdf(x, h, k) = (1.0 - k*x)**(1.0/k - 1.0)*
                                  exp(-(1.0 - k*x)**(1.0/k))

        h != 0 and k = 0::

            kappa4.pdf(x, h, k) = exp(-x)*(1.0 - h*exp(-x))**(1.0/h - 1.0)

        h = 0 and k = 0::

            kappa4.pdf(x, h, k) = exp(-x)*exp(-exp(-x))

        kappa4 takes :math:`h` and :math:`k` as shape parameters.

        The kappa4 distribution returns other distributions when certain
        :math:`h` and :math:`k` values are used.

        +------+-------------+----------------+------------------+
        | h    | k=0.0       | k=1.0          | -inf<=k<=inf     |
        +======+=============+================+==================+
        | -1.0 | Logistic    |                | Generalized      |
        |      |             |                | Logistic(1)      |
        |      |             |                |                  |
        |      | logistic(x) |                |                  |
        +------+-------------+----------------+------------------+
        |  0.0 | Gumbel      | Reverse        | Generalized      |
        |      |             | Exponential(2) | Extreme Value    |
        |      |             |                |                  |
        |      | gumbel_r(x) |                | genextreme(x, k) |
        +------+-------------+----------------+------------------+
        |  1.0 | Exponential | Uniform        | Generalized      |
        |      |             |                | Pareto           |
        |      |             |                |                  |
        |      | expon(x)    | uniform(x)     | genpareto(x, -k) |
        +------+-------------+----------------+------------------+

        (1) There are at least five generalized logistic distributions.
            Four are described here:
            https://en.wikipedia.org/wiki/Generalized_logistic_distribution
            The "fifth" one is the one kappa4 should match which currently
            isn't implemented in scipy:
            https://en.wikipedia.org/wiki/Talk:Generalized_logistic_distribution
            https://www.mathwave.com/help/easyfit/html/analyses/distributions/gen_logistic.html
        (2) This distribution is currently not in scipy.

        References
        ----------
        J.C. Finney, "Optimization of a Skewed Logistic Distribution With Respect
        to the Kolmogorov-Smirnov Test", A Dissertation Submitted to the Graduate
        Faculty of the Louisiana State University and Agricultural and Mechanical
        College, (August, 2004),
        https://digitalcommons.lsu.edu/gradschool_dissertations/3672

        J.R.M. Hosking, "The four-parameter kappa distribution". IBM J. Res.
        Develop. 38 (3), 25 1-258 (1994).

        B. Kumphon, A. Kaew-Man, P. Seenoi, "A Rainfall Distribution for the Lampao
        Site in the Chi River Basin, Thailand", Journal of Water Resource and
        Protection, vol. 4, 866-869, (2012).
        :doi:`10.4236/jwarp.2012.410101`

        C. Winchester, "On Estimation of the Four-Parameter Kappa Distribution", A
        Thesis Submitted to Dalhousie University, Halifax, Nova Scotia, (March
        2000).
        http://www.nlc-bnc.ca/obj/s4/f2/dsk2/ftp01/MQ57336.pdf

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``kappa4.pdf(x, h, k, loc, scale)`` is identically
        equivalent to ``kappa4.pdf(y, h, k) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import kappa4
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> h, k = 0.1, 0
        >>> mean, var, skew, kurt = kappa4.stats(h, k, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(kappa4.ppf(0.01, h, k),
        ...                 kappa4.ppf(0.99, h, k), 100)
        >>> ax.plot(x, kappa4.pdf(x, h, k),
        ...        'r-', lw=5, alpha=0.6, label='kappa4 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = kappa4(h, k)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = kappa4.ppf([0.001, 0.5, 0.999], h, k)
        >>> np.allclose([0.001, 0.5, 0.999], kappa4.cdf(vals, h, k))
        True

        Generate random numbers:

        >>> r = kappa4.rvs(h, k, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    ksone = <scipy.stats._continuous_distns.ksone_gen object>
        Kolmogorov-Smirnov one-sided test statistic distribution.

        This is the distribution of the one-sided Kolmogorov-Smirnov (KS)
        statistics :math:`D_n^+` and :math:`D_n^-`
        for a finite sample size ``n >= 1`` (the shape parameter).

        As an instance of the `rv_continuous` class, `ksone` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, n, loc=0, scale=1)
            Probability density function.
        logpdf(x, n, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, n, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, n, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, n, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, n, loc=0, scale=1)
            Log of the survival function.
        ppf(q, n, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, n, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(n, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(n,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, loc=0, scale=1)
            Median of the distribution.
        mean(n, loc=0, scale=1)
            Mean of the distribution.
        var(n, loc=0, scale=1)
            Variance of the distribution.
        std(n, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, n, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        kstwobign, kstwo, kstest

        Notes
        -----
        :math:`D_n^+` and :math:`D_n^-` are given by

        .. math::

            D_n^+ &= \text{sup}_x (F_n(x) - F(x)),\\
            D_n^- &= \text{sup}_x (F(x) - F_n(x)),\\

        where :math:`F` is a continuous CDF and :math:`F_n` is an empirical CDF.
        `ksone` describes the distribution under the null hypothesis of the KS test
        that the empirical CDF corresponds to :math:`n` i.i.d. random variates
        with CDF :math:`F`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``ksone.pdf(x, n, loc, scale)`` is identically
        equivalent to ``ksone.pdf(y, n) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Birnbaum, Z. W. and Tingey, F.H. "One-sided confidence contours
           for probability distribution functions", The Annals of Mathematical
           Statistics, 22(4), pp 592-596 (1951).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import ksone
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Display the probability density function (``pdf``):

        >>> n = 1e+03
        >>> x = np.linspace(ksone.ppf(0.01, n),
        ...                 ksone.ppf(0.99, n), 100)
        >>> ax.plot(x, ksone.pdf(x, n),
        ...         'r-', lw=5, alpha=0.6, label='ksone pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = ksone(n)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = ksone.ppf([0.001, 0.5, 0.999], n)
        >>> np.allclose([0.001, 0.5, 0.999], ksone.cdf(vals, n))
        True

    kstwo = <scipy.stats._continuous_distns.kstwo_gen object>
        Kolmogorov-Smirnov two-sided test statistic distribution.

        This is the distribution of the two-sided Kolmogorov-Smirnov (KS)
        statistic :math:`D_n` for a finite sample size ``n >= 1``
        (the shape parameter).

        As an instance of the `rv_continuous` class, `kstwo` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, n, loc=0, scale=1)
            Probability density function.
        logpdf(x, n, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, n, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, n, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, n, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, n, loc=0, scale=1)
            Log of the survival function.
        ppf(q, n, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, n, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(n, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(n,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, loc=0, scale=1)
            Median of the distribution.
        mean(n, loc=0, scale=1)
            Mean of the distribution.
        var(n, loc=0, scale=1)
            Variance of the distribution.
        std(n, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, n, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        kstwobign, ksone, kstest

        Notes
        -----
        :math:`D_n` is given by

        .. math::

            D_n = \text{sup}_x |F_n(x) - F(x)|

        where :math:`F` is a (continuous) CDF and :math:`F_n` is an empirical CDF.
        `kstwo` describes the distribution under the null hypothesis of the KS test
        that the empirical CDF corresponds to :math:`n` i.i.d. random variates
        with CDF :math:`F`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``kstwo.pdf(x, n, loc, scale)`` is identically
        equivalent to ``kstwo.pdf(y, n) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Simard, R., L'Ecuyer, P. "Computing the Two-Sided
           Kolmogorov-Smirnov Distribution",  Journal of Statistical Software,
           Vol 39, 11, 1-18 (2011).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import kstwo
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Display the probability density function (``pdf``):

        >>> n = 10
        >>> x = np.linspace(kstwo.ppf(0.01, n),
        ...                 kstwo.ppf(0.99, n), 100)
        >>> ax.plot(x, kstwo.pdf(x, n),
        ...         'r-', lw=5, alpha=0.6, label='kstwo pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = kstwo(n)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = kstwo.ppf([0.001, 0.5, 0.999], n)
        >>> np.allclose([0.001, 0.5, 0.999], kstwo.cdf(vals, n))
        True

    kstwobign = <scipy.stats._continuous_distns.kstwobign_gen object>
        Limiting distribution of scaled Kolmogorov-Smirnov two-sided test statistic.

        This is the asymptotic distribution of the two-sided Kolmogorov-Smirnov
        statistic :math:`\sqrt{n} D_n` that measures the maximum absolute
        distance of the theoretical (continuous) CDF from the empirical CDF.
        (see `kstest`).

        As an instance of the `rv_continuous` class, `kstwobign` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        ksone, kstwo, kstest

        Notes
        -----
        :math:`\sqrt{n} D_n` is given by

        .. math::

            D_n = \text{sup}_x |F_n(x) - F(x)|

        where :math:`F` is a continuous CDF and :math:`F_n` is an empirical CDF.
        `kstwobign`  describes the asymptotic distribution (i.e. the limit of
        :math:`\sqrt{n} D_n`) under the null hypothesis of the KS test that the
        empirical CDF corresponds to i.i.d. random variates with CDF :math:`F`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``kstwobign.pdf(x, loc, scale)`` is identically
        equivalent to ``kstwobign.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Feller, W. "On the Kolmogorov-Smirnov Limit Theorems for Empirical
           Distributions",  Ann. Math. Statist. Vol 19, 177-189 (1948).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import kstwobign
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = kstwobign.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(kstwobign.ppf(0.01),
        ...                 kstwobign.ppf(0.99), 100)
        >>> ax.plot(x, kstwobign.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='kstwobign pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = kstwobign()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = kstwobign.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], kstwobign.cdf(vals))
        True

        Generate random numbers:

        >>> r = kstwobign.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    laplace = <scipy.stats._continuous_distns.laplace_gen object>
        A Laplace continuous random variable.

        As an instance of the `rv_continuous` class, `laplace` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `laplace` is

        .. math::

            f(x) = \frac{1}{2} \exp(-|x|)

        for a real number :math:`x`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``laplace.pdf(x, loc, scale)`` is identically
        equivalent to ``laplace.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import laplace
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = laplace.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(laplace.ppf(0.01),
        ...                 laplace.ppf(0.99), 100)
        >>> ax.plot(x, laplace.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='laplace pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = laplace()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = laplace.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], laplace.cdf(vals))
        True

        Generate random numbers:

        >>> r = laplace.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    laplace_asymmetric = <scipy.stats._continuous_distns.laplace_asymmetri...
        An asymmetric Laplace continuous random variable.

        As an instance of the `rv_continuous` class, `laplace_asymmetric` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(kappa, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, kappa, loc=0, scale=1)
            Probability density function.
        logpdf(x, kappa, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, kappa, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, kappa, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, kappa, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, kappa, loc=0, scale=1)
            Log of the survival function.
        ppf(q, kappa, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, kappa, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, kappa, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(kappa, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(kappa, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(kappa,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(kappa, loc=0, scale=1)
            Median of the distribution.
        mean(kappa, loc=0, scale=1)
            Mean of the distribution.
        var(kappa, loc=0, scale=1)
            Variance of the distribution.
        std(kappa, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, kappa, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        laplace : Laplace distribution

        Notes
        -----
        The probability density function for `laplace_asymmetric` is

        .. math::

           f(x, \kappa) &= \frac{1}{\kappa+\kappa^{-1}}\exp(-x\kappa),\quad x\ge0\\
                        &= \frac{1}{\kappa+\kappa^{-1}}\exp(x/\kappa),\quad x<0\\

        for :math:`-\infty < x < \infty`, :math:`\kappa > 0`.

        `laplace_asymmetric` takes ``kappa`` as a shape parameter for
        :math:`\kappa`. For :math:`\kappa = 1`, it is identical to a
        Laplace distribution.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``laplace_asymmetric.pdf(x, kappa, loc, scale)`` is identically
        equivalent to ``laplace_asymmetric.pdf(y, kappa) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Note that the scale parameter of some references is the reciprocal of
        SciPy's ``scale``. For example, :math:`\lambda = 1/2` in the
        parameterization of [1]_ is equivalent to ``scale = 2`` with
        `laplace_asymmetric`.

        References
        ----------
        .. [1] "Asymmetric Laplace distribution", Wikipedia
                https://en.wikipedia.org/wiki/Asymmetric_Laplace_distribution

        .. [2] Kozubowski TJ and Podgórski K. A Multivariate and
               Asymmetric Generalization of Laplace Distribution,
               Computational Statistics 15, 531--540 (2000).
               :doi:`10.1007/PL00022717`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import laplace_asymmetric
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> kappa = 2
        >>> mean, var, skew, kurt = laplace_asymmetric.stats(kappa, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(laplace_asymmetric.ppf(0.01, kappa),
        ...                 laplace_asymmetric.ppf(0.99, kappa), 100)
        >>> ax.plot(x, laplace_asymmetric.pdf(x, kappa),
        ...        'r-', lw=5, alpha=0.6, label='laplace_asymmetric pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = laplace_asymmetric(kappa)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = laplace_asymmetric.ppf([0.001, 0.5, 0.999], kappa)
        >>> np.allclose([0.001, 0.5, 0.999], laplace_asymmetric.cdf(vals, kappa))
        True

        Generate random numbers:

        >>> r = laplace_asymmetric.rvs(kappa, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    levy = <scipy.stats._continuous_distns.levy_gen object>
        A Levy continuous random variable.

        As an instance of the `rv_continuous` class, `levy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        levy_stable, levy_l

        Notes
        -----
        The probability density function for `levy` is:

        .. math::

            f(x) = \frac{1}{\sqrt{2\pi x^3}} \exp\left(-\frac{1}{2x}\right)

        for :math:`x > 0`.

        This is the same as the Levy-stable distribution with :math:`a=1/2` and
        :math:`b=1`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``levy.pdf(x, loc, scale)`` is identically
        equivalent to ``levy.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import levy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mean, var, skew, kurt = levy.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> # `levy` is very heavy-tailed.
        >>> # To show a nice plot, let's cut off the upper 40 percent.
        >>> a, b = levy.ppf(0), levy.ppf(0.6)
        >>> x = np.linspace(a, b, 100)
        >>> ax.plot(x, levy.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='levy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = levy()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = levy.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], levy.cdf(vals))
        True

        Generate random numbers:

        >>> r = levy.rvs(size=1000)

        And compare the histogram:

        >>> # manual binning to ignore the tail
        >>> bins = np.concatenate((np.linspace(a, b, 20), [np.max(r)]))
        >>> ax.hist(r, bins=bins, density=True, histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    levy_l = <scipy.stats._continuous_distns.levy_l_gen object>
        A left-skewed Levy continuous random variable.

        As an instance of the `rv_continuous` class, `levy_l` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        levy, levy_stable

        Notes
        -----
        The probability density function for `levy_l` is:

        .. math::
            f(x) = \frac{1}{|x| \sqrt{2\pi |x|}} \exp{ \left(-\frac{1}{2|x|} \right)}

        for :math:`x < 0`.

        This is the same as the Levy-stable distribution with :math:`a=1/2` and
        :math:`b=-1`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``levy_l.pdf(x, loc, scale)`` is identically
        equivalent to ``levy_l.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import levy_l
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mean, var, skew, kurt = levy_l.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> # `levy_l` is very heavy-tailed.
        >>> # To show a nice plot, let's cut off the lower 40 percent.
        >>> a, b = levy_l.ppf(0.4), levy_l.ppf(1)
        >>> x = np.linspace(a, b, 100)
        >>> ax.plot(x, levy_l.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='levy_l pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = levy_l()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = levy_l.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], levy_l.cdf(vals))
        True

        Generate random numbers:

        >>> r = levy_l.rvs(size=1000)

        And compare the histogram:

        >>> # manual binning to ignore the tail
        >>> bins = np.concatenate(([np.min(r)], np.linspace(a, b, 20)))
        >>> ax.hist(r, bins=bins, density=True, histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    levy_stable = <scipy.stats._levy_stable.levy_stable_gen object>
        A Levy-stable continuous random variable.

        As an instance of the `rv_continuous` class, `levy_stable` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(alpha, beta, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, alpha, beta, loc=0, scale=1)
            Probability density function.
        logpdf(x, alpha, beta, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, alpha, beta, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, alpha, beta, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, alpha, beta, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, alpha, beta, loc=0, scale=1)
            Log of the survival function.
        ppf(q, alpha, beta, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, alpha, beta, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, alpha, beta, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(alpha, beta, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(alpha, beta, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(alpha, beta), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(alpha, beta, loc=0, scale=1)
            Median of the distribution.
        mean(alpha, beta, loc=0, scale=1)
            Mean of the distribution.
        var(alpha, beta, loc=0, scale=1)
            Variance of the distribution.
        std(alpha, beta, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, alpha, beta, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        levy, levy_l, cauchy, norm

        Notes
        -----
        The distribution for `levy_stable` has characteristic function:

        .. math::

            \varphi(t, \alpha, \beta, c, \mu) =
            e^{it\mu -|ct|^{\alpha}(1-i\beta\operatorname{sign}(t)\Phi(\alpha, t))}

        where two different parameterizations are supported. The first :math:`S_1`:

        .. math::

            \Phi = \begin{cases}
                    \tan \left({\frac {\pi \alpha }{2}}\right)&\alpha \neq 1\\
                    -{\frac {2}{\pi }}\log |t|&\alpha =1
                    \end{cases}

        The second :math:`S_0`:

        .. math::

            \Phi = \begin{cases}
                    -\tan \left({\frac {\pi \alpha }{2}}\right)(|ct|^{1-\alpha}-1)
                    &\alpha \neq 1\\
                    -{\frac {2}{\pi }}\log |ct|&\alpha =1
                    \end{cases}


        The probability density function for `levy_stable` is:

        .. math::

            f(x) = \frac{1}{2\pi}\int_{-\infty}^\infty \varphi(t)e^{-ixt}\,dt

        where :math:`-\infty < t < \infty`. This integral does not have a known
        closed form.

        `levy_stable` generalizes several distributions.  Where possible, they
        should be used instead.  Specifically, when the shape parameters
        assume the values in the table below, the corresponding equivalent
        distribution should be used.

        =========  ========  ===========
        ``alpha``  ``beta``   Equivalent
        =========  ========  ===========
         1/2       -1        `levy_l`
         1/2       1         `levy`
         1         0         `cauchy`
         2         any       `norm` (with ``scale=sqrt(2)``)
        =========  ========  ===========

        Evaluation of the pdf uses Nolan's piecewise integration approach with the
        Zolotarev :math:`M` parameterization by default. There is also the option
        to use direct numerical integration of the standard parameterization of the
        characteristic function or to evaluate by taking the FFT of the
        characteristic function.

        The default method can changed by setting the class variable
        ``levy_stable.pdf_default_method`` to one of 'piecewise' for Nolan's
        approach, 'dni' for direct numerical integration, or 'fft-simpson' for the
        FFT based approach. For the sake of backwards compatibility, the methods
        'best' and 'zolotarev' are equivalent to 'piecewise' and the method
        'quadrature' is equivalent to 'dni'.

        The parameterization can be changed  by setting the class variable
        ``levy_stable.parameterization`` to either 'S0' or 'S1'.
        The default is 'S1'.

        To improve performance of piecewise and direct numerical integration one
        can specify ``levy_stable.quad_eps`` (defaults to 1.2e-14). This is used
        as both the absolute and relative quadrature tolerance for direct numerical
        integration and as the relative quadrature tolerance for the piecewise
        method. One can also specify ``levy_stable.piecewise_x_tol_near_zeta``
        (defaults to 0.005) for how close x is to zeta before it is considered the
        same as x [NO]. The exact check is
        ``abs(x0 - zeta) < piecewise_x_tol_near_zeta*alpha**(1/alpha)``. One can
        also specify ``levy_stable.piecewise_alpha_tol_near_one`` (defaults to
        0.005) for how close alpha is to 1 before being considered equal to 1.

        To increase accuracy of FFT calculation one can specify
        ``levy_stable.pdf_fft_grid_spacing`` (defaults to 0.001) and
        ``pdf_fft_n_points_two_power`` (defaults to None which means a value is
        calculated that sufficiently covers the input range).

        Further control over FFT calculation is available by setting
        ``pdf_fft_interpolation_degree`` (defaults to 3) for spline order and
        ``pdf_fft_interpolation_level`` for determining the number of points to use
        in the Newton-Cotes formula when approximating the characteristic function
        (considered experimental).

        Evaluation of the cdf uses Nolan's piecewise integration approach with the
        Zolatarev :math:`S_0` parameterization by default. There is also the option
        to evaluate through integration of an interpolated spline of the pdf
        calculated by means of the FFT method. The settings affecting FFT
        calculation are the same as for pdf calculation. The default cdf method can
        be changed by setting ``levy_stable.cdf_default_method`` to either
        'piecewise' or 'fft-simpson'.  For cdf calculations the Zolatarev method is
        superior in accuracy, so FFT is disabled by default.

        Fitting estimate uses quantile estimation method in [MC]. MLE estimation of
        parameters in fit method uses this quantile estimate initially. Note that
        MLE doesn't always converge if using FFT for pdf calculations; this will be
        the case if alpha <= 1 where the FFT approach doesn't give good
        approximations.

        Any non-missing value for the attribute
        ``levy_stable.pdf_fft_min_points_threshold`` will set
        ``levy_stable.pdf_default_method`` to 'fft-simpson' if a valid
        default method is not otherwise set.



        .. warning::

            For pdf calculations FFT calculation is considered experimental.

            For cdf calculations FFT calculation is considered experimental. Use
            Zolatarev's method instead (default).

        The probability density above is defined in the "standardized" form. To
        shift and/or scale the distribution use the ``loc`` and ``scale``
        parameters.
        Generally ``levy_stable.pdf(x, alpha, beta, loc, scale)`` is identically
        equivalent to ``levy_stable.pdf(y, alpha, beta) / scale`` with
        ``y = (x - loc) / scale``, except in the ``S1`` parameterization if
        ``alpha == 1``.  In that case ``levy_stable.pdf(x, alpha, beta, loc, scale)``
        is identically equivalent to ``levy_stable.pdf(y, alpha, beta) / scale`` with
        ``y = (x - loc - 2 * beta * scale * np.log(scale) / np.pi) / scale``.
        See [NO2]_ Definition 1.8 for more information.
        Note that shifting the location of a distribution
        does not make it a "noncentral" distribution.

        References
        ----------
        .. [MC] McCulloch, J., 1986. Simple consistent estimators of stable
            distribution parameters. Communications in Statistics - Simulation and
            Computation 15, 11091136.
        .. [WZ] Wang, Li and Zhang, Ji-Hong, 2008. Simpson's rule based FFT method
            to compute densities of stable distribution.
        .. [NO] Nolan, J., 1997. Numerical Calculation of Stable Densities and
            distributions Functions.
        .. [NO2] Nolan, J., 2018. Stable Distributions: Models for Heavy Tailed
            Data.
        .. [HO] Hopcraft, K. I., Jakeman, E., Tanner, R. M. J., 1999. Lévy random
            walks with fluctuating step number and multiscale behavior.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import levy_stable
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> alpha, beta = 1.8, -0.5
        >>> mean, var, skew, kurt = levy_stable.stats(alpha, beta, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(levy_stable.ppf(0.01, alpha, beta),
        ...                 levy_stable.ppf(0.99, alpha, beta), 100)
        >>> ax.plot(x, levy_stable.pdf(x, alpha, beta),
        ...        'r-', lw=5, alpha=0.6, label='levy_stable pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = levy_stable(alpha, beta)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = levy_stable.ppf([0.001, 0.5, 0.999], alpha, beta)
        >>> np.allclose([0.001, 0.5, 0.999], levy_stable.cdf(vals, alpha, beta))
        True

        Generate random numbers:

        >>> r = levy_stable.rvs(alpha, beta, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    loggamma = <scipy.stats._continuous_distns.loggamma_gen object>
        A log gamma continuous random variable.

        As an instance of the `rv_continuous` class, `loggamma` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `loggamma` is:

        .. math::

            f(x, c) = \frac{\exp(c x - \exp(x))}
                           {\Gamma(c)}

        for all :math:`x, c > 0`. Here, :math:`\Gamma` is the
        gamma function (`scipy.special.gamma`).

        `loggamma` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``loggamma.pdf(x, c, loc, scale)`` is identically
        equivalent to ``loggamma.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import loggamma
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.414
        >>> mean, var, skew, kurt = loggamma.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(loggamma.ppf(0.01, c),
        ...                 loggamma.ppf(0.99, c), 100)
        >>> ax.plot(x, loggamma.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='loggamma pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = loggamma(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = loggamma.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], loggamma.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = loggamma.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    logistic = <scipy.stats._continuous_distns.logistic_gen object>
        A logistic (or Sech-squared) continuous random variable.

        As an instance of the `rv_continuous` class, `logistic` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `logistic` is:

        .. math::

            f(x) = \frac{\exp(-x)}
                        {(1+\exp(-x))^2}

        `logistic` is a special case of `genlogistic` with ``c=1``.

        Remark that the survival function (``logistic.sf``) is equal to the
        Fermi-Dirac distribution describing fermionic statistics.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``logistic.pdf(x, loc, scale)`` is identically
        equivalent to ``logistic.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import logistic
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = logistic.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(logistic.ppf(0.01),
        ...                 logistic.ppf(0.99), 100)
        >>> ax.plot(x, logistic.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='logistic pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = logistic()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = logistic.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], logistic.cdf(vals))
        True

        Generate random numbers:

        >>> r = logistic.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    loglaplace = <scipy.stats._continuous_distns.loglaplace_gen object>
        A log-Laplace continuous random variable.

        As an instance of the `rv_continuous` class, `loglaplace` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `loglaplace` is:

        .. math::

            f(x, c) = \begin{cases}\frac{c}{2} x^{ c-1}  &\text{for } 0 < x < 1\\
                                   \frac{c}{2} x^{-c-1}  &\text{for } x \ge 1
                      \end{cases}

        for :math:`c > 0`.

        `loglaplace` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``loglaplace.pdf(x, c, loc, scale)`` is identically
        equivalent to ``loglaplace.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Suppose a random variable ``X`` follows the Laplace distribution with
        location ``a`` and scale ``b``.  Then ``Y = exp(X)`` follows the
        log-Laplace distribution with ``c = 1 / b`` and ``scale = exp(a)``.

        References
        ----------
        T.J. Kozubowski and K. Podgorski, "A log-Laplace growth rate model",
        The Mathematical Scientist, vol. 28, pp. 49-60, 2003.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import loglaplace
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 3.25
        >>> mean, var, skew, kurt = loglaplace.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(loglaplace.ppf(0.01, c),
        ...                 loglaplace.ppf(0.99, c), 100)
        >>> ax.plot(x, loglaplace.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='loglaplace pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = loglaplace(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = loglaplace.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], loglaplace.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = loglaplace.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    lognorm = <scipy.stats._continuous_distns.lognorm_gen object>
        A lognormal continuous random variable.

        As an instance of the `rv_continuous` class, `lognorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(s, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, s, loc=0, scale=1)
            Probability density function.
        logpdf(x, s, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, s, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, s, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, s, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, s, loc=0, scale=1)
            Log of the survival function.
        ppf(q, s, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, s, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, s, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(s, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(s, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(s,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(s, loc=0, scale=1)
            Median of the distribution.
        mean(s, loc=0, scale=1)
            Mean of the distribution.
        var(s, loc=0, scale=1)
            Variance of the distribution.
        std(s, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, s, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `lognorm` is:

        .. math::

            f(x, s) = \frac{1}{s x \sqrt{2\pi}}
                      \exp\left(-\frac{\log^2(x)}{2s^2}\right)

        for :math:`x > 0`, :math:`s > 0`.

        `lognorm` takes ``s`` as a shape parameter for :math:`s`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``lognorm.pdf(x, s, loc, scale)`` is identically
        equivalent to ``lognorm.pdf(y, s) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Suppose a normally distributed random variable ``X`` has  mean ``mu`` and
        standard deviation ``sigma``. Then ``Y = exp(X)`` is lognormally
        distributed with ``s = sigma`` and ``scale = exp(mu)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import lognorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> s = 0.954
        >>> mean, var, skew, kurt = lognorm.stats(s, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(lognorm.ppf(0.01, s),
        ...                 lognorm.ppf(0.99, s), 100)
        >>> ax.plot(x, lognorm.pdf(x, s),
        ...        'r-', lw=5, alpha=0.6, label='lognorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = lognorm(s)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = lognorm.ppf([0.001, 0.5, 0.999], s)
        >>> np.allclose([0.001, 0.5, 0.999], lognorm.cdf(vals, s))
        True

        Generate random numbers:

        >>> r = lognorm.rvs(s, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        The logarithm of a log-normally distributed random variable is
        normally distributed:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy import stats
        >>> fig, ax = plt.subplots(1, 1)
        >>> mu, sigma = 2, 0.5
        >>> X = stats.norm(loc=mu, scale=sigma)
        >>> Y = stats.lognorm(s=sigma, scale=np.exp(mu))
        >>> x = np.linspace(*X.interval(0.999))
        >>> y = Y.rvs(size=10000)
        >>> ax.plot(x, X.pdf(x), label='X (pdf)')
        >>> ax.hist(np.log(y), density=True, bins=x, label='log(Y) (histogram)')
        >>> ax.legend()
        >>> plt.show()

    logser = <scipy.stats._discrete_distns.logser_gen object>
        A Logarithmic (Log-Series, Series) discrete random variable.

        As an instance of the `rv_discrete` class, `logser` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(p, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, p, loc=0)
            Probability mass function.
        logpmf(k, p, loc=0)
            Log of the probability mass function.
        cdf(k, p, loc=0)
            Cumulative distribution function.
        logcdf(k, p, loc=0)
            Log of the cumulative distribution function.
        sf(k, p, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, p, loc=0)
            Log of the survival function.
        ppf(q, p, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, p, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(p, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(p, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(p,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(p, loc=0)
            Median of the distribution.
        mean(p, loc=0)
            Mean of the distribution.
        var(p, loc=0)
            Variance of the distribution.
        std(p, loc=0)
            Standard deviation of the distribution.
        interval(confidence, p, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `logser` is:

        .. math::

            f(k) = - \frac{p^k}{k \log(1-p)}

        for :math:`k \ge 1`, :math:`0 < p < 1`

        `logser` takes :math:`p` as shape parameter,
        where :math:`p` is the probability of a single success
        and :math:`1-p` is the probability of a single failure.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``logser.pmf(k, p, loc)`` is identically
        equivalent to ``logser.pmf(k - loc, p)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import logser
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> p = 0.6
        >>> mean, var, skew, kurt = logser.stats(p, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(logser.ppf(0.01, p),
        ...               logser.ppf(0.99, p))
        >>> ax.plot(x, logser.pmf(x, p), 'bo', ms=8, label='logser pmf')
        >>> ax.vlines(x, 0, logser.pmf(x, p), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = logser(p)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = logser.cdf(x, p)
        >>> np.allclose(x, logser.ppf(prob, p))
        True

        Generate random numbers:

        >>> r = logser.rvs(p, size=1000)

    loguniform = <scipy.stats._continuous_distns.reciprocal_gen object>
        A loguniform or reciprocal continuous random variable.

        As an instance of the `rv_continuous` class, `loguniform` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for this class is:

        .. math::

            f(x, a, b) = \frac{1}{x \log(b/a)}

        for :math:`a \le x \le b`, :math:`b > a > 0`. This class takes
        :math:`a` and :math:`b` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``loguniform.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``loguniform.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import loguniform
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 0.01, 1.25
        >>> mean, var, skew, kurt = loguniform.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(loguniform.ppf(0.01, a, b),
        ...                 loguniform.ppf(0.99, a, b), 100)
        >>> ax.plot(x, loguniform.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='loguniform pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = loguniform(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = loguniform.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], loguniform.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = loguniform.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        This doesn't show the equal probability of ``0.01``, ``0.1`` and
        ``1``. This is best when the x-axis is log-scaled:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.hist(np.log10(r))
        >>> ax.set_ylabel("Frequency")
        >>> ax.set_xlabel("Value of random variable")
        >>> ax.xaxis.set_major_locator(plt.FixedLocator([-2, -1, 0]))
        >>> ticks = ["$10^{{ {} }}$".format(i) for i in [-2, -1, 0]]
        >>> ax.set_xticklabels(ticks)  # doctest: +SKIP
        >>> plt.show()

        This random variable will be log-uniform regardless of the base chosen for
        ``a`` and ``b``. Let's specify with base ``2`` instead:

        >>> rvs = loguniform(2**-2, 2**0).rvs(size=1000)

        Values of ``1/4``, ``1/2`` and ``1`` are equally likely with this random
        variable.  Here's the histogram:

        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.hist(np.log2(rvs))
        >>> ax.set_ylabel("Frequency")
        >>> ax.set_xlabel("Value of random variable")
        >>> ax.xaxis.set_major_locator(plt.FixedLocator([-2, -1, 0]))
        >>> ticks = ["$2^{{ {} }}$".format(i) for i in [-2, -1, 0]]
        >>> ax.set_xticklabels(ticks)  # doctest: +SKIP
        >>> plt.show()

    lomax = <scipy.stats._continuous_distns.lomax_gen object>
        A Lomax (Pareto of the second kind) continuous random variable.

        As an instance of the `rv_continuous` class, `lomax` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `lomax` is:

        .. math::

            f(x, c) = \frac{c}{(1+x)^{c+1}}

        for :math:`x \ge 0`, :math:`c > 0`.

        `lomax` takes ``c`` as a shape parameter for :math:`c`.

        `lomax` is a special case of `pareto` with ``loc=-1.0``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``lomax.pdf(x, c, loc, scale)`` is identically
        equivalent to ``lomax.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import lomax
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 1.88
        >>> mean, var, skew, kurt = lomax.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(lomax.ppf(0.01, c),
        ...                 lomax.ppf(0.99, c), 100)
        >>> ax.plot(x, lomax.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='lomax pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = lomax(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = lomax.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], lomax.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = lomax.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    matrix_normal = <scipy.stats._multivariate.matrix_normal_gen object>
        A matrix normal random variable.

        The `mean` keyword specifies the mean. The `rowcov` keyword specifies the
        among-row covariance matrix. The 'colcov' keyword specifies the
        among-column covariance matrix.

        Methods
        -------
        pdf(X, mean=None, rowcov=1, colcov=1)
            Probability density function.
        logpdf(X, mean=None, rowcov=1, colcov=1)
            Log of the probability density function.
        rvs(mean=None, rowcov=1, colcov=1, size=1, random_state=None)
            Draw random samples.
        entropy(rowcol=1, colcov=1)
            Differential entropy.

        Parameters
        ----------
        mean : array_like, optional
            Mean of the distribution (default: `None`)
        rowcov : array_like, optional
            Among-row covariance matrix of the distribution (default: `1`)
        colcov : array_like, optional
            Among-column covariance matrix of the distribution (default: `1`)
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        If `mean` is set to `None` then a matrix of zeros is used for the mean.
        The dimensions of this matrix are inferred from the shape of `rowcov` and
        `colcov`, if these are provided, or set to `1` if ambiguous.

        `rowcov` and `colcov` can be two-dimensional array_likes specifying the
        covariance matrices directly. Alternatively, a one-dimensional array will
        be be interpreted as the entries of a diagonal matrix, and a scalar or
        zero-dimensional array will be interpreted as this value times the
        identity matrix.

        The covariance matrices specified by `rowcov` and `colcov` must be
        (symmetric) positive definite. If the samples in `X` are
        :math:`m \times n`, then `rowcov` must be :math:`m \times m` and
        `colcov` must be :math:`n \times n`. `mean` must be the same shape as `X`.

        The probability density function for `matrix_normal` is

        .. math::

            f(X) = (2 \pi)^{-\frac{mn}{2}}|U|^{-\frac{n}{2}} |V|^{-\frac{m}{2}}
                   \exp\left( -\frac{1}{2} \mathrm{Tr}\left[ U^{-1} (X-M) V^{-1}
                   (X-M)^T \right] \right),

        where :math:`M` is the mean, :math:`U` the among-row covariance matrix,
        :math:`V` the among-column covariance matrix.

        The `allow_singular` behaviour of the `multivariate_normal`
        distribution is not currently supported. Covariance matrices must be
        full rank.

        The `matrix_normal` distribution is closely related to the
        `multivariate_normal` distribution. Specifically, :math:`\mathrm{Vec}(X)`
        (the vector formed by concatenating the columns  of :math:`X`) has a
        multivariate normal distribution with mean :math:`\mathrm{Vec}(M)`
        and covariance :math:`V \otimes U` (where :math:`\otimes` is the Kronecker
        product). Sampling and pdf evaluation are
        :math:`\mathcal{O}(m^3 + n^3 + m^2 n + m n^2)` for the matrix normal, but
        :math:`\mathcal{O}(m^3 n^3)` for the equivalent multivariate normal,
        making this equivalent form algorithmically inefficient.

        .. versionadded:: 0.17.0

        Examples
        --------

        >>> import numpy as np
        >>> from scipy.stats import matrix_normal

        >>> M = np.arange(6).reshape(3,2); M
        array([[0, 1],
               [2, 3],
               [4, 5]])
        >>> U = np.diag([1,2,3]); U
        array([[1, 0, 0],
               [0, 2, 0],
               [0, 0, 3]])
        >>> V = 0.3*np.identity(2); V
        array([[ 0.3,  0. ],
               [ 0. ,  0.3]])
        >>> X = M + 0.1; X
        array([[ 0.1,  1.1],
               [ 2.1,  3.1],
               [ 4.1,  5.1]])
        >>> matrix_normal.pdf(X, mean=M, rowcov=U, colcov=V)
        0.023410202050005054

        >>> # Equivalent multivariate normal
        >>> from scipy.stats import multivariate_normal
        >>> vectorised_X = X.T.flatten()
        >>> equiv_mean = M.T.flatten()
        >>> equiv_cov = np.kron(V,U)
        >>> multivariate_normal.pdf(vectorised_X, mean=equiv_mean, cov=equiv_cov)
        0.023410202050005054

        Alternatively, the object may be called (as a function) to fix the mean
        and covariance parameters, returning a "frozen" matrix normal
        random variable:

        >>> rv = matrix_normal(mean=None, rowcov=1, colcov=1)
        >>> # Frozen object with the same methods but holding the given
        >>> # mean and covariance fixed.

    maxwell = <scipy.stats._continuous_distns.maxwell_gen object>
        A Maxwell continuous random variable.

        As an instance of the `rv_continuous` class, `maxwell` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        A special case of a `chi` distribution,  with ``df=3``, ``loc=0.0``,
        and given ``scale = a``, where ``a`` is the parameter used in the
        Mathworld description [1]_.

        The probability density function for `maxwell` is:

        .. math::

            f(x) = \sqrt{2/\pi}x^2 \exp(-x^2/2)

        for :math:`x >= 0`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``maxwell.pdf(x, loc, scale)`` is identically
        equivalent to ``maxwell.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] http://mathworld.wolfram.com/MaxwellDistribution.html

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import maxwell
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = maxwell.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(maxwell.ppf(0.01),
        ...                 maxwell.ppf(0.99), 100)
        >>> ax.plot(x, maxwell.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='maxwell pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = maxwell()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = maxwell.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], maxwell.cdf(vals))
        True

        Generate random numbers:

        >>> r = maxwell.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    mielke = <scipy.stats._continuous_distns.mielke_gen object>
        A Mielke Beta-Kappa / Dagum continuous random variable.

        As an instance of the `rv_continuous` class, `mielke` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(k, s, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, k, s, loc=0, scale=1)
            Probability density function.
        logpdf(x, k, s, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, k, s, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, k, s, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, k, s, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, k, s, loc=0, scale=1)
            Log of the survival function.
        ppf(q, k, s, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, k, s, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, k, s, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(k, s, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(k, s, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(k, s), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(k, s, loc=0, scale=1)
            Median of the distribution.
        mean(k, s, loc=0, scale=1)
            Mean of the distribution.
        var(k, s, loc=0, scale=1)
            Variance of the distribution.
        std(k, s, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, k, s, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `mielke` is:

        .. math::

            f(x, k, s) = \frac{k x^{k-1}}{(1+x^s)^{1+k/s}}

        for :math:`x > 0` and :math:`k, s > 0`. The distribution is sometimes
        called Dagum distribution ([2]_). It was already defined in [3]_, called
        a Burr Type III distribution (`burr` with parameters ``c=s`` and
        ``d=k/s``).

        `mielke` takes ``k`` and ``s`` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``mielke.pdf(x, k, s, loc, scale)`` is identically
        equivalent to ``mielke.pdf(y, k, s) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Mielke, P.W., 1973 "Another Family of Distributions for Describing
               and Analyzing Precipitation Data." J. Appl. Meteor., 12, 275-280
        .. [2] Dagum, C., 1977 "A new model for personal income distribution."
               Economie Appliquee, 33, 327-367.
        .. [3] Burr, I. W. "Cumulative frequency functions", Annals of
               Mathematical Statistics, 13(2), pp 215-232 (1942).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import mielke
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> k, s = 10.4, 4.6
        >>> mean, var, skew, kurt = mielke.stats(k, s, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(mielke.ppf(0.01, k, s),
        ...                 mielke.ppf(0.99, k, s), 100)
        >>> ax.plot(x, mielke.pdf(x, k, s),
        ...        'r-', lw=5, alpha=0.6, label='mielke pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = mielke(k, s)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = mielke.ppf([0.001, 0.5, 0.999], k, s)
        >>> np.allclose([0.001, 0.5, 0.999], mielke.cdf(vals, k, s))
        True

        Generate random numbers:

        >>> r = mielke.rvs(k, s, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    moyal = <scipy.stats._continuous_distns.moyal_gen object>
        A Moyal continuous random variable.

        As an instance of the `rv_continuous` class, `moyal` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `moyal` is:

        .. math::

            f(x) = \exp(-(x + \exp(-x))/2) / \sqrt{2\pi}

        for a real number :math:`x`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``moyal.pdf(x, loc, scale)`` is identically
        equivalent to ``moyal.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        This distribution has utility in high-energy physics and radiation
        detection. It describes the energy loss of a charged relativistic
        particle due to ionization of the medium [1]_. It also provides an
        approximation for the Landau distribution. For an in depth description
        see [2]_. For additional description, see [3]_.

        References
        ----------
        .. [1] J.E. Moyal, "XXX. Theory of ionization fluctuations",
               The London, Edinburgh, and Dublin Philosophical Magazine
               and Journal of Science, vol 46, 263-280, (1955).
               :doi:`10.1080/14786440308521076` (gated)
        .. [2] G. Cordeiro et al., "The beta Moyal: a useful skew distribution",
               International Journal of Research and Reviews in Applied Sciences,
               vol 10, 171-192, (2012).
               http://www.arpapress.com/Volumes/Vol10Issue2/IJRRAS_10_2_02.pdf
        .. [3] C. Walck, "Handbook on Statistical Distributions for
               Experimentalists; International Report SUF-PFY/96-01", Chapter 26,
               University of Stockholm: Stockholm, Sweden, (2007).
               http://www.stat.rice.edu/~dobelman/textfiles/DistributionsHandbook.pdf

        .. versionadded:: 1.1.0

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import moyal
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = moyal.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(moyal.ppf(0.01),
        ...                 moyal.ppf(0.99), 100)
        >>> ax.plot(x, moyal.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='moyal pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = moyal()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = moyal.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], moyal.cdf(vals))
        True

        Generate random numbers:

        >>> r = moyal.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    multinomial = <scipy.stats._multivariate.multinomial_gen object>
        A multinomial random variable.

        Methods
        -------
        pmf(x, n, p)
            Probability mass function.
        logpmf(x, n, p)
            Log of the probability mass function.
        rvs(n, p, size=1, random_state=None)
            Draw random samples from a multinomial distribution.
        entropy(n, p)
            Compute the entropy of the multinomial distribution.
        cov(n, p)
            Compute the covariance matrix of the multinomial distribution.

        Parameters
        ----------
        n : int
            Number of trials
        p : array_like
            Probability of a trial falling into each category; should sum to 1
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        `n` should be a nonnegative integer. Each element of `p` should be in the
        interval :math:`[0,1]` and the elements should sum to 1. If they do not sum to
        1, the last element of the `p` array is not used and is replaced with the
        remaining probability left over from the earlier elements.

        The probability mass function for `multinomial` is

        .. math::

            f(x) = \frac{n!}{x_1! \cdots x_k!} p_1^{x_1} \cdots p_k^{x_k},

        supported on :math:`x=(x_1, \ldots, x_k)` where each :math:`x_i` is a
        nonnegative integer and their sum is :math:`n`.

        .. versionadded:: 0.19.0

        Examples
        --------

        >>> from scipy.stats import multinomial
        >>> rv = multinomial(8, [0.3, 0.2, 0.5])
        >>> rv.pmf([1, 3, 4])
        0.042000000000000072

        The multinomial distribution for :math:`k=2` is identical to the
        corresponding binomial distribution (tiny numerical differences
        notwithstanding):

        >>> from scipy.stats import binom
        >>> multinomial.pmf([3, 4], n=7, p=[0.4, 0.6])
        0.29030399999999973
        >>> binom.pmf(3, 7, 0.4)
        0.29030400000000012

        The functions ``pmf``, ``logpmf``, ``entropy``, and ``cov`` support
        broadcasting, under the convention that the vector parameters (``x`` and
        ``p``) are interpreted as if each row along the last axis is a single
        object. For instance:

        >>> multinomial.pmf([[3, 4], [3, 5]], n=[7, 8], p=[.3, .7])
        array([0.2268945,  0.25412184])

        Here, ``x.shape == (2, 2)``, ``n.shape == (2,)``, and ``p.shape == (2,)``,
        but following the rules mentioned above they behave as if the rows
        ``[3, 4]`` and ``[3, 5]`` in ``x`` and ``[.3, .7]`` in ``p`` were a single
        object, and as if we had ``x.shape = (2,)``, ``n.shape = (2,)``, and
        ``p.shape = ()``. To obtain the individual elements without broadcasting,
        we would do this:

        >>> multinomial.pmf([3, 4], n=7, p=[.3, .7])
        0.2268945
        >>> multinomial.pmf([3, 5], 8, p=[.3, .7])
        0.25412184

        This broadcasting also works for ``cov``, where the output objects are
        square matrices of size ``p.shape[-1]``. For example:

        >>> multinomial.cov([4, 5], [[.3, .7], [.4, .6]])
        array([[[ 0.84, -0.84],
                [-0.84,  0.84]],
               [[ 1.2 , -1.2 ],
                [-1.2 ,  1.2 ]]])

        In this example, ``n.shape == (2,)`` and ``p.shape == (2, 2)``, and
        following the rules above, these broadcast as if ``p.shape == (2,)``.
        Thus the result should also be of shape ``(2,)``, but since each output is
        a :math:`2 \times 2` matrix, the result in fact has shape ``(2, 2, 2)``,
        where ``result[0]`` is equal to ``multinomial.cov(n=4, p=[.3, .7])`` and
        ``result[1]`` is equal to ``multinomial.cov(n=5, p=[.4, .6])``.

        Alternatively, the object may be called (as a function) to fix the `n` and
        `p` parameters, returning a "frozen" multinomial random variable:

        >>> rv = multinomial(n=7, p=[.3, .7])
        >>> # Frozen object with the same methods but holding the given
        >>> # degrees of freedom and scale fixed.

        See also
        --------
        scipy.stats.binom : The binomial distribution.
        numpy.random.Generator.multinomial : Sampling from the multinomial distribution.
        scipy.stats.multivariate_hypergeom :
            The multivariate hypergeometric distribution.

    multivariate_hypergeom = <scipy.stats._multivariate.multivariate_hyper...
        A multivariate hypergeometric random variable.

        Methods
        -------
        pmf(x, m, n)
            Probability mass function.
        logpmf(x, m, n)
            Log of the probability mass function.
        rvs(m, n, size=1, random_state=None)
            Draw random samples from a multivariate hypergeometric
            distribution.
        mean(m, n)
            Mean of the multivariate hypergeometric distribution.
        var(m, n)
            Variance of the multivariate hypergeometric distribution.
        cov(m, n)
            Compute the covariance matrix of the multivariate
            hypergeometric distribution.

        Parameters
        ----------
        m : array_like
            The number of each type of object in the population.
            That is, :math:`m[i]` is the number of objects of
            type :math:`i`.
        n : array_like
            The number of samples taken from the population.
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        `m` must be an array of positive integers. If the quantile
        :math:`i` contains values out of the range :math:`[0, m_i]`
        where :math:`m_i` is the number of objects of type :math:`i`
        in the population or if the parameters are inconsistent with one
        another (e.g. ``x.sum() != n``), methods return the appropriate
        value (e.g. ``0`` for ``pmf``). If `m` or `n` contain negative
        values, the result will contain ``nan`` there.

        The probability mass function for `multivariate_hypergeom` is

        .. math::

            P(X_1 = x_1, X_2 = x_2, \ldots, X_k = x_k) = \frac{\binom{m_1}{x_1}
            \binom{m_2}{x_2} \cdots \binom{m_k}{x_k}}{\binom{M}{n}}, \\ \quad
            (x_1, x_2, \ldots, x_k) \in \mathbb{N}^k \text{ with }
            \sum_{i=1}^k x_i = n

        where :math:`m_i` are the number of objects of type :math:`i`, :math:`M`
        is the total number of objects in the population (sum of all the
        :math:`m_i`), and :math:`n` is the size of the sample to be taken
        from the population.

        .. versionadded:: 1.6.0

        Examples
        --------
        To evaluate the probability mass function of the multivariate
        hypergeometric distribution, with a dichotomous population of size
        :math:`10` and :math:`20`, at a sample of size :math:`12` with
        :math:`8` objects of the first type and :math:`4` objects of the
        second type, use:

        >>> from scipy.stats import multivariate_hypergeom
        >>> multivariate_hypergeom.pmf(x=[8, 4], m=[10, 20], n=12)
        0.0025207176631464523

        The `multivariate_hypergeom` distribution is identical to the
        corresponding `hypergeom` distribution (tiny numerical differences
        notwithstanding) when only two types (good and bad) of objects
        are present in the population as in the example above. Consider
        another example for a comparison with the hypergeometric distribution:

        >>> from scipy.stats import hypergeom
        >>> multivariate_hypergeom.pmf(x=[3, 1], m=[10, 5], n=4)
        0.4395604395604395
        >>> hypergeom.pmf(k=3, M=15, n=4, N=10)
        0.43956043956044005

        The functions ``pmf``, ``logpmf``, ``mean``, ``var``, ``cov``, and ``rvs``
        support broadcasting, under the convention that the vector parameters
        (``x``, ``m``, and ``n``) are interpreted as if each row along the last
        axis is a single object. For instance, we can combine the previous two
        calls to `multivariate_hypergeom` as

        >>> multivariate_hypergeom.pmf(x=[[8, 4], [3, 1]], m=[[10, 20], [10, 5]],
        ...                            n=[12, 4])
        array([0.00252072, 0.43956044])

        This broadcasting also works for ``cov``, where the output objects are
        square matrices of size ``m.shape[-1]``. For example:

        >>> multivariate_hypergeom.cov(m=[[7, 9], [10, 15]], n=[8, 12])
        array([[[ 1.05, -1.05],
                [-1.05,  1.05]],
               [[ 1.56, -1.56],
                [-1.56,  1.56]]])

        That is, ``result[0]`` is equal to
        ``multivariate_hypergeom.cov(m=[7, 9], n=8)`` and ``result[1]`` is equal
        to ``multivariate_hypergeom.cov(m=[10, 15], n=12)``.

        Alternatively, the object may be called (as a function) to fix the `m`
        and `n` parameters, returning a "frozen" multivariate hypergeometric
        random variable.

        >>> rv = multivariate_hypergeom(m=[10, 20], n=12)
        >>> rv.pmf(x=[8, 4])
        0.0025207176631464523

        See Also
        --------
        scipy.stats.hypergeom : The hypergeometric distribution.
        scipy.stats.multinomial : The multinomial distribution.

        References
        ----------
        .. [1] The Multivariate Hypergeometric Distribution,
               http://www.randomservices.org/random/urn/MultiHypergeometric.html
        .. [2] Thomas J. Sargent and John Stachurski, 2020,
               Multivariate Hypergeometric Distribution
               https://python.quantecon.org/multi_hyper.html

    multivariate_normal = <scipy.stats._multivariate.multivariate_normal_g...
        A multivariate normal random variable.

        The `mean` keyword specifies the mean. The `cov` keyword specifies the
        covariance matrix.

        Methods
        -------
        pdf(x, mean=None, cov=1, allow_singular=False)
            Probability density function.
        logpdf(x, mean=None, cov=1, allow_singular=False)
            Log of the probability density function.
        cdf(x, mean=None, cov=1, allow_singular=False, maxpts=1000000*dim, abseps=1e-5, releps=1e-5, lower_limit=None)
            Cumulative distribution function.
        logcdf(x, mean=None, cov=1, allow_singular=False, maxpts=1000000*dim, abseps=1e-5, releps=1e-5)
            Log of the cumulative distribution function.
        rvs(mean=None, cov=1, size=1, random_state=None)
            Draw random samples from a multivariate normal distribution.
        entropy(mean=None, cov=1)
            Compute the differential entropy of the multivariate normal.
        fit(x, fix_mean=None, fix_cov=None)
            Fit a multivariate normal distribution to data.

        Parameters
        ----------
        mean : array_like, default: ``[0]``
            Mean of the distribution.
        cov : array_like or `Covariance`, default: ``[1]``
            Symmetric positive (semi)definite covariance matrix of the distribution.
        allow_singular : bool, default: ``False``
            Whether to allow a singular covariance matrix. This is ignored if `cov` is
            a `Covariance` object.
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        Setting the parameter `mean` to `None` is equivalent to having `mean`
        be the zero-vector. The parameter `cov` can be a scalar, in which case
        the covariance matrix is the identity times that value, a vector of
        diagonal entries for the covariance matrix, a two-dimensional array_like,
        or a `Covariance` object.

        The covariance matrix `cov` may be an instance of a subclass of
        `Covariance`, e.g. `scipy.stats.CovViaPrecision`. If so, `allow_singular`
        is ignored.

        Otherwise, `cov` must be a symmetric positive semidefinite
        matrix when `allow_singular` is True; it must be (strictly) positive
        definite when `allow_singular` is False.
        Symmetry is not checked; only the lower triangular portion is used.
        The determinant and inverse of `cov` are computed
        as the pseudo-determinant and pseudo-inverse, respectively, so
        that `cov` does not need to have full rank.

        The probability density function for `multivariate_normal` is

        .. math::

            f(x) = \frac{1}{\sqrt{(2 \pi)^k \det \Sigma}}
                   \exp\left( -\frac{1}{2} (x - \mu)^T \Sigma^{-1} (x - \mu) \right),

        where :math:`\mu` is the mean, :math:`\Sigma` the covariance matrix,
        :math:`k` the rank of :math:`\Sigma`. In case of singular :math:`\Sigma`,
        SciPy extends this definition according to [1]_.

        .. versionadded:: 0.14.0

        References
        ----------
        .. [1] Multivariate Normal Distribution - Degenerate Case, Wikipedia,
               https://en.wikipedia.org/wiki/Multivariate_normal_distribution#Degenerate_case

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import multivariate_normal

        >>> x = np.linspace(0, 5, 10, endpoint=False)
        >>> y = multivariate_normal.pdf(x, mean=2.5, cov=0.5); y
        array([ 0.00108914,  0.01033349,  0.05946514,  0.20755375,  0.43939129,
                0.56418958,  0.43939129,  0.20755375,  0.05946514,  0.01033349])
        >>> fig1 = plt.figure()
        >>> ax = fig1.add_subplot(111)
        >>> ax.plot(x, y)
        >>> plt.show()

        Alternatively, the object may be called (as a function) to fix the mean
        and covariance parameters, returning a "frozen" multivariate normal
        random variable:

        >>> rv = multivariate_normal(mean=None, cov=1, allow_singular=False)
        >>> # Frozen object with the same methods but holding the given
        >>> # mean and covariance fixed.

        The input quantiles can be any shape of array, as long as the last
        axis labels the components.  This allows us for instance to
        display the frozen pdf for a non-isotropic random variable in 2D as
        follows:

        >>> x, y = np.mgrid[-1:1:.01, -1:1:.01]
        >>> pos = np.dstack((x, y))
        >>> rv = multivariate_normal([0.5, -0.2], [[2.0, 0.3], [0.3, 0.5]])
        >>> fig2 = plt.figure()
        >>> ax2 = fig2.add_subplot(111)
        >>> ax2.contourf(x, y, rv.pdf(pos))

    multivariate_t = <scipy.stats._multivariate.multivariate_t_gen object>
        A multivariate t-distributed random variable.

        The `loc` parameter specifies the location. The `shape` parameter specifies
        the positive semidefinite shape matrix. The `df` parameter specifies the
        degrees of freedom.

        In addition to calling the methods below, the object itself may be called
        as a function to fix the location, shape matrix, and degrees of freedom
        parameters, returning a "frozen" multivariate t-distribution random.

        Methods
        -------
        pdf(x, loc=None, shape=1, df=1, allow_singular=False)
            Probability density function.
        logpdf(x, loc=None, shape=1, df=1, allow_singular=False)
            Log of the probability density function.
        cdf(x, loc=None, shape=1, df=1, allow_singular=False, *,
            maxpts=None, lower_limit=None, random_state=None)
            Cumulative distribution function.
        rvs(loc=None, shape=1, df=1, size=1, random_state=None)
            Draw random samples from a multivariate t-distribution.
        entropy(loc=None, shape=1, df=1)
            Differential entropy of a multivariate t-distribution.

        Parameters
        ----------
        loc : array_like, optional
            Location of the distribution. (default ``0``)
        shape : array_like, optional
            Positive semidefinite matrix of the distribution. (default ``1``)
        df : float, optional
            Degrees of freedom of the distribution; must be greater than zero.
            If ``np.inf`` then results are multivariate normal. The default is ``1``.
        allow_singular : bool, optional
            Whether to allow a singular matrix. (default ``False``)
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Notes
        -----
        Setting the parameter `loc` to ``None`` is equivalent to having `loc`
        be the zero-vector. The parameter `shape` can be a scalar, in which case
        the shape matrix is the identity times that value, a vector of
        diagonal entries for the shape matrix, or a two-dimensional array_like.
        The matrix `shape` must be a (symmetric) positive semidefinite matrix. The
        determinant and inverse of `shape` are computed as the pseudo-determinant
        and pseudo-inverse, respectively, so that `shape` does not need to have
        full rank.

        The probability density function for `multivariate_t` is

        .. math::

            f(x) = \frac{\Gamma((\nu + p)/2)}{\Gamma(\nu/2)\nu^{p/2}\pi^{p/2}|\Sigma|^{1/2}}
                   \left[1 + \frac{1}{\nu} (\mathbf{x} - \boldsymbol{\mu})^{\top}
                   \boldsymbol{\Sigma}^{-1}
                   (\mathbf{x} - \boldsymbol{\mu}) \right]^{-(\nu + p)/2},

        where :math:`p` is the dimension of :math:`\mathbf{x}`,
        :math:`\boldsymbol{\mu}` is the :math:`p`-dimensional location,
        :math:`\boldsymbol{\Sigma}` the :math:`p \times p`-dimensional shape
        matrix, and :math:`\nu` is the degrees of freedom.

        .. versionadded:: 1.6.0

        References
        ----------
        .. [1] Arellano-Valle et al. "Shannon Entropy and Mutual Information for
               Multivariate Skew-Elliptical Distributions". Scandinavian Journal
               of Statistics. Vol. 40, issue 1.

        Examples
        --------
        The object may be called (as a function) to fix the `loc`, `shape`,
        `df`, and `allow_singular` parameters, returning a "frozen"
        multivariate_t random variable:

        >>> import numpy as np
        >>> from scipy.stats import multivariate_t
        >>> rv = multivariate_t([1.0, -0.5], [[2.1, 0.3], [0.3, 1.5]], df=2)
        >>> # Frozen object with the same methods but holding the given location,
        >>> # scale, and degrees of freedom fixed.

        Create a contour plot of the PDF.

        >>> import matplotlib.pyplot as plt
        >>> x, y = np.mgrid[-1:3:.01, -2:1.5:.01]
        >>> pos = np.dstack((x, y))
        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.set_aspect('equal')
        >>> plt.contourf(x, y, rv.pdf(pos))

    nakagami = <scipy.stats._continuous_distns.nakagami_gen object>
        A Nakagami continuous random variable.

        As an instance of the `rv_continuous` class, `nakagami` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(nu, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, nu, loc=0, scale=1)
            Probability density function.
        logpdf(x, nu, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, nu, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, nu, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, nu, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, nu, loc=0, scale=1)
            Log of the survival function.
        ppf(q, nu, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, nu, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, nu, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(nu, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(nu, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(nu,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(nu, loc=0, scale=1)
            Median of the distribution.
        mean(nu, loc=0, scale=1)
            Mean of the distribution.
        var(nu, loc=0, scale=1)
            Variance of the distribution.
        std(nu, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, nu, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `nakagami` is:

        .. math::

            f(x, \nu) = \frac{2 \nu^\nu}{\Gamma(\nu)} x^{2\nu-1} \exp(-\nu x^2)

        for :math:`x >= 0`, :math:`\nu > 0`. The distribution was introduced in
        [2]_, see also [1]_ for further information.

        `nakagami` takes ``nu`` as a shape parameter for :math:`\nu`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``nakagami.pdf(x, nu, loc, scale)`` is identically
        equivalent to ``nakagami.pdf(y, nu) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] "Nakagami distribution", Wikipedia
               https://en.wikipedia.org/wiki/Nakagami_distribution
        .. [2] M. Nakagami, "The m-distribution - A general formula of intensity
               distribution of rapid fading", Statistical methods in radio wave
               propagation, Pergamon Press, 1960, 3-36.
               :doi:`10.1016/B978-0-08-009306-2.50005-4`

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nakagami
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> nu = 4.97
        >>> mean, var, skew, kurt = nakagami.stats(nu, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(nakagami.ppf(0.01, nu),
        ...                 nakagami.ppf(0.99, nu), 100)
        >>> ax.plot(x, nakagami.pdf(x, nu),
        ...        'r-', lw=5, alpha=0.6, label='nakagami pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = nakagami(nu)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = nakagami.ppf([0.001, 0.5, 0.999], nu)
        >>> np.allclose([0.001, 0.5, 0.999], nakagami.cdf(vals, nu))
        True

        Generate random numbers:

        >>> r = nakagami.rvs(nu, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    nbinom = <scipy.stats._discrete_distns.nbinom_gen object>
        A negative binomial discrete random variable.

        As an instance of the `rv_discrete` class, `nbinom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(n, p, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, n, p, loc=0)
            Probability mass function.
        logpmf(k, n, p, loc=0)
            Log of the probability mass function.
        cdf(k, n, p, loc=0)
            Cumulative distribution function.
        logcdf(k, n, p, loc=0)
            Log of the cumulative distribution function.
        sf(k, n, p, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, n, p, loc=0)
            Log of the survival function.
        ppf(q, n, p, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, n, p, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(n, p, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(n, p, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(n, p), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(n, p, loc=0)
            Median of the distribution.
        mean(n, p, loc=0)
            Mean of the distribution.
        var(n, p, loc=0)
            Variance of the distribution.
        std(n, p, loc=0)
            Standard deviation of the distribution.
        interval(confidence, n, p, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        Negative binomial distribution describes a sequence of i.i.d. Bernoulli
        trials, repeated until a predefined, non-random number of successes occurs.

        The probability mass function of the number of failures for `nbinom` is:

        .. math::

           f(k) = \binom{k+n-1}{n-1} p^n (1-p)^k

        for :math:`k \ge 0`, :math:`0 < p \leq 1`

        `nbinom` takes :math:`n` and :math:`p` as shape parameters where :math:`n`
        is the number of successes, :math:`p` is the probability of a single
        success, and :math:`1-p` is the probability of a single failure.

        Another common parameterization of the negative binomial distribution is
        in terms of the mean number of failures :math:`\mu` to achieve :math:`n`
        successes. The mean :math:`\mu` is related to the probability of success
        as

        .. math::

           p = \frac{n}{n + \mu}

        The number of successes :math:`n` may also be specified in terms of a
        "dispersion", "heterogeneity", or "aggregation" parameter :math:`\alpha`,
        which relates the mean :math:`\mu` to the variance :math:`\sigma^2`,
        e.g. :math:`\sigma^2 = \mu + \alpha \mu^2`. Regardless of the convention
        used for :math:`\alpha`,

        .. math::

           p &= \frac{\mu}{\sigma^2} \\
           n &= \frac{\mu^2}{\sigma^2 - \mu}

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``nbinom.pmf(k, n, p, loc)`` is identically
        equivalent to ``nbinom.pmf(k - loc, n, p)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nbinom
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> n, p = 5, 0.5
        >>> mean, var, skew, kurt = nbinom.stats(n, p, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(nbinom.ppf(0.01, n, p),
        ...               nbinom.ppf(0.99, n, p))
        >>> ax.plot(x, nbinom.pmf(x, n, p), 'bo', ms=8, label='nbinom pmf')
        >>> ax.vlines(x, 0, nbinom.pmf(x, n, p), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = nbinom(n, p)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = nbinom.cdf(x, n, p)
        >>> np.allclose(x, nbinom.ppf(prob, n, p))
        True

        Generate random numbers:

        >>> r = nbinom.rvs(n, p, size=1000)

        See Also
        --------
        hypergeom, binom, nhypergeom

    ncf = <scipy.stats._continuous_distns.ncf_gen object>
        A non-central F distribution continuous random variable.

        As an instance of the `rv_continuous` class, `ncf` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(dfn, dfd, nc, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, dfn, dfd, nc, loc=0, scale=1)
            Probability density function.
        logpdf(x, dfn, dfd, nc, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, dfn, dfd, nc, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, dfn, dfd, nc, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, dfn, dfd, nc, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, dfn, dfd, nc, loc=0, scale=1)
            Log of the survival function.
        ppf(q, dfn, dfd, nc, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, dfn, dfd, nc, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, dfn, dfd, nc, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(dfn, dfd, nc, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(dfn, dfd, nc, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(dfn, dfd, nc), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(dfn, dfd, nc, loc=0, scale=1)
            Median of the distribution.
        mean(dfn, dfd, nc, loc=0, scale=1)
            Mean of the distribution.
        var(dfn, dfd, nc, loc=0, scale=1)
            Variance of the distribution.
        std(dfn, dfd, nc, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, dfn, dfd, nc, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        scipy.stats.f : Fisher distribution

        Notes
        -----
        The probability density function for `ncf` is:

        .. math::

            f(x, n_1, n_2, \lambda) =
                \exp\left(\frac{\lambda}{2} +
                          \lambda n_1 \frac{x}{2(n_1 x + n_2)}
                    \right)
                n_1^{n_1/2} n_2^{n_2/2} x^{n_1/2 - 1} \\
                (n_2 + n_1 x)^{-(n_1 + n_2)/2}
                \gamma(n_1/2) \gamma(1 + n_2/2) \\
                \frac{L^{\frac{n_1}{2}-1}_{n_2/2}
                    \left(-\lambda n_1 \frac{x}{2(n_1 x + n_2)}\right)}
                {B(n_1/2, n_2/2)
                    \gamma\left(\frac{n_1 + n_2}{2}\right)}

        for :math:`n_1, n_2 > 0`, :math:`\lambda \ge 0`.  Here :math:`n_1` is the
        degrees of freedom in the numerator, :math:`n_2` the degrees of freedom in
        the denominator, :math:`\lambda` the non-centrality parameter,
        :math:`\gamma` is the logarithm of the Gamma function, :math:`L_n^k` is a
        generalized Laguerre polynomial and :math:`B` is the beta function.

        `ncf` takes ``df1``, ``df2`` and ``nc`` as shape parameters. If ``nc=0``,
        the distribution becomes equivalent to the Fisher distribution.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``ncf.pdf(x, dfn, dfd, nc, loc, scale)`` is identically
        equivalent to ``ncf.pdf(y, dfn, dfd, nc) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import ncf
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> dfn, dfd, nc = 27, 27, 0.416
        >>> mean, var, skew, kurt = ncf.stats(dfn, dfd, nc, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(ncf.ppf(0.01, dfn, dfd, nc),
        ...                 ncf.ppf(0.99, dfn, dfd, nc), 100)
        >>> ax.plot(x, ncf.pdf(x, dfn, dfd, nc),
        ...        'r-', lw=5, alpha=0.6, label='ncf pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = ncf(dfn, dfd, nc)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = ncf.ppf([0.001, 0.5, 0.999], dfn, dfd, nc)
        >>> np.allclose([0.001, 0.5, 0.999], ncf.cdf(vals, dfn, dfd, nc))
        True

        Generate random numbers:

        >>> r = ncf.rvs(dfn, dfd, nc, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    nchypergeom_fisher = <scipy.stats._discrete_distns.nchypergeom_fisher_...
        A Fisher's noncentral hypergeometric discrete random variable.

        Fisher's noncentral hypergeometric distribution models drawing objects of
        two types from a bin. `M` is the total number of objects, `n` is the
        number of Type I objects, and `odds` is the odds ratio: the odds of
        selecting a Type I object rather than a Type II object when there is only
        one object of each type.
        The random variate represents the number of Type I objects drawn if we
        take a handful of objects from the bin at once and find out afterwards
        that we took `N` objects.

        As an instance of the `rv_discrete` class, `nchypergeom_fisher` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(M, n, N, odds, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, M, n, N, odds, loc=0)
            Probability mass function.
        logpmf(k, M, n, N, odds, loc=0)
            Log of the probability mass function.
        cdf(k, M, n, N, odds, loc=0)
            Cumulative distribution function.
        logcdf(k, M, n, N, odds, loc=0)
            Log of the cumulative distribution function.
        sf(k, M, n, N, odds, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, M, n, N, odds, loc=0)
            Log of the survival function.
        ppf(q, M, n, N, odds, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, M, n, N, odds, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(M, n, N, odds, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(M, n, N, odds, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(M, n, N, odds), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(M, n, N, odds, loc=0)
            Median of the distribution.
        mean(M, n, N, odds, loc=0)
            Mean of the distribution.
        var(M, n, N, odds, loc=0)
            Variance of the distribution.
        std(M, n, N, odds, loc=0)
            Standard deviation of the distribution.
        interval(confidence, M, n, N, odds, loc=0)
            Confidence interval with equal areas around the median.

        See Also
        --------
        nchypergeom_wallenius, hypergeom, nhypergeom

        Notes
        -----
        Let mathematical symbols :math:`N`, :math:`n`, and :math:`M` correspond
        with parameters `N`, `n`, and `M` (respectively) as defined above.

        The probability mass function is defined as

        .. math::

            p(x; M, n, N, \omega) =
            \frac{\binom{n}{x}\binom{M - n}{N-x}\omega^x}{P_0},

        for
        :math:`x \in [x_l, x_u]`,
        :math:`M \in {\mathbb N}`,
        :math:`n \in [0, M]`,
        :math:`N \in [0, M]`,
        :math:`\omega > 0`,
        where
        :math:`x_l = \max(0, N - (M - n))`,
        :math:`x_u = \min(N, n)`,

        .. math::

            P_0 = \sum_{y=x_l}^{x_u} \binom{n}{y}\binom{M - n}{N-y}\omega^y,

        and the binomial coefficients are defined as

        .. math:: \binom{n}{k} \equiv \frac{n!}{k! (n - k)!}.

        `nchypergeom_fisher` uses the BiasedUrn package by Agner Fog with
        permission for it to be distributed under SciPy's license.

        The symbols used to denote the shape parameters (`N`, `n`, and `M`) are not
        universally accepted; they are chosen for consistency with `hypergeom`.

        Note that Fisher's noncentral hypergeometric distribution is distinct
        from Wallenius' noncentral hypergeometric distribution, which models
        drawing a pre-determined `N` objects from a bin one by one.
        When the odds ratio is unity, however, both distributions reduce to the
        ordinary hypergeometric distribution.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``nchypergeom_fisher.pmf(k, M, n, N, odds, loc)`` is identically
        equivalent to ``nchypergeom_fisher.pmf(k - loc, M, n, N, odds)``.

        References
        ----------
        .. [1] Agner Fog, "Biased Urn Theory".
               https://cran.r-project.org/web/packages/BiasedUrn/vignettes/UrnTheory.pdf

        .. [2] "Fisher's noncentral hypergeometric distribution", Wikipedia,
               https://en.wikipedia.org/wiki/Fisher's_noncentral_hypergeometric_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nchypergeom_fisher
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> M, n, N, odds = 140, 80, 60, 0.5
        >>> mean, var, skew, kurt = nchypergeom_fisher.stats(M, n, N, odds, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(nchypergeom_fisher.ppf(0.01, M, n, N, odds),
        ...               nchypergeom_fisher.ppf(0.99, M, n, N, odds))
        >>> ax.plot(x, nchypergeom_fisher.pmf(x, M, n, N, odds), 'bo', ms=8, label='nchypergeom_fisher pmf')
        >>> ax.vlines(x, 0, nchypergeom_fisher.pmf(x, M, n, N, odds), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = nchypergeom_fisher(M, n, N, odds)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = nchypergeom_fisher.cdf(x, M, n, N, odds)
        >>> np.allclose(x, nchypergeom_fisher.ppf(prob, M, n, N, odds))
        True

        Generate random numbers:

        >>> r = nchypergeom_fisher.rvs(M, n, N, odds, size=1000)

    nchypergeom_wallenius = <scipy.stats._discrete_distns.nchypergeom_wall...
        A Wallenius' noncentral hypergeometric discrete random variable.

        Wallenius' noncentral hypergeometric distribution models drawing objects of
        two types from a bin. `M` is the total number of objects, `n` is the
        number of Type I objects, and `odds` is the odds ratio: the odds of
        selecting a Type I object rather than a Type II object when there is only
        one object of each type.
        The random variate represents the number of Type I objects drawn if we
        draw a pre-determined `N` objects from a bin one by one.

        As an instance of the `rv_discrete` class, `nchypergeom_wallenius` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(M, n, N, odds, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, M, n, N, odds, loc=0)
            Probability mass function.
        logpmf(k, M, n, N, odds, loc=0)
            Log of the probability mass function.
        cdf(k, M, n, N, odds, loc=0)
            Cumulative distribution function.
        logcdf(k, M, n, N, odds, loc=0)
            Log of the cumulative distribution function.
        sf(k, M, n, N, odds, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, M, n, N, odds, loc=0)
            Log of the survival function.
        ppf(q, M, n, N, odds, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, M, n, N, odds, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(M, n, N, odds, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(M, n, N, odds, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(M, n, N, odds), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(M, n, N, odds, loc=0)
            Median of the distribution.
        mean(M, n, N, odds, loc=0)
            Mean of the distribution.
        var(M, n, N, odds, loc=0)
            Variance of the distribution.
        std(M, n, N, odds, loc=0)
            Standard deviation of the distribution.
        interval(confidence, M, n, N, odds, loc=0)
            Confidence interval with equal areas around the median.

        See Also
        --------
        nchypergeom_fisher, hypergeom, nhypergeom

        Notes
        -----
        Let mathematical symbols :math:`N`, :math:`n`, and :math:`M` correspond
        with parameters `N`, `n`, and `M` (respectively) as defined above.

        The probability mass function is defined as

        .. math::

            p(x; N, n, M) = \binom{n}{x} \binom{M - n}{N-x}
            \int_0^1 \left(1-t^{\omega/D}\right)^x\left(1-t^{1/D}\right)^{N-x} dt

        for
        :math:`x \in [x_l, x_u]`,
        :math:`M \in {\mathbb N}`,
        :math:`n \in [0, M]`,
        :math:`N \in [0, M]`,
        :math:`\omega > 0`,
        where
        :math:`x_l = \max(0, N - (M - n))`,
        :math:`x_u = \min(N, n)`,

        .. math::

            D = \omega(n - x) + ((M - n)-(N-x)),

        and the binomial coefficients are defined as

        .. math:: \binom{n}{k} \equiv \frac{n!}{k! (n - k)!}.

        `nchypergeom_wallenius` uses the BiasedUrn package by Agner Fog with
        permission for it to be distributed under SciPy's license.

        The symbols used to denote the shape parameters (`N`, `n`, and `M`) are not
        universally accepted; they are chosen for consistency with `hypergeom`.

        Note that Wallenius' noncentral hypergeometric distribution is distinct
        from Fisher's noncentral hypergeometric distribution, which models
        take a handful of objects from the bin at once, finding out afterwards
        that `N` objects were taken.
        When the odds ratio is unity, however, both distributions reduce to the
        ordinary hypergeometric distribution.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``nchypergeom_wallenius.pmf(k, M, n, N, odds, loc)`` is identically
        equivalent to ``nchypergeom_wallenius.pmf(k - loc, M, n, N, odds)``.

        References
        ----------
        .. [1] Agner Fog, "Biased Urn Theory".
               https://cran.r-project.org/web/packages/BiasedUrn/vignettes/UrnTheory.pdf

        .. [2] "Wallenius' noncentral hypergeometric distribution", Wikipedia,
               https://en.wikipedia.org/wiki/Wallenius'_noncentral_hypergeometric_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nchypergeom_wallenius
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> M, n, N, odds = 140, 80, 60, 0.5
        >>> mean, var, skew, kurt = nchypergeom_wallenius.stats(M, n, N, odds, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(nchypergeom_wallenius.ppf(0.01, M, n, N, odds),
        ...               nchypergeom_wallenius.ppf(0.99, M, n, N, odds))
        >>> ax.plot(x, nchypergeom_wallenius.pmf(x, M, n, N, odds), 'bo', ms=8, label='nchypergeom_wallenius pmf')
        >>> ax.vlines(x, 0, nchypergeom_wallenius.pmf(x, M, n, N, odds), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = nchypergeom_wallenius(M, n, N, odds)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = nchypergeom_wallenius.cdf(x, M, n, N, odds)
        >>> np.allclose(x, nchypergeom_wallenius.ppf(prob, M, n, N, odds))
        True

        Generate random numbers:

        >>> r = nchypergeom_wallenius.rvs(M, n, N, odds, size=1000)

    nct = <scipy.stats._continuous_distns.nct_gen object>
        A non-central Student's t continuous random variable.

        As an instance of the `rv_continuous` class, `nct` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(df, nc, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, df, nc, loc=0, scale=1)
            Probability density function.
        logpdf(x, df, nc, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, df, nc, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, df, nc, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, df, nc, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, df, nc, loc=0, scale=1)
            Log of the survival function.
        ppf(q, df, nc, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, df, nc, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, df, nc, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(df, nc, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(df, nc, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(df, nc), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(df, nc, loc=0, scale=1)
            Median of the distribution.
        mean(df, nc, loc=0, scale=1)
            Mean of the distribution.
        var(df, nc, loc=0, scale=1)
            Variance of the distribution.
        std(df, nc, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, df, nc, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        If :math:`Y` is a standard normal random variable and :math:`V` is
        an independent chi-square random variable (`chi2`) with :math:`k` degrees
        of freedom, then

        .. math::

            X = \frac{Y + c}{\sqrt{V/k}}

        has a non-central Student's t distribution on the real line.
        The degrees of freedom parameter :math:`k` (denoted ``df`` in the
        implementation) satisfies :math:`k > 0` and the noncentrality parameter
        :math:`c` (denoted ``nc`` in the implementation) is a real number.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``nct.pdf(x, df, nc, loc, scale)`` is identically
        equivalent to ``nct.pdf(y, df, nc) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nct
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> df, nc = 14, 0.24
        >>> mean, var, skew, kurt = nct.stats(df, nc, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(nct.ppf(0.01, df, nc),
        ...                 nct.ppf(0.99, df, nc), 100)
        >>> ax.plot(x, nct.pdf(x, df, nc),
        ...        'r-', lw=5, alpha=0.6, label='nct pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = nct(df, nc)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = nct.ppf([0.001, 0.5, 0.999], df, nc)
        >>> np.allclose([0.001, 0.5, 0.999], nct.cdf(vals, df, nc))
        True

        Generate random numbers:

        >>> r = nct.rvs(df, nc, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    ncx2 = <scipy.stats._continuous_distns.ncx2_gen object>
        A non-central chi-squared continuous random variable.

        As an instance of the `rv_continuous` class, `ncx2` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(df, nc, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, df, nc, loc=0, scale=1)
            Probability density function.
        logpdf(x, df, nc, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, df, nc, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, df, nc, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, df, nc, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, df, nc, loc=0, scale=1)
            Log of the survival function.
        ppf(q, df, nc, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, df, nc, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, df, nc, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(df, nc, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(df, nc, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(df, nc), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(df, nc, loc=0, scale=1)
            Median of the distribution.
        mean(df, nc, loc=0, scale=1)
            Mean of the distribution.
        var(df, nc, loc=0, scale=1)
            Variance of the distribution.
        std(df, nc, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, df, nc, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `ncx2` is:

        .. math::

            f(x, k, \lambda) = \frac{1}{2} \exp(-(\lambda+x)/2)
                (x/\lambda)^{(k-2)/4}  I_{(k-2)/2}(\sqrt{\lambda x})

        for :math:`x >= 0`, :math:`k > 0` and :math:`\lambda \ge 0`.
        :math:`k` specifies the degrees of freedom (denoted ``df`` in the
        implementation) and :math:`\lambda` is the non-centrality parameter
        (denoted ``nc`` in the implementation). :math:`I_\nu` denotes the
        modified Bessel function of first order of degree :math:`\nu`
        (`scipy.special.iv`).

        `ncx2` takes ``df`` and ``nc`` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``ncx2.pdf(x, df, nc, loc, scale)`` is identically
        equivalent to ``ncx2.pdf(y, df, nc) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import ncx2
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> df, nc = 21, 1.06
        >>> mean, var, skew, kurt = ncx2.stats(df, nc, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(ncx2.ppf(0.01, df, nc),
        ...                 ncx2.ppf(0.99, df, nc), 100)
        >>> ax.plot(x, ncx2.pdf(x, df, nc),
        ...        'r-', lw=5, alpha=0.6, label='ncx2 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = ncx2(df, nc)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = ncx2.ppf([0.001, 0.5, 0.999], df, nc)
        >>> np.allclose([0.001, 0.5, 0.999], ncx2.cdf(vals, df, nc))
        True

        Generate random numbers:

        >>> r = ncx2.rvs(df, nc, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    nhypergeom = <scipy.stats._discrete_distns.nhypergeom_gen object>
        A negative hypergeometric discrete random variable.

        Consider a box containing :math:`M` balls:, :math:`n` red and
        :math:`M-n` blue. We randomly sample balls from the box, one
        at a time and *without* replacement, until we have picked :math:`r`
        blue balls. `nhypergeom` is the distribution of the number of
        red balls :math:`k` we have picked.

        As an instance of the `rv_discrete` class, `nhypergeom` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(M, n, r, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, M, n, r, loc=0)
            Probability mass function.
        logpmf(k, M, n, r, loc=0)
            Log of the probability mass function.
        cdf(k, M, n, r, loc=0)
            Cumulative distribution function.
        logcdf(k, M, n, r, loc=0)
            Log of the cumulative distribution function.
        sf(k, M, n, r, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, M, n, r, loc=0)
            Log of the survival function.
        ppf(q, M, n, r, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, M, n, r, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(M, n, r, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(M, n, r, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(M, n, r), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(M, n, r, loc=0)
            Median of the distribution.
        mean(M, n, r, loc=0)
            Mean of the distribution.
        var(M, n, r, loc=0)
            Variance of the distribution.
        std(M, n, r, loc=0)
            Standard deviation of the distribution.
        interval(confidence, M, n, r, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The symbols used to denote the shape parameters (`M`, `n`, and `r`) are not
        universally accepted. See the Examples for a clarification of the
        definitions used here.

        The probability mass function is defined as,

        .. math:: f(k; M, n, r) = \frac{{{k+r-1}\choose{k}}{{M-r-k}\choose{n-k}}}
                                       {{M \choose n}}

        for :math:`k \in [0, n]`, :math:`n \in [0, M]`, :math:`r \in [0, M-n]`,
        and the binomial coefficient is:

        .. math:: \binom{n}{k} \equiv \frac{n!}{k! (n - k)!}.

        It is equivalent to observing :math:`k` successes in :math:`k+r-1`
        samples with :math:`k+r`'th sample being a failure. The former
        can be modelled as a hypergeometric distribution. The probability
        of the latter is simply the number of failures remaining
        :math:`M-n-(r-1)` divided by the size of the remaining population
        :math:`M-(k+r-1)`. This relationship can be shown as:

        .. math:: NHG(k;M,n,r) = HG(k;M,n,k+r-1)\frac{(M-n-(r-1))}{(M-(k+r-1))}

        where :math:`NHG` is probability mass function (PMF) of the
        negative hypergeometric distribution and :math:`HG` is the
        PMF of the hypergeometric distribution.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``nhypergeom.pmf(k, M, n, r, loc)`` is identically
        equivalent to ``nhypergeom.pmf(k - loc, M, n, r)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import nhypergeom
        >>> import matplotlib.pyplot as plt

        Suppose we have a collection of 20 animals, of which 7 are dogs.
        Then if we want to know the probability of finding a given number
        of dogs (successes) in a sample with exactly 12 animals that
        aren't dogs (failures), we can initialize a frozen distribution
        and plot the probability mass function:

        >>> M, n, r = [20, 7, 12]
        >>> rv = nhypergeom(M, n, r)
        >>> x = np.arange(0, n+2)
        >>> pmf_dogs = rv.pmf(x)

        >>> fig = plt.figure()
        >>> ax = fig.add_subplot(111)
        >>> ax.plot(x, pmf_dogs, 'bo')
        >>> ax.vlines(x, 0, pmf_dogs, lw=2)
        >>> ax.set_xlabel('# of dogs in our group with given 12 failures')
        >>> ax.set_ylabel('nhypergeom PMF')
        >>> plt.show()

        Instead of using a frozen distribution we can also use `nhypergeom`
        methods directly.  To for example obtain the probability mass
        function, use:

        >>> prb = nhypergeom.pmf(x, M, n, r)

        And to generate random numbers:

        >>> R = nhypergeom.rvs(M, n, r, size=10)

        To verify the relationship between `hypergeom` and `nhypergeom`, use:

        >>> from scipy.stats import hypergeom, nhypergeom
        >>> M, n, r = 45, 13, 8
        >>> k = 6
        >>> nhypergeom.pmf(k, M, n, r)
        0.06180776620271643
        >>> hypergeom.pmf(k, M, n, k+r-1) * (M - n - (r-1)) / (M - (k+r-1))
        0.06180776620271644

        See Also
        --------
        hypergeom, binom, nbinom

        References
        ----------
        .. [1] Negative Hypergeometric Distribution on Wikipedia
               https://en.wikipedia.org/wiki/Negative_hypergeometric_distribution

        .. [2] Negative Hypergeometric Distribution from
               http://www.math.wm.edu/~leemis/chart/UDR/PDFs/Negativehypergeometric.pdf

    norm = <scipy.stats._continuous_distns.norm_gen object>
        A normal continuous random variable.

        The location (``loc``) keyword specifies the mean.
        The scale (``scale``) keyword specifies the standard deviation.

        As an instance of the `rv_continuous` class, `norm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `norm` is:

        .. math::

            f(x) = \frac{\exp(-x^2/2)}{\sqrt{2\pi}}

        for a real number :math:`x`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``norm.pdf(x, loc, scale)`` is identically
        equivalent to ``norm.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import norm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = norm.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(norm.ppf(0.01),
        ...                 norm.ppf(0.99), 100)
        >>> ax.plot(x, norm.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='norm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = norm()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = norm.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], norm.cdf(vals))
        True

        Generate random numbers:

        >>> r = norm.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    norminvgauss = <scipy.stats._continuous_distns.norminvgauss_gen object...
        A Normal Inverse Gaussian continuous random variable.

        As an instance of the `rv_continuous` class, `norminvgauss` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `norminvgauss` is:

        .. math::

            f(x, a, b) = \frac{a \, K_1(a \sqrt{1 + x^2})}{\pi \sqrt{1 + x^2}} \,
                         \exp(\sqrt{a^2 - b^2} + b x)

        where :math:`x` is a real number, the parameter :math:`a` is the tail
        heaviness and :math:`b` is the asymmetry parameter satisfying
        :math:`a > 0` and :math:`|b| <= a`.
        :math:`K_1` is the modified Bessel function of second kind
        (`scipy.special.k1`).

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``norminvgauss.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``norminvgauss.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        A normal inverse Gaussian random variable `Y` with parameters `a` and `b`
        can be expressed as a normal mean-variance mixture:
        `Y = b * V + sqrt(V) * X` where `X` is `norm(0,1)` and `V` is
        `invgauss(mu=1/sqrt(a**2 - b**2))`. This representation is used
        to generate random variates.

        Another common parametrization of the distribution (see Equation 2.1 in
        [2]_) is given by the following expression of the pdf:

        .. math::

            g(x, \alpha, \beta, \delta, \mu) =
            \frac{\alpha\delta K_1\left(\alpha\sqrt{\delta^2 + (x - \mu)^2}\right)}
            {\pi \sqrt{\delta^2 + (x - \mu)^2}} \,
            e^{\delta \sqrt{\alpha^2 - \beta^2} + \beta (x - \mu)}

        In SciPy, this corresponds to
        `a = alpha * delta, b = beta * delta, loc = mu, scale=delta`.

        References
        ----------
        .. [1] O. Barndorff-Nielsen, "Hyperbolic Distributions and Distributions on
               Hyperbolae", Scandinavian Journal of Statistics, Vol. 5(3),
               pp. 151-157, 1978.

        .. [2] O. Barndorff-Nielsen, "Normal Inverse Gaussian Distributions and
               Stochastic Volatility Modelling", Scandinavian Journal of
               Statistics, Vol. 24, pp. 1-13, 1997.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import norminvgauss
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 1.25, 0.5
        >>> mean, var, skew, kurt = norminvgauss.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(norminvgauss.ppf(0.01, a, b),
        ...                 norminvgauss.ppf(0.99, a, b), 100)
        >>> ax.plot(x, norminvgauss.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='norminvgauss pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = norminvgauss(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = norminvgauss.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], norminvgauss.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = norminvgauss.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    ortho_group = <scipy.stats._multivariate.ortho_group_gen object>
    pareto = <scipy.stats._continuous_distns.pareto_gen object>
        A Pareto continuous random variable.

        As an instance of the `rv_continuous` class, `pareto` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(b,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(b, loc=0, scale=1)
            Median of the distribution.
        mean(b, loc=0, scale=1)
            Mean of the distribution.
        var(b, loc=0, scale=1)
            Variance of the distribution.
        std(b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `pareto` is:

        .. math::

            f(x, b) = \frac{b}{x^{b+1}}

        for :math:`x \ge 1`, :math:`b > 0`.

        `pareto` takes ``b`` as a shape parameter for :math:`b`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``pareto.pdf(x, b, loc, scale)`` is identically
        equivalent to ``pareto.pdf(y, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import pareto
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> b = 2.62
        >>> mean, var, skew, kurt = pareto.stats(b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(pareto.ppf(0.01, b),
        ...                 pareto.ppf(0.99, b), 100)
        >>> ax.plot(x, pareto.pdf(x, b),
        ...        'r-', lw=5, alpha=0.6, label='pareto pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = pareto(b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = pareto.ppf([0.001, 0.5, 0.999], b)
        >>> np.allclose([0.001, 0.5, 0.999], pareto.cdf(vals, b))
        True

        Generate random numbers:

        >>> r = pareto.rvs(b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    pearson3 = <scipy.stats._continuous_distns.pearson3_gen object>
        A pearson type III continuous random variable.

        As an instance of the `rv_continuous` class, `pearson3` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(skew, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, skew, loc=0, scale=1)
            Probability density function.
        logpdf(x, skew, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, skew, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, skew, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, skew, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, skew, loc=0, scale=1)
            Log of the survival function.
        ppf(q, skew, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, skew, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, skew, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(skew, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(skew, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(skew,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(skew, loc=0, scale=1)
            Median of the distribution.
        mean(skew, loc=0, scale=1)
            Mean of the distribution.
        var(skew, loc=0, scale=1)
            Variance of the distribution.
        std(skew, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, skew, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `pearson3` is:

        .. math::

            f(x, \kappa) = \frac{|\beta|}{\Gamma(\alpha)}
                           (\beta (x - \zeta))^{\alpha - 1}
                           \exp(-\beta (x - \zeta))

        where:

        .. math::

                \beta = \frac{2}{\kappa}

                \alpha = \beta^2 = \frac{4}{\kappa^2}

                \zeta = -\frac{\alpha}{\beta} = -\beta

        :math:`\Gamma` is the gamma function (`scipy.special.gamma`).
        Pass the skew :math:`\kappa` into `pearson3` as the shape parameter
        ``skew``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``pearson3.pdf(x, skew, loc, scale)`` is identically
        equivalent to ``pearson3.pdf(y, skew) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import pearson3
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> skew = -2
        >>> mean, var, skew, kurt = pearson3.stats(skew, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(pearson3.ppf(0.01, skew),
        ...                 pearson3.ppf(0.99, skew), 100)
        >>> ax.plot(x, pearson3.pdf(x, skew),
        ...        'r-', lw=5, alpha=0.6, label='pearson3 pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = pearson3(skew)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = pearson3.ppf([0.001, 0.5, 0.999], skew)
        >>> np.allclose([0.001, 0.5, 0.999], pearson3.cdf(vals, skew))
        True

        Generate random numbers:

        >>> r = pearson3.rvs(skew, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        References
        ----------
        R.W. Vogel and D.E. McMartin, "Probability Plot Goodness-of-Fit and
        Skewness Estimation Procedures for the Pearson Type 3 Distribution", Water
        Resources Research, Vol.27, 3149-3158 (1991).

        L.R. Salvosa, "Tables of Pearson's Type III Function", Ann. Math. Statist.,
        Vol.1, 191-198 (1930).

        "Using Modern Computing Tools to Fit the Pearson Type III Distribution to
        Aviation Loads Data", Office of Aviation Research (2003).

    planck = <scipy.stats._discrete_distns.planck_gen object>
        A Planck discrete exponential random variable.

        As an instance of the `rv_discrete` class, `planck` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(lambda_, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, lambda_, loc=0)
            Probability mass function.
        logpmf(k, lambda_, loc=0)
            Log of the probability mass function.
        cdf(k, lambda_, loc=0)
            Cumulative distribution function.
        logcdf(k, lambda_, loc=0)
            Log of the cumulative distribution function.
        sf(k, lambda_, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, lambda_, loc=0)
            Log of the survival function.
        ppf(q, lambda_, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, lambda_, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(lambda_, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(lambda_, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(lambda_,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(lambda_, loc=0)
            Median of the distribution.
        mean(lambda_, loc=0)
            Mean of the distribution.
        var(lambda_, loc=0)
            Variance of the distribution.
        std(lambda_, loc=0)
            Standard deviation of the distribution.
        interval(confidence, lambda_, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `planck` is:

        .. math::

            f(k) = (1-\exp(-\lambda)) \exp(-\lambda k)

        for :math:`k \ge 0` and :math:`\lambda > 0`.

        `planck` takes :math:`\lambda` as shape parameter. The Planck distribution
        can be written as a geometric distribution (`geom`) with
        :math:`p = 1 - \exp(-\lambda)` shifted by ``loc = -1``.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``planck.pmf(k, lambda_, loc)`` is identically
        equivalent to ``planck.pmf(k - loc, lambda_)``.

        See Also
        --------
        geom

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import planck
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> lambda_ = 0.51
        >>> mean, var, skew, kurt = planck.stats(lambda_, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(planck.ppf(0.01, lambda_),
        ...               planck.ppf(0.99, lambda_))
        >>> ax.plot(x, planck.pmf(x, lambda_), 'bo', ms=8, label='planck pmf')
        >>> ax.vlines(x, 0, planck.pmf(x, lambda_), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = planck(lambda_)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = planck.cdf(x, lambda_)
        >>> np.allclose(x, planck.ppf(prob, lambda_))
        True

        Generate random numbers:

        >>> r = planck.rvs(lambda_, size=1000)

    poisson = <scipy.stats._discrete_distns.poisson_gen object>
        A Poisson discrete random variable.

        As an instance of the `rv_discrete` class, `poisson` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(mu, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, mu, loc=0)
            Probability mass function.
        logpmf(k, mu, loc=0)
            Log of the probability mass function.
        cdf(k, mu, loc=0)
            Cumulative distribution function.
        logcdf(k, mu, loc=0)
            Log of the cumulative distribution function.
        sf(k, mu, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, mu, loc=0)
            Log of the survival function.
        ppf(q, mu, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, mu, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(mu, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(mu, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(mu,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(mu, loc=0)
            Median of the distribution.
        mean(mu, loc=0)
            Mean of the distribution.
        var(mu, loc=0)
            Variance of the distribution.
        std(mu, loc=0)
            Standard deviation of the distribution.
        interval(confidence, mu, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `poisson` is:

        .. math::

            f(k) = \exp(-\mu) \frac{\mu^k}{k!}

        for :math:`k \ge 0`.

        `poisson` takes :math:`\mu \geq 0` as shape parameter.
        When :math:`\mu = 0`, the ``pmf`` method
        returns ``1.0`` at quantile :math:`k = 0`.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``poisson.pmf(k, mu, loc)`` is identically
        equivalent to ``poisson.pmf(k - loc, mu)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import poisson
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mu = 0.6
        >>> mean, var, skew, kurt = poisson.stats(mu, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(poisson.ppf(0.01, mu),
        ...               poisson.ppf(0.99, mu))
        >>> ax.plot(x, poisson.pmf(x, mu), 'bo', ms=8, label='poisson pmf')
        >>> ax.vlines(x, 0, poisson.pmf(x, mu), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = poisson(mu)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = poisson.cdf(x, mu)
        >>> np.allclose(x, poisson.ppf(prob, mu))
        True

        Generate random numbers:

        >>> r = poisson.rvs(mu, size=1000)

    powerlaw = <scipy.stats._continuous_distns.powerlaw_gen object>
        A power-function continuous random variable.

        As an instance of the `rv_continuous` class, `powerlaw` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        pareto

        Notes
        -----
        The probability density function for `powerlaw` is:

        .. math::

            f(x, a) = a x^{a-1}

        for :math:`0 \le x \le 1`, :math:`a > 0`.

        `powerlaw` takes ``a`` as a shape parameter for :math:`a`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``powerlaw.pdf(x, a, loc, scale)`` is identically
        equivalent to ``powerlaw.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        For example, the support of `powerlaw` can be adjusted from the default
        interval ``[0, 1]`` to the interval ``[c, c+d]`` by setting ``loc=c`` and
        ``scale=d``. For a power-law distribution with infinite support, see
        `pareto`.

        `powerlaw` is a special case of `beta` with ``b=1``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import powerlaw
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 0.659
        >>> mean, var, skew, kurt = powerlaw.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(powerlaw.ppf(0.01, a),
        ...                 powerlaw.ppf(0.99, a), 100)
        >>> ax.plot(x, powerlaw.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='powerlaw pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = powerlaw(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = powerlaw.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], powerlaw.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = powerlaw.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    powerlognorm = <scipy.stats._continuous_distns.powerlognorm_gen object...
        A power log-normal continuous random variable.

        As an instance of the `rv_continuous` class, `powerlognorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, s, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, s, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, s, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, s, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, s, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, s, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, s, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, s, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, s, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, s, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, s, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, s, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c, s), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, s, loc=0, scale=1)
            Median of the distribution.
        mean(c, s, loc=0, scale=1)
            Mean of the distribution.
        var(c, s, loc=0, scale=1)
            Variance of the distribution.
        std(c, s, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, s, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `powerlognorm` is:

        .. math::

            f(x, c, s) = \frac{c}{x s} \phi(\log(x)/s)
                         (\Phi(-\log(x)/s))^{c-1}

        where :math:`\phi` is the normal pdf, and :math:`\Phi` is the normal cdf,
        and :math:`x > 0`, :math:`s, c > 0`.

        `powerlognorm` takes :math:`c` and :math:`s` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``powerlognorm.pdf(x, c, s, loc, scale)`` is identically
        equivalent to ``powerlognorm.pdf(y, c, s) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import powerlognorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c, s = 2.14, 0.446
        >>> mean, var, skew, kurt = powerlognorm.stats(c, s, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(powerlognorm.ppf(0.01, c, s),
        ...                 powerlognorm.ppf(0.99, c, s), 100)
        >>> ax.plot(x, powerlognorm.pdf(x, c, s),
        ...        'r-', lw=5, alpha=0.6, label='powerlognorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = powerlognorm(c, s)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = powerlognorm.ppf([0.001, 0.5, 0.999], c, s)
        >>> np.allclose([0.001, 0.5, 0.999], powerlognorm.cdf(vals, c, s))
        True

        Generate random numbers:

        >>> r = powerlognorm.rvs(c, s, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    powernorm = <scipy.stats._continuous_distns.powernorm_gen object>
        A power normal continuous random variable.

        As an instance of the `rv_continuous` class, `powernorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `powernorm` is:

        .. math::

            f(x, c) = c \phi(x) (\Phi(-x))^{c-1}

        where :math:`\phi` is the normal pdf, :math:`\Phi` is the normal cdf,
        :math:`x` is any real, and :math:`c > 0` [1]_.

        `powernorm` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``powernorm.pdf(x, c, loc, scale)`` is identically
        equivalent to ``powernorm.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] NIST Engineering Statistics Handbook, Section 1.3.6.6.13,
               https://www.itl.nist.gov/div898/handbook//eda/section3/eda366d.htm

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import powernorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 4.45
        >>> mean, var, skew, kurt = powernorm.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(powernorm.ppf(0.01, c),
        ...                 powernorm.ppf(0.99, c), 100)
        >>> ax.plot(x, powernorm.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='powernorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = powernorm(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = powernorm.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], powernorm.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = powernorm.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    randint = <scipy.stats._discrete_distns.randint_gen object>
        A uniform discrete random variable.

        As an instance of the `rv_discrete` class, `randint` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(low, high, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, low, high, loc=0)
            Probability mass function.
        logpmf(k, low, high, loc=0)
            Log of the probability mass function.
        cdf(k, low, high, loc=0)
            Cumulative distribution function.
        logcdf(k, low, high, loc=0)
            Log of the cumulative distribution function.
        sf(k, low, high, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, low, high, loc=0)
            Log of the survival function.
        ppf(q, low, high, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, low, high, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(low, high, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(low, high, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(low, high), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(low, high, loc=0)
            Median of the distribution.
        mean(low, high, loc=0)
            Mean of the distribution.
        var(low, high, loc=0)
            Variance of the distribution.
        std(low, high, loc=0)
            Standard deviation of the distribution.
        interval(confidence, low, high, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability mass function for `randint` is:

        .. math::

            f(k) = \frac{1}{\texttt{high} - \texttt{low}}

        for :math:`k \in \{\texttt{low}, \dots, \texttt{high} - 1\}`.

        `randint` takes :math:`\texttt{low}` and :math:`\texttt{high}` as shape
        parameters.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``randint.pmf(k, low, high, loc)`` is identically
        equivalent to ``randint.pmf(k - loc, low, high)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import randint
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> low, high = 7, 31
        >>> mean, var, skew, kurt = randint.stats(low, high, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(low - 5, high + 5)
        >>> ax.plot(x, randint.pmf(x, low, high), 'bo', ms=8, label='randint pmf')
        >>> ax.vlines(x, 0, randint.pmf(x, low, high), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function) to
        fix the shape and location. This returns a "frozen" RV object holding the
        given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = randint(low, high)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-',
        ...           lw=1, label='frozen pmf')
        >>> ax.legend(loc='lower center')
        >>> plt.show()

        Check the relationship between the cumulative distribution function
        (``cdf``) and its inverse, the percent point function (``ppf``):

        >>> q = np.arange(low, high)
        >>> p = randint.cdf(q, low, high)
        >>> np.allclose(q, randint.ppf(p, low, high))
        True

        Generate random numbers:

        >>> r = randint.rvs(low, high, size=1000)

    random_correlation = <scipy.stats._multivariate.random_correlation_gen...
    random_table = <scipy.stats._multivariate.random_table_gen object>
    rayleigh = <scipy.stats._continuous_distns.rayleigh_gen object>
        A Rayleigh continuous random variable.

        As an instance of the `rv_continuous` class, `rayleigh` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `rayleigh` is:

        .. math::

            f(x) = x \exp(-x^2/2)

        for :math:`x \ge 0`.

        `rayleigh` is a special case of `chi` with ``df=2``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``rayleigh.pdf(x, loc, scale)`` is identically
        equivalent to ``rayleigh.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import rayleigh
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = rayleigh.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(rayleigh.ppf(0.01),
        ...                 rayleigh.ppf(0.99), 100)
        >>> ax.plot(x, rayleigh.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='rayleigh pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = rayleigh()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = rayleigh.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], rayleigh.cdf(vals))
        True

        Generate random numbers:

        >>> r = rayleigh.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    rdist = <scipy.stats._continuous_distns.rdist_gen object>
        An R-distributed (symmetric beta) continuous random variable.

        As an instance of the `rv_continuous` class, `rdist` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `rdist` is:

        .. math::

            f(x, c) = \frac{(1-x^2)^{c/2-1}}{B(1/2, c/2)}

        for :math:`-1 \le x \le 1`, :math:`c > 0`. `rdist` is also called the
        symmetric beta distribution: if B has a `beta` distribution with
        parameters (c/2, c/2), then X = 2*B - 1 follows a R-distribution with
        parameter c.

        `rdist` takes ``c`` as a shape parameter for :math:`c`.

        This distribution includes the following distribution kernels as
        special cases::

            c = 2:  uniform
            c = 3:  `semicircular`
            c = 4:  Epanechnikov (parabolic)
            c = 6:  quartic (biweight)
            c = 8:  triweight

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``rdist.pdf(x, c, loc, scale)`` is identically
        equivalent to ``rdist.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import rdist
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 1.6
        >>> mean, var, skew, kurt = rdist.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(rdist.ppf(0.01, c),
        ...                 rdist.ppf(0.99, c), 100)
        >>> ax.plot(x, rdist.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='rdist pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = rdist(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = rdist.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], rdist.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = rdist.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    recipinvgauss = <scipy.stats._continuous_distns.recipinvgauss_gen obje...
        A reciprocal inverse Gaussian continuous random variable.

        As an instance of the `rv_continuous` class, `recipinvgauss` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(mu, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, mu, loc=0, scale=1)
            Probability density function.
        logpdf(x, mu, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, mu, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, mu, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, mu, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, mu, loc=0, scale=1)
            Log of the survival function.
        ppf(q, mu, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, mu, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, mu, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(mu, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(mu, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(mu,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(mu, loc=0, scale=1)
            Median of the distribution.
        mean(mu, loc=0, scale=1)
            Mean of the distribution.
        var(mu, loc=0, scale=1)
            Variance of the distribution.
        std(mu, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, mu, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `recipinvgauss` is:

        .. math::

            f(x, \mu) = \frac{1}{\sqrt{2\pi x}}
                        \exp\left(\frac{-(1-\mu x)^2}{2\mu^2x}\right)

        for :math:`x \ge 0`.

        `recipinvgauss` takes ``mu`` as a shape parameter for :math:`\mu`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``recipinvgauss.pdf(x, mu, loc, scale)`` is identically
        equivalent to ``recipinvgauss.pdf(y, mu) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import recipinvgauss
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mu = 0.63
        >>> mean, var, skew, kurt = recipinvgauss.stats(mu, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(recipinvgauss.ppf(0.01, mu),
        ...                 recipinvgauss.ppf(0.99, mu), 100)
        >>> ax.plot(x, recipinvgauss.pdf(x, mu),
        ...        'r-', lw=5, alpha=0.6, label='recipinvgauss pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = recipinvgauss(mu)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = recipinvgauss.ppf([0.001, 0.5, 0.999], mu)
        >>> np.allclose([0.001, 0.5, 0.999], recipinvgauss.cdf(vals, mu))
        True

        Generate random numbers:

        >>> r = recipinvgauss.rvs(mu, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    reciprocal = <scipy.stats._continuous_distns.reciprocal_gen object>
        A loguniform or reciprocal continuous random variable.

        As an instance of the `rv_continuous` class, `reciprocal` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for this class is:

        .. math::

            f(x, a, b) = \frac{1}{x \log(b/a)}

        for :math:`a \le x \le b`, :math:`b > a > 0`. This class takes
        :math:`a` and :math:`b` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``reciprocal.pdf(x, a, b, loc, scale)`` is identically
        equivalent to ``reciprocal.pdf(y, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import reciprocal
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 0.01, 1.25
        >>> mean, var, skew, kurt = reciprocal.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(reciprocal.ppf(0.01, a, b),
        ...                 reciprocal.ppf(0.99, a, b), 100)
        >>> ax.plot(x, reciprocal.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='reciprocal pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = reciprocal(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = reciprocal.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], reciprocal.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = reciprocal.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        This doesn't show the equal probability of ``0.01``, ``0.1`` and
        ``1``. This is best when the x-axis is log-scaled:

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.hist(np.log10(r))
        >>> ax.set_ylabel("Frequency")
        >>> ax.set_xlabel("Value of random variable")
        >>> ax.xaxis.set_major_locator(plt.FixedLocator([-2, -1, 0]))
        >>> ticks = ["$10^{{ {} }}$".format(i) for i in [-2, -1, 0]]
        >>> ax.set_xticklabels(ticks)  # doctest: +SKIP
        >>> plt.show()

        This random variable will be log-uniform regardless of the base chosen for
        ``a`` and ``b``. Let's specify with base ``2`` instead:

        >>> rvs = reciprocal(2**-2, 2**0).rvs(size=1000)

        Values of ``1/4``, ``1/2`` and ``1`` are equally likely with this random
        variable.  Here's the histogram:

        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.hist(np.log2(rvs))
        >>> ax.set_ylabel("Frequency")
        >>> ax.set_xlabel("Value of random variable")
        >>> ax.xaxis.set_major_locator(plt.FixedLocator([-2, -1, 0]))
        >>> ticks = ["$2^{{ {} }}$".format(i) for i in [-2, -1, 0]]
        >>> ax.set_xticklabels(ticks)  # doctest: +SKIP
        >>> plt.show()

    rel_breitwigner = <scipy.stats._continuous_distns.rel_breitwigner_gen ...
        A relativistic Breit-Wigner random variable.

        As an instance of the `rv_continuous` class, `rel_breitwigner` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(rho, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, rho, loc=0, scale=1)
            Probability density function.
        logpdf(x, rho, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, rho, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, rho, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, rho, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, rho, loc=0, scale=1)
            Log of the survival function.
        ppf(q, rho, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, rho, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, rho, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(rho, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(rho, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(rho,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(rho, loc=0, scale=1)
            Median of the distribution.
        mean(rho, loc=0, scale=1)
            Mean of the distribution.
        var(rho, loc=0, scale=1)
            Variance of the distribution.
        std(rho, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, rho, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        cauchy: Cauchy distribution, also known as the Breit-Wigner distribution.

        Notes
        -----

        The probability density function for `rel_breitwigner` is

        .. math::

            f(x, \rho) = \frac{k}{(x^2 - \rho^2)^2 + \rho^2}

        where

        .. math::
            k = \frac{2\sqrt{2}\rho^2\sqrt{\rho^2 + 1}}
                {\pi\sqrt{\rho^2 + \rho\sqrt{\rho^2 + 1}}}

        The relativistic Breit-Wigner distribution is used in high energy physics
        to model resonances [1]_. It gives the uncertainty in the invariant mass,
        :math:`M` [2]_, of a resonance with characteristic mass :math:`M_0` and
        decay-width :math:`\Gamma`, where :math:`M`, :math:`M_0` and :math:`\Gamma`
        are expressed in natural units. In SciPy's parametrization, the shape
        parameter :math:`\rho` is equal to :math:`M_0/\Gamma` and takes values in
        :math:`(0, \infty)`.

        Equivalently, the relativistic Breit-Wigner distribution is said to give
        the uncertainty in the center-of-mass energy :math:`E_{\text{cm}}`. In
        natural units, the speed of light :math:`c` is equal to 1 and the invariant
        mass :math:`M` is equal to the rest energy :math:`Mc^2`. In the
        center-of-mass frame, the rest energy is equal to the total energy [3]_.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``rel_breitwigner.pdf(x, rho, loc, scale)`` is identically
        equivalent to ``rel_breitwigner.pdf(y, rho) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        :math:`\rho = M/\Gamma` and :math:`\Gamma` is the scale parameter. For
        example, if one seeks to model the :math:`Z^0` boson with :math:`M_0
        \approx 91.1876 \text{ GeV}` and :math:`\Gamma \approx 2.4952\text{ GeV}`
        [4]_ one can set ``rho=91.1876/2.4952`` and ``scale=2.4952``.

        To ensure a physically meaningful result when using the `fit` method, one
        should set ``floc=0`` to fix the location parameter to 0.

        References
        ----------
        .. [1] Relativistic Breit-Wigner distribution, Wikipedia,
               https://en.wikipedia.org/wiki/Relativistic_Breit-Wigner_distribution
        .. [2] Invariant mass, Wikipedia,
               https://en.wikipedia.org/wiki/Invariant_mass
        .. [3] Center-of-momentum frame, Wikipedia,
               https://en.wikipedia.org/wiki/Center-of-momentum_frame
        .. [4] M. Tanabashi et al. (Particle Data Group) Phys. Rev. D 98, 030001 -
               Published 17 August 2018

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import rel_breitwigner
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> rho = 36.5
        >>> mean, var, skew, kurt = rel_breitwigner.stats(rho, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(rel_breitwigner.ppf(0.01, rho),
        ...                 rel_breitwigner.ppf(0.99, rho), 100)
        >>> ax.plot(x, rel_breitwigner.pdf(x, rho),
        ...        'r-', lw=5, alpha=0.6, label='rel_breitwigner pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = rel_breitwigner(rho)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = rel_breitwigner.ppf([0.001, 0.5, 0.999], rho)
        >>> np.allclose([0.001, 0.5, 0.999], rel_breitwigner.cdf(vals, rho))
        True

        Generate random numbers:

        >>> r = rel_breitwigner.rvs(rho, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    rice = <scipy.stats._continuous_distns.rice_gen object>
        A Rice continuous random variable.

        As an instance of the `rv_continuous` class, `rice` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(b,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(b, loc=0, scale=1)
            Median of the distribution.
        mean(b, loc=0, scale=1)
            Mean of the distribution.
        var(b, loc=0, scale=1)
            Variance of the distribution.
        std(b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `rice` is:

        .. math::

            f(x, b) = x \exp(- \frac{x^2 + b^2}{2}) I_0(x b)

        for :math:`x >= 0`, :math:`b > 0`. :math:`I_0` is the modified Bessel
        function of order zero (`scipy.special.i0`).

        `rice` takes ``b`` as a shape parameter for :math:`b`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``rice.pdf(x, b, loc, scale)`` is identically
        equivalent to ``rice.pdf(y, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The Rice distribution describes the length, :math:`r`, of a 2-D vector with
        components :math:`(U+u, V+v)`, where :math:`U, V` are constant, :math:`u,
        v` are independent Gaussian random variables with standard deviation
        :math:`s`.  Let :math:`R = \sqrt{U^2 + V^2}`. Then the pdf of :math:`r` is
        ``rice.pdf(x, R/s, scale=s)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import rice
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> b = 0.775
        >>> mean, var, skew, kurt = rice.stats(b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(rice.ppf(0.01, b),
        ...                 rice.ppf(0.99, b), 100)
        >>> ax.plot(x, rice.pdf(x, b),
        ...        'r-', lw=5, alpha=0.6, label='rice pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = rice(b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = rice.ppf([0.001, 0.5, 0.999], b)
        >>> np.allclose([0.001, 0.5, 0.999], rice.cdf(vals, b))
        True

        Generate random numbers:

        >>> r = rice.rvs(b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    semicircular = <scipy.stats._continuous_distns.semicircular_gen object...
        A semicircular continuous random variable.

        As an instance of the `rv_continuous` class, `semicircular` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        rdist

        Notes
        -----
        The probability density function for `semicircular` is:

        .. math::

            f(x) = \frac{2}{\pi} \sqrt{1-x^2}

        for :math:`-1 \le x \le 1`.

        The distribution is a special case of `rdist` with `c = 3`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``semicircular.pdf(x, loc, scale)`` is identically
        equivalent to ``semicircular.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] "Wigner semicircle distribution",
               https://en.wikipedia.org/wiki/Wigner_semicircle_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import semicircular
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = semicircular.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(semicircular.ppf(0.01),
        ...                 semicircular.ppf(0.99), 100)
        >>> ax.plot(x, semicircular.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='semicircular pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = semicircular()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = semicircular.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], semicircular.cdf(vals))
        True

        Generate random numbers:

        >>> r = semicircular.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    skellam = <scipy.stats._discrete_distns.skellam_gen object>
        A  Skellam discrete random variable.

        As an instance of the `rv_discrete` class, `skellam` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(mu1, mu2, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, mu1, mu2, loc=0)
            Probability mass function.
        logpmf(k, mu1, mu2, loc=0)
            Log of the probability mass function.
        cdf(k, mu1, mu2, loc=0)
            Cumulative distribution function.
        logcdf(k, mu1, mu2, loc=0)
            Log of the cumulative distribution function.
        sf(k, mu1, mu2, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, mu1, mu2, loc=0)
            Log of the survival function.
        ppf(q, mu1, mu2, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, mu1, mu2, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(mu1, mu2, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(mu1, mu2, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(mu1, mu2), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(mu1, mu2, loc=0)
            Median of the distribution.
        mean(mu1, mu2, loc=0)
            Mean of the distribution.
        var(mu1, mu2, loc=0)
            Variance of the distribution.
        std(mu1, mu2, loc=0)
            Standard deviation of the distribution.
        interval(confidence, mu1, mu2, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----
        Probability distribution of the difference of two correlated or
        uncorrelated Poisson random variables.

        Let :math:`k_1` and :math:`k_2` be two Poisson-distributed r.v. with
        expected values :math:`\lambda_1` and :math:`\lambda_2`. Then,
        :math:`k_1 - k_2` follows a Skellam distribution with parameters
        :math:`\mu_1 = \lambda_1 - \rho \sqrt{\lambda_1 \lambda_2}` and
        :math:`\mu_2 = \lambda_2 - \rho \sqrt{\lambda_1 \lambda_2}`, where
        :math:`\rho` is the correlation coefficient between :math:`k_1` and
        :math:`k_2`. If the two Poisson-distributed r.v. are independent then
        :math:`\rho = 0`.

        Parameters :math:`\mu_1` and :math:`\mu_2` must be strictly positive.

        For details see: https://en.wikipedia.org/wiki/Skellam_distribution

        `skellam` takes :math:`\mu_1` and :math:`\mu_2` as shape parameters.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``skellam.pmf(k, mu1, mu2, loc)`` is identically
        equivalent to ``skellam.pmf(k - loc, mu1, mu2)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import skellam
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> mu1, mu2 = 15, 8
        >>> mean, var, skew, kurt = skellam.stats(mu1, mu2, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(skellam.ppf(0.01, mu1, mu2),
        ...               skellam.ppf(0.99, mu1, mu2))
        >>> ax.plot(x, skellam.pmf(x, mu1, mu2), 'bo', ms=8, label='skellam pmf')
        >>> ax.vlines(x, 0, skellam.pmf(x, mu1, mu2), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = skellam(mu1, mu2)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = skellam.cdf(x, mu1, mu2)
        >>> np.allclose(x, skellam.ppf(prob, mu1, mu2))
        True

        Generate random numbers:

        >>> r = skellam.rvs(mu1, mu2, size=1000)

    skewcauchy = <scipy.stats._continuous_distns.skewcauchy_gen object>
        A skewed Cauchy random variable.

        As an instance of the `rv_continuous` class, `skewcauchy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        cauchy : Cauchy distribution

        Notes
        -----

        The probability density function for `skewcauchy` is:

        .. math::

            f(x) = \frac{1}{\pi \left(\frac{x^2}{\left(a\, \text{sign}(x) + 1
                                                       \right)^2} + 1 \right)}

        for a real number :math:`x` and skewness parameter :math:`-1 < a < 1`.

        When :math:`a=0`, the distribution reduces to the usual Cauchy
        distribution.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``skewcauchy.pdf(x, a, loc, scale)`` is identically
        equivalent to ``skewcauchy.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] "Skewed generalized *t* distribution", Wikipedia
           https://en.wikipedia.org/wiki/Skewed_generalized_t_distribution#Skewed_Cauchy_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import skewcauchy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 0.5
        >>> mean, var, skew, kurt = skewcauchy.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(skewcauchy.ppf(0.01, a),
        ...                 skewcauchy.ppf(0.99, a), 100)
        >>> ax.plot(x, skewcauchy.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='skewcauchy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = skewcauchy(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = skewcauchy.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], skewcauchy.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = skewcauchy.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    skewnorm = <scipy.stats._continuous_distns.skewnorm_gen object>
        A skew-normal random variable.

        As an instance of the `rv_continuous` class, `skewnorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0, scale=1)
            Median of the distribution.
        mean(a, loc=0, scale=1)
            Mean of the distribution.
        var(a, loc=0, scale=1)
            Variance of the distribution.
        std(a, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The pdf is::

            skewnorm.pdf(x, a) = 2 * norm.pdf(x) * norm.cdf(a*x)

        `skewnorm` takes a real number :math:`a` as a skewness parameter
        When ``a = 0`` the distribution is identical to a normal distribution
        (`norm`). `rvs` implements the method of [1]_.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``skewnorm.pdf(x, a, loc, scale)`` is identically
        equivalent to ``skewnorm.pdf(y, a) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import skewnorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 4
        >>> mean, var, skew, kurt = skewnorm.stats(a, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(skewnorm.ppf(0.01, a),
        ...                 skewnorm.ppf(0.99, a), 100)
        >>> ax.plot(x, skewnorm.pdf(x, a),
        ...        'r-', lw=5, alpha=0.6, label='skewnorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = skewnorm(a)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = skewnorm.ppf([0.001, 0.5, 0.999], a)
        >>> np.allclose([0.001, 0.5, 0.999], skewnorm.cdf(vals, a))
        True

        Generate random numbers:

        >>> r = skewnorm.rvs(a, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        References
        ----------
        .. [1] A. Azzalini and A. Capitanio (1999). Statistical applications of
            the multivariate skew-normal distribution. J. Roy. Statist. Soc.,
            B 61, 579-602. :arxiv:`0911.2093`

    special_ortho_group = <scipy.stats._multivariate.special_ortho_group_g...
    studentized_range = <scipy.stats._continuous_distns.studentized_range_...
        A studentized range continuous random variable.

        As an instance of the `rv_continuous` class, `studentized_range` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(k, df, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, k, df, loc=0, scale=1)
            Probability density function.
        logpdf(x, k, df, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, k, df, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, k, df, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, k, df, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, k, df, loc=0, scale=1)
            Log of the survival function.
        ppf(q, k, df, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, k, df, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, k, df, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(k, df, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(k, df, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(k, df), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(k, df, loc=0, scale=1)
            Median of the distribution.
        mean(k, df, loc=0, scale=1)
            Mean of the distribution.
        var(k, df, loc=0, scale=1)
            Variance of the distribution.
        std(k, df, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, k, df, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        t: Student's t distribution

        Notes
        -----
        The probability density function for `studentized_range` is:

        .. math::

             f(x; k, \nu) = \frac{k(k-1)\nu^{\nu/2}}{\Gamma(\nu/2)
                            2^{\nu/2-1}} \int_{0}^{\infty} \int_{-\infty}^{\infty}
                            s^{\nu} e^{-\nu s^2/2} \phi(z) \phi(sx + z)
                            [\Phi(sx + z) - \Phi(z)]^{k-2} \,dz \,ds

        for :math:`x ≥ 0`, :math:`k > 1`, and :math:`\nu > 0`.

        `studentized_range` takes ``k`` for :math:`k` and ``df`` for :math:`\nu`
        as shape parameters.

        When :math:`\nu` exceeds 100,000, an asymptotic approximation (infinite
        degrees of freedom) is used to compute the cumulative distribution
        function [4]_ and probability distribution function.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``studentized_range.pdf(x, k, df, loc, scale)`` is identically
        equivalent to ``studentized_range.pdf(y, k, df) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------

        .. [1] "Studentized range distribution",
               https://en.wikipedia.org/wiki/Studentized_range_distribution
        .. [2] Batista, Ben Dêivide, et al. "Externally Studentized Normal Midrange
               Distribution." Ciência e Agrotecnologia, vol. 41, no. 4, 2017, pp.
               378-389., doi:10.1590/1413-70542017414047716.
        .. [3] Harter, H. Leon. "Tables of Range and Studentized Range." The Annals
               of Mathematical Statistics, vol. 31, no. 4, 1960, pp. 1122-1147.
               JSTOR, www.jstor.org/stable/2237810. Accessed 18 Feb. 2021.
        .. [4] Lund, R. E., and J. R. Lund. "Algorithm AS 190: Probabilities and
               Upper Quantiles for the Studentized Range." Journal of the Royal
               Statistical Society. Series C (Applied Statistics), vol. 32, no. 2,
               1983, pp. 204-210. JSTOR, www.jstor.org/stable/2347300. Accessed 18
               Feb. 2021.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import studentized_range
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Display the probability density function (``pdf``):

        >>> k, df = 3, 10
        >>> x = np.linspace(studentized_range.ppf(0.01, k, df),
        ...                 studentized_range.ppf(0.99, k, df), 100)
        >>> ax.plot(x, studentized_range.pdf(x, k, df),
        ...         'r-', lw=5, alpha=0.6, label='studentized_range pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = studentized_range(k, df)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = studentized_range.ppf([0.001, 0.5, 0.999], k, df)
        >>> np.allclose([0.001, 0.5, 0.999], studentized_range.cdf(vals, k, df))
        True

        Rather than using (``studentized_range.rvs``) to generate random variates,
        which is very slow for this distribution, we can approximate the inverse
        CDF using an interpolator, and then perform inverse transform sampling
        with this approximate inverse CDF.

        This distribution has an infinite but thin right tail, so we focus our
        attention on the leftmost 99.9 percent.

        >>> a, b = studentized_range.ppf([0, .999], k, df)
        >>> a, b
        0, 7.41058083802274

        >>> from scipy.interpolate import interp1d
        >>> rng = np.random.default_rng()
        >>> xs = np.linspace(a, b, 50)
        >>> cdf = studentized_range.cdf(xs, k, df)
        # Create an interpolant of the inverse CDF
        >>> ppf = interp1d(cdf, xs, fill_value='extrapolate')
        # Perform inverse transform sampling using the interpolant
        >>> r = ppf(rng.uniform(size=1000))

        And compare the histogram:

        >>> ax.hist(r, density=True, histtype='stepfilled', alpha=0.2)
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    t = <scipy.stats._continuous_distns.t_gen object>
        A Student's t continuous random variable.

        For the noncentral t distribution, see `nct`.

        As an instance of the `rv_continuous` class, `t` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(df, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, df, loc=0, scale=1)
            Probability density function.
        logpdf(x, df, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, df, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, df, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, df, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, df, loc=0, scale=1)
            Log of the survival function.
        ppf(q, df, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, df, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, df, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(df, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(df, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(df,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(df, loc=0, scale=1)
            Median of the distribution.
        mean(df, loc=0, scale=1)
            Mean of the distribution.
        var(df, loc=0, scale=1)
            Variance of the distribution.
        std(df, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, df, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        nct

        Notes
        -----
        The probability density function for `t` is:

        .. math::

            f(x, \nu) = \frac{\Gamma((\nu+1)/2)}
                            {\sqrt{\pi \nu} \Gamma(\nu/2)}
                        (1+x^2/\nu)^{-(\nu+1)/2}

        where :math:`x` is a real number and the degrees of freedom parameter
        :math:`\nu` (denoted ``df`` in the implementation) satisfies
        :math:`\nu > 0`. :math:`\Gamma` is the gamma function
        (`scipy.special.gamma`).

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``t.pdf(x, df, loc, scale)`` is identically
        equivalent to ``t.pdf(y, df) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import t
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> df = 2.74
        >>> mean, var, skew, kurt = t.stats(df, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(t.ppf(0.01, df),
        ...                 t.ppf(0.99, df), 100)
        >>> ax.plot(x, t.pdf(x, df),
        ...        'r-', lw=5, alpha=0.6, label='t pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = t(df)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = t.ppf([0.001, 0.5, 0.999], df)
        >>> np.allclose([0.001, 0.5, 0.999], t.cdf(vals, df))
        True

        Generate random numbers:

        >>> r = t.rvs(df, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    trapezoid = <scipy.stats._continuous_distns.trapezoid_gen object>
        A trapezoidal continuous random variable.

        As an instance of the `rv_continuous` class, `trapezoid` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, d, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, d, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, d, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, d, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, d, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, d, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, d, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, d, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, d, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, d, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, d, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, d, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c, d), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, d, loc=0, scale=1)
            Median of the distribution.
        mean(c, d, loc=0, scale=1)
            Mean of the distribution.
        var(c, d, loc=0, scale=1)
            Variance of the distribution.
        std(c, d, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, d, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The trapezoidal distribution can be represented with an up-sloping line
        from ``loc`` to ``(loc + c*scale)``, then constant to ``(loc + d*scale)``
        and then downsloping from ``(loc + d*scale)`` to ``(loc+scale)``.  This
        defines the trapezoid base from ``loc`` to ``(loc+scale)`` and the flat
        top from ``c`` to ``d`` proportional to the position along the base
        with ``0 <= c <= d <= 1``.  When ``c=d``, this is equivalent to `triang`
        with the same values for `loc`, `scale` and `c`.
        The method of [1]_ is used for computing moments.

        `trapezoid` takes :math:`c` and :math:`d` as shape parameters.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``trapezoid.pdf(x, c, d, loc, scale)`` is identically
        equivalent to ``trapezoid.pdf(y, c, d) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The standard form is in the range [0, 1] with c the mode.
        The location parameter shifts the start to `loc`.
        The scale parameter changes the width from 1 to `scale`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import trapezoid
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c, d = 0.2, 0.8
        >>> mean, var, skew, kurt = trapezoid.stats(c, d, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(trapezoid.ppf(0.01, c, d),
        ...                 trapezoid.ppf(0.99, c, d), 100)
        >>> ax.plot(x, trapezoid.pdf(x, c, d),
        ...        'r-', lw=5, alpha=0.6, label='trapezoid pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = trapezoid(c, d)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = trapezoid.ppf([0.001, 0.5, 0.999], c, d)
        >>> np.allclose([0.001, 0.5, 0.999], trapezoid.cdf(vals, c, d))
        True

        Generate random numbers:

        >>> r = trapezoid.rvs(c, d, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        References
        ----------
        .. [1] Kacker, R.N. and Lawrence, J.F. (2007). Trapezoidal and triangular
           distributions for Type B evaluation of standard uncertainty.
           Metrologia 44, 117-127. :doi:`10.1088/0026-1394/44/2/003`

    trapz = <scipy.stats._continuous_distns.trapz_gen object>
    triang = <scipy.stats._continuous_distns.triang_gen object>
        A triangular continuous random variable.

        As an instance of the `rv_continuous` class, `triang` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The triangular distribution can be represented with an up-sloping line from
        ``loc`` to ``(loc + c*scale)`` and then downsloping for ``(loc + c*scale)``
        to ``(loc + scale)``.

        `triang` takes ``c`` as a shape parameter for :math:`0 \le c \le 1`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``triang.pdf(x, c, loc, scale)`` is identically
        equivalent to ``triang.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        The standard form is in the range [0, 1] with c the mode.
        The location parameter shifts the start to `loc`.
        The scale parameter changes the width from 1 to `scale`.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import triang
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.158
        >>> mean, var, skew, kurt = triang.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(triang.ppf(0.01, c),
        ...                 triang.ppf(0.99, c), 100)
        >>> ax.plot(x, triang.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='triang pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = triang(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = triang.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], triang.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = triang.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    truncexpon = <scipy.stats._continuous_distns.truncexpon_gen object>
        A truncated exponential continuous random variable.

        As an instance of the `rv_continuous` class, `truncexpon` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(b,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(b, loc=0, scale=1)
            Median of the distribution.
        mean(b, loc=0, scale=1)
            Mean of the distribution.
        var(b, loc=0, scale=1)
            Variance of the distribution.
        std(b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `truncexpon` is:

        .. math::

            f(x, b) = \frac{\exp(-x)}{1 - \exp(-b)}

        for :math:`0 <= x <= b`.

        `truncexpon` takes ``b`` as a shape parameter for :math:`b`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``truncexpon.pdf(x, b, loc, scale)`` is identically
        equivalent to ``truncexpon.pdf(y, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import truncexpon
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> b = 4.69
        >>> mean, var, skew, kurt = truncexpon.stats(b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(truncexpon.ppf(0.01, b),
        ...                 truncexpon.ppf(0.99, b), 100)
        >>> ax.plot(x, truncexpon.pdf(x, b),
        ...        'r-', lw=5, alpha=0.6, label='truncexpon pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = truncexpon(b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = truncexpon.ppf([0.001, 0.5, 0.999], b)
        >>> np.allclose([0.001, 0.5, 0.999], truncexpon.cdf(vals, b))
        True

        Generate random numbers:

        >>> r = truncexpon.rvs(b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    truncnorm = <scipy.stats._continuous_distns.truncnorm_gen object>
        A truncated normal continuous random variable.

        As an instance of the `rv_continuous` class, `truncnorm` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, b, loc=0, scale=1)
            Median of the distribution.
        mean(a, b, loc=0, scale=1)
            Mean of the distribution.
        var(a, b, loc=0, scale=1)
            Variance of the distribution.
        std(a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        This distribution is the normal distribution centered on ``loc`` (default
        0), with standard deviation ``scale`` (default 1), and truncated at ``a``
        and ``b`` *standard deviations* from ``loc``. For arbitrary ``loc`` and
        ``scale``, ``a`` and ``b`` are *not* the abscissae at which the shifted
        and scaled distribution is truncated.

        .. note::
            If ``a_trunc`` and ``b_trunc`` are the abscissae at which we wish
            to truncate the distribution (as opposed to the number of standard
            deviations from ``loc``), then we can calculate the distribution
            parameters ``a`` and ``b`` as follows::

                a, b = (a_trunc - loc) / scale, (b_trunc - loc) / scale

            This is a common point of confusion. For additional clarification,
            please see the example below.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import truncnorm
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, b = 0.1, 2
        >>> mean, var, skew, kurt = truncnorm.stats(a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(truncnorm.ppf(0.01, a, b),
        ...                 truncnorm.ppf(0.99, a, b), 100)
        >>> ax.plot(x, truncnorm.pdf(x, a, b),
        ...        'r-', lw=5, alpha=0.6, label='truncnorm pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = truncnorm(a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = truncnorm.ppf([0.001, 0.5, 0.999], a, b)
        >>> np.allclose([0.001, 0.5, 0.999], truncnorm.cdf(vals, a, b))
        True

        Generate random numbers:

        >>> r = truncnorm.rvs(a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()


        In the examples above, ``loc=0`` and ``scale=1``, so the plot is truncated
        at ``a`` on the left and ``b`` on the right. However, suppose we were to
        produce the same histogram with ``loc = 1`` and ``scale=0.5``.

        >>> loc, scale = 1, 0.5
        >>> rv = truncnorm(a, b, loc=loc, scale=scale)
        >>> x = np.linspace(truncnorm.ppf(0.01, a, b),
        ...                 truncnorm.ppf(0.99, a, b), 100)
        >>> r = rv.rvs(size=1000)

        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim(a, b)
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Note that the distribution is no longer appears to be truncated at
        abscissae ``a`` and ``b``. That is because the *standard* normal
        distribution is first truncated at ``a`` and ``b``, *then* the resulting
        distribution is scaled by ``scale`` and shifted by ``loc``. If we instead
        want the shifted and scaled distribution to be truncated at ``a`` and
        ``b``, we need to transform these values before passing them as the
        distribution parameters.

        >>> a_transformed, b_transformed = (a - loc) / scale, (b - loc) / scale
        >>> rv = truncnorm(a_transformed, b_transformed, loc=loc, scale=scale)
        >>> x = np.linspace(truncnorm.ppf(0.01, a, b),
        ...                 truncnorm.ppf(0.99, a, b), 100)
        >>> r = rv.rvs(size=10000)

        >>> fig, ax = plt.subplots(1, 1)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')
        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim(a-0.1, b+0.1)
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    truncpareto = <scipy.stats._continuous_distns.truncpareto_gen object>
        An upper truncated Pareto continuous random variable.

        As an instance of the `rv_continuous` class, `truncpareto` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(b, c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, b, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, b, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, b, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, b, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, b, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, b, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, b, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, b, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, b, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(b, c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(b, c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(b, c), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(b, c, loc=0, scale=1)
            Median of the distribution.
        mean(b, c, loc=0, scale=1)
            Mean of the distribution.
        var(b, c, loc=0, scale=1)
            Variance of the distribution.
        std(b, c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, b, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        pareto : Pareto distribution

        Notes
        -----
        The probability density function for `truncpareto` is:

        .. math::

            f(x, b, c) = \frac{b}{1 - c^{-b}} \frac{1}{x^{b+1}}

        for :math:`b > 0`, :math:`c > 1` and :math:`1 \le x \le c`.

        `truncpareto` takes `b` and `c` as shape parameters for :math:`b` and
        :math:`c`.

        Notice that the upper truncation value :math:`c` is defined in
        standardized form so that random values of an unscaled, unshifted variable
        are within the range ``[1, c]``.
        If ``u_r`` is the upper bound to a scaled and/or shifted variable,
        then ``c = (u_r - loc) / scale``. In other words, the support of the
        distribution becomes ``(scale + loc) <= x <= (c*scale + loc)`` when
        `scale` and/or `loc` are provided.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``truncpareto.pdf(x, b, c, loc, scale)`` is identically
        equivalent to ``truncpareto.pdf(y, b, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        .. [1] Burroughs, S. M., and Tebbens S. F.
            "Upper-truncated power laws in natural systems."
            Pure and Applied Geophysics 158.4 (2001): 741-757.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import truncpareto
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> b, c = 2, 5
        >>> mean, var, skew, kurt = truncpareto.stats(b, c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(truncpareto.ppf(0.01, b, c),
        ...                 truncpareto.ppf(0.99, b, c), 100)
        >>> ax.plot(x, truncpareto.pdf(x, b, c),
        ...        'r-', lw=5, alpha=0.6, label='truncpareto pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = truncpareto(b, c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = truncpareto.ppf([0.001, 0.5, 0.999], b, c)
        >>> np.allclose([0.001, 0.5, 0.999], truncpareto.cdf(vals, b, c))
        True

        Generate random numbers:

        >>> r = truncpareto.rvs(b, c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    truncweibull_min = <scipy.stats._continuous_distns.truncweibull_min_ge...
        A doubly truncated Weibull minimum continuous random variable.

        As an instance of the `rv_continuous` class, `truncweibull_min` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, a, b, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, a, b, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, a, b, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, a, b, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, a, b, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, a, b, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, a, b, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, a, b, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, a, b, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, a, b, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, a, b, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, a, b, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c, a, b), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, a, b, loc=0, scale=1)
            Median of the distribution.
        mean(c, a, b, loc=0, scale=1)
            Mean of the distribution.
        var(c, a, b, loc=0, scale=1)
            Variance of the distribution.
        std(c, a, b, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, a, b, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        weibull_min, truncexpon

        Notes
        -----
        The probability density function for `truncweibull_min` is:

        .. math::

            f(x, a, b, c) = \frac{c x^{c-1} \exp(-x^c)}{\exp(-a^c) - \exp(-b^c)}

        for :math:`a < x <= b`, :math:`0 \le a < b` and :math:`c > 0`.

        `truncweibull_min` takes :math:`a`, :math:`b`, and :math:`c` as shape
        parameters.

        Notice that the truncation values, :math:`a` and :math:`b`, are defined in
        standardized form:

        .. math::

            a = (u_l - loc)/scale
            b = (u_r - loc)/scale

        where :math:`u_l` and :math:`u_r` are the specific left and right
        truncation values, respectively. In other words, the support of the
        distribution becomes :math:`(a*scale + loc) < x <= (b*scale + loc)` when
        :math:`loc` and/or :math:`scale` are provided.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``truncweibull_min.pdf(x, c, a, b, loc, scale)`` is identically
        equivalent to ``truncweibull_min.pdf(y, c, a, b) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------

        .. [1] Rinne, H. "The Weibull Distribution: A Handbook". CRC Press (2009).

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import truncweibull_min
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c, a, b = 2.5, 0.25, 1.75
        >>> mean, var, skew, kurt = truncweibull_min.stats(c, a, b, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(truncweibull_min.ppf(0.01, c, a, b),
        ...                 truncweibull_min.ppf(0.99, c, a, b), 100)
        >>> ax.plot(x, truncweibull_min.pdf(x, c, a, b),
        ...        'r-', lw=5, alpha=0.6, label='truncweibull_min pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = truncweibull_min(c, a, b)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = truncweibull_min.ppf([0.001, 0.5, 0.999], c, a, b)
        >>> np.allclose([0.001, 0.5, 0.999], truncweibull_min.cdf(vals, c, a, b))
        True

        Generate random numbers:

        >>> r = truncweibull_min.rvs(c, a, b, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    tukeylambda = <scipy.stats._continuous_distns.tukeylambda_gen object>
        A Tukey-Lamdba continuous random variable.

        As an instance of the `rv_continuous` class, `tukeylambda` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(lam, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, lam, loc=0, scale=1)
            Probability density function.
        logpdf(x, lam, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, lam, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, lam, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, lam, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, lam, loc=0, scale=1)
            Log of the survival function.
        ppf(q, lam, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, lam, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, lam, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(lam, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(lam, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(lam,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(lam, loc=0, scale=1)
            Median of the distribution.
        mean(lam, loc=0, scale=1)
            Mean of the distribution.
        var(lam, loc=0, scale=1)
            Variance of the distribution.
        std(lam, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, lam, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        A flexible distribution, able to represent and interpolate between the
        following distributions:

        - Cauchy                (:math:`lambda = -1`)
        - logistic              (:math:`lambda = 0`)
        - approx Normal         (:math:`lambda = 0.14`)
        - uniform from -1 to 1  (:math:`lambda = 1`)

        `tukeylambda` takes a real number :math:`lambda` (denoted ``lam``
        in the implementation) as a shape parameter.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``tukeylambda.pdf(x, lam, loc, scale)`` is identically
        equivalent to ``tukeylambda.pdf(y, lam) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import tukeylambda
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> lam = 3.13
        >>> mean, var, skew, kurt = tukeylambda.stats(lam, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(tukeylambda.ppf(0.01, lam),
        ...                 tukeylambda.ppf(0.99, lam), 100)
        >>> ax.plot(x, tukeylambda.pdf(x, lam),
        ...        'r-', lw=5, alpha=0.6, label='tukeylambda pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = tukeylambda(lam)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = tukeylambda.ppf([0.001, 0.5, 0.999], lam)
        >>> np.allclose([0.001, 0.5, 0.999], tukeylambda.cdf(vals, lam))
        True

        Generate random numbers:

        >>> r = tukeylambda.rvs(lam, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    uniform = <scipy.stats._continuous_distns.uniform_gen object>
        A uniform continuous random variable.

        In the standard form, the distribution is uniform on ``[0, 1]``. Using
        the parameters ``loc`` and ``scale``, one obtains the uniform distribution
        on ``[loc, loc + scale]``.

        As an instance of the `rv_continuous` class, `uniform` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import uniform
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = uniform.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(uniform.ppf(0.01),
        ...                 uniform.ppf(0.99), 100)
        >>> ax.plot(x, uniform.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='uniform pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = uniform()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = uniform.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], uniform.cdf(vals))
        True

        Generate random numbers:

        >>> r = uniform.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    uniform_direction = <scipy.stats._multivariate.uniform_direction_gen o...
    unitary_group = <scipy.stats._multivariate.unitary_group_gen object>
    vonmises = <scipy.stats._continuous_distns.vonmises_gen object>
        A Von Mises continuous random variable.

        As an instance of the `rv_continuous` class, `vonmises` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(kappa, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, kappa, loc=0, scale=1)
            Probability density function.
        logpdf(x, kappa, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, kappa, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, kappa, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, kappa, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, kappa, loc=0, scale=1)
            Log of the survival function.
        ppf(q, kappa, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, kappa, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, kappa, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(kappa, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(kappa, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(kappa,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(kappa, loc=0, scale=1)
            Median of the distribution.
        mean(kappa, loc=0, scale=1)
            Mean of the distribution.
        var(kappa, loc=0, scale=1)
            Variance of the distribution.
        std(kappa, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, kappa, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        scipy.stats.vonmises_fisher : Von-Mises Fisher distribution on a
                                      hypersphere

        Notes
        -----
        The probability density function for `vonmises` and `vonmises_line` is:

        .. math::

            f(x, \kappa) = \frac{ \exp(\kappa \cos(x)) }{ 2 \pi I_0(\kappa) }

        for :math:`-\pi \le x \le \pi`, :math:`\kappa \ge 0`. :math:`I_0` is the
        modified Bessel function of order zero (`scipy.special.i0`).

        `vonmises` is a circular distribution which does not restrict the
        distribution to a fixed interval. Currently, there is no circular
        distribution framework in SciPy. The ``cdf`` is implemented such that
        ``cdf(x + 2*np.pi) == cdf(x) + 1``.

        `vonmises_line` is the same distribution, defined on :math:`[-\pi, \pi]`
        on the real line. This is a regular (i.e. non-circular) distribution.

        Note about distribution parameters: `vonmises` and `vonmises_line` take
        ``kappa`` as a shape parameter (concentration) and ``loc`` as the location
        (circular mean). A ``scale`` parameter is accepted but does not have any
        effect.

        Examples
        --------
        Import the necessary modules.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import vonmises

        Define distribution parameters.

        >>> loc = 0.5 * np.pi  # circular mean
        >>> kappa = 1  # concentration

        Compute the probability density at ``x=0`` via the ``pdf`` method.

        >>> vonmises.pdf(0, loc=loc, kappa=kappa)
        0.12570826359722018

        Verify that the percentile function ``ppf`` inverts the cumulative
        distribution function ``cdf`` up to floating point accuracy.

        >>> x = 1
        >>> cdf_value = vonmises.cdf(x, loc=loc, kappa=kappa)
        >>> ppf_value = vonmises.ppf(cdf_value, loc=loc, kappa=kappa)
        >>> x, cdf_value, ppf_value
        (1, 0.31489339900904967, 1.0000000000000004)

        Draw 1000 random variates by calling the ``rvs`` method.

        >>> sample_size = 1000
        >>> sample = vonmises(loc=loc, kappa=kappa).rvs(sample_size)

        Plot the von Mises density on a Cartesian and polar grid to emphasize
        that it is a circular distribution.

        >>> fig = plt.figure(figsize=(12, 6))
        >>> left = plt.subplot(121)
        >>> right = plt.subplot(122, projection='polar')
        >>> x = np.linspace(-np.pi, np.pi, 500)
        >>> vonmises_pdf = vonmises.pdf(x, loc=loc, kappa=kappa)
        >>> ticks = [0, 0.15, 0.3]

        The left image contains the Cartesian plot.

        >>> left.plot(x, vonmises_pdf)
        >>> left.set_yticks(ticks)
        >>> number_of_bins = int(np.sqrt(sample_size))
        >>> left.hist(sample, density=True, bins=number_of_bins)
        >>> left.set_title("Cartesian plot")
        >>> left.set_xlim(-np.pi, np.pi)
        >>> left.grid(True)

        The right image contains the polar plot.

        >>> right.plot(x, vonmises_pdf, label="PDF")
        >>> right.set_yticks(ticks)
        >>> right.hist(sample, density=True, bins=number_of_bins,
        ...            label="Histogram")
        >>> right.set_title("Polar plot")
        >>> right.legend(bbox_to_anchor=(0.15, 1.06))

    vonmises_fisher = <scipy.stats._multivariate.vonmises_fisher_gen objec...
    vonmises_line = <scipy.stats._continuous_distns.vonmises_gen object>
        A Von Mises continuous random variable.

        As an instance of the `rv_continuous` class, `vonmises_line` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(kappa, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, kappa, loc=0, scale=1)
            Probability density function.
        logpdf(x, kappa, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, kappa, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, kappa, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, kappa, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, kappa, loc=0, scale=1)
            Log of the survival function.
        ppf(q, kappa, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, kappa, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, kappa, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(kappa, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(kappa, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(kappa,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(kappa, loc=0, scale=1)
            Median of the distribution.
        mean(kappa, loc=0, scale=1)
            Mean of the distribution.
        var(kappa, loc=0, scale=1)
            Variance of the distribution.
        std(kappa, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, kappa, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        scipy.stats.vonmises_fisher : Von-Mises Fisher distribution on a
                                      hypersphere

        Notes
        -----
        The probability density function for `vonmises` and `vonmises_line` is:

        .. math::

            f(x, \kappa) = \frac{ \exp(\kappa \cos(x)) }{ 2 \pi I_0(\kappa) }

        for :math:`-\pi \le x \le \pi`, :math:`\kappa \ge 0`. :math:`I_0` is the
        modified Bessel function of order zero (`scipy.special.i0`).

        `vonmises` is a circular distribution which does not restrict the
        distribution to a fixed interval. Currently, there is no circular
        distribution framework in SciPy. The ``cdf`` is implemented such that
        ``cdf(x + 2*np.pi) == cdf(x) + 1``.

        `vonmises_line` is the same distribution, defined on :math:`[-\pi, \pi]`
        on the real line. This is a regular (i.e. non-circular) distribution.

        Note about distribution parameters: `vonmises` and `vonmises_line` take
        ``kappa`` as a shape parameter (concentration) and ``loc`` as the location
        (circular mean). A ``scale`` parameter is accepted but does not have any
        effect.

        Examples
        --------
        Import the necessary modules.

        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import vonmises

        Define distribution parameters.

        >>> loc = 0.5 * np.pi  # circular mean
        >>> kappa = 1  # concentration

        Compute the probability density at ``x=0`` via the ``pdf`` method.

        >>> vonmises.pdf(0, loc=loc, kappa=kappa)
        0.12570826359722018

        Verify that the percentile function ``ppf`` inverts the cumulative
        distribution function ``cdf`` up to floating point accuracy.

        >>> x = 1
        >>> cdf_value = vonmises.cdf(x, loc=loc, kappa=kappa)
        >>> ppf_value = vonmises.ppf(cdf_value, loc=loc, kappa=kappa)
        >>> x, cdf_value, ppf_value
        (1, 0.31489339900904967, 1.0000000000000004)

        Draw 1000 random variates by calling the ``rvs`` method.

        >>> sample_size = 1000
        >>> sample = vonmises(loc=loc, kappa=kappa).rvs(sample_size)

        Plot the von Mises density on a Cartesian and polar grid to emphasize
        that it is a circular distribution.

        >>> fig = plt.figure(figsize=(12, 6))
        >>> left = plt.subplot(121)
        >>> right = plt.subplot(122, projection='polar')
        >>> x = np.linspace(-np.pi, np.pi, 500)
        >>> vonmises_pdf = vonmises.pdf(x, loc=loc, kappa=kappa)
        >>> ticks = [0, 0.15, 0.3]

        The left image contains the Cartesian plot.

        >>> left.plot(x, vonmises_pdf)
        >>> left.set_yticks(ticks)
        >>> number_of_bins = int(np.sqrt(sample_size))
        >>> left.hist(sample, density=True, bins=number_of_bins)
        >>> left.set_title("Cartesian plot")
        >>> left.set_xlim(-np.pi, np.pi)
        >>> left.grid(True)

        The right image contains the polar plot.

        >>> right.plot(x, vonmises_pdf, label="PDF")
        >>> right.set_yticks(ticks)
        >>> right.hist(sample, density=True, bins=number_of_bins,
        ...            label="Histogram")
        >>> right.set_title("Polar plot")
        >>> right.legend(bbox_to_anchor=(0.15, 1.06))

    wald = <scipy.stats._continuous_distns.wald_gen object>
        A Wald continuous random variable.

        As an instance of the `rv_continuous` class, `wald` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, loc=0, scale=1)
            Probability density function.
        logpdf(x, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, loc=0, scale=1)
            Log of the survival function.
        ppf(q, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(loc=0, scale=1)
            Median of the distribution.
        mean(loc=0, scale=1)
            Mean of the distribution.
        var(loc=0, scale=1)
            Variance of the distribution.
        std(loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `wald` is:

        .. math::

            f(x) = \frac{1}{\sqrt{2\pi x^3}} \exp(- \frac{ (x-1)^2 }{ 2x })

        for :math:`x >= 0`.

        `wald` is a special case of `invgauss` with ``mu=1``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``wald.pdf(x, loc, scale)`` is identically
        equivalent to ``wald.pdf(y) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import wald
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:


        >>> mean, var, skew, kurt = wald.stats(moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(wald.ppf(0.01),
        ...                 wald.ppf(0.99), 100)
        >>> ax.plot(x, wald.pdf(x),
        ...        'r-', lw=5, alpha=0.6, label='wald pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = wald()
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = wald.ppf([0.001, 0.5, 0.999])
        >>> np.allclose([0.001, 0.5, 0.999], wald.cdf(vals))
        True

        Generate random numbers:

        >>> r = wald.rvs(size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    weibull_max = <scipy.stats._continuous_distns.weibull_max_gen object>
        Weibull maximum continuous random variable.

        The Weibull Maximum Extreme Value distribution, from extreme value theory
        (Fisher-Gnedenko theorem), is the limiting distribution of rescaled
        maximum of iid random variables. This is the distribution of -X
        if X is from the `weibull_min` function.

        As an instance of the `rv_continuous` class, `weibull_max` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        weibull_min

        Notes
        -----
        The probability density function for `weibull_max` is:

        .. math::

            f(x, c) = c (-x)^{c-1} \exp(-(-x)^c)

        for :math:`x < 0`, :math:`c > 0`.

        `weibull_max` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``weibull_max.pdf(x, c, loc, scale)`` is identically
        equivalent to ``weibull_max.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        https://en.wikipedia.org/wiki/Weibull_distribution

        https://en.wikipedia.org/wiki/Fisher-Tippett-Gnedenko_theorem

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import weibull_max
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 2.87
        >>> mean, var, skew, kurt = weibull_max.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(weibull_max.ppf(0.01, c),
        ...                 weibull_max.ppf(0.99, c), 100)
        >>> ax.plot(x, weibull_max.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='weibull_max pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = weibull_max(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = weibull_max.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], weibull_max.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = weibull_max.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    weibull_min = <scipy.stats._continuous_distns.weibull_min_gen object>
        Weibull minimum continuous random variable.

        The Weibull Minimum Extreme Value distribution, from extreme value theory
        (Fisher-Gnedenko theorem), is also often simply called the Weibull
        distribution. It arises as the limiting distribution of the rescaled
        minimum of iid random variables.

        As an instance of the `rv_continuous` class, `weibull_min` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        See Also
        --------
        weibull_max, numpy.random.Generator.weibull, exponweib

        Notes
        -----
        The probability density function for `weibull_min` is:

        .. math::

            f(x, c) = c x^{c-1} \exp(-x^c)

        for :math:`x > 0`, :math:`c > 0`.

        `weibull_min` takes ``c`` as a shape parameter for :math:`c`.
        (named :math:`k` in Wikipedia article and :math:`a` in
        ``numpy.random.weibull``).  Special shape values are :math:`c=1` and
        :math:`c=2` where Weibull distribution reduces to the `expon` and
        `rayleigh` distributions respectively.

        Suppose ``X`` is an exponentially distributed random variable with
        scale ``s``. Then ``Y = X**k`` is `weibull_min` distributed with shape
        ``c = 1/k`` and scale ``s**k``.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``weibull_min.pdf(x, c, loc, scale)`` is identically
        equivalent to ``weibull_min.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        References
        ----------
        https://en.wikipedia.org/wiki/Weibull_distribution

        https://en.wikipedia.org/wiki/Fisher-Tippett-Gnedenko_theorem

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import weibull_min
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 1.79
        >>> mean, var, skew, kurt = weibull_min.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(weibull_min.ppf(0.01, c),
        ...                 weibull_min.ppf(0.99, c), 100)
        >>> ax.plot(x, weibull_min.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='weibull_min pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = weibull_min(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = weibull_min.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], weibull_min.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = weibull_min.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    wishart = <scipy.stats._multivariate.wishart_gen object>
        A Wishart random variable.

        The `df` keyword specifies the degrees of freedom. The `scale` keyword
        specifies the scale matrix, which must be symmetric and positive definite.
        In this context, the scale matrix is often interpreted in terms of a
        multivariate normal precision matrix (the inverse of the covariance
        matrix). These arguments must satisfy the relationship
        ``df > scale.ndim - 1``, but see notes on using the `rvs` method with
        ``df < scale.ndim``.

        Methods
        -------
        pdf(x, df, scale)
            Probability density function.
        logpdf(x, df, scale)
            Log of the probability density function.
        rvs(df, scale, size=1, random_state=None)
            Draw random samples from a Wishart distribution.
        entropy()
            Compute the differential entropy of the Wishart distribution.

        Parameters
        ----------
        df : int
            Degrees of freedom, must be greater than or equal to dimension of the
            scale matrix
        scale : array_like
            Symmetric positive definite scale matrix of the distribution
        seed : {None, int, np.random.RandomState, np.random.Generator}, optional
            Used for drawing random variates.
            If `seed` is `None`, the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is `None`.

        Raises
        ------
        scipy.linalg.LinAlgError
            If the scale matrix `scale` is not positive definite.

        See Also
        --------
        invwishart, chi2

        Notes
        -----


        The scale matrix `scale` must be a symmetric positive definite
        matrix. Singular matrices, including the symmetric positive semi-definite
        case, are not supported. Symmetry is not checked; only the lower triangular
        portion is used.

        The Wishart distribution is often denoted

        .. math::

            W_p(\nu, \Sigma)

        where :math:`\nu` is the degrees of freedom and :math:`\Sigma` is the
        :math:`p \times p` scale matrix.

        The probability density function for `wishart` has support over positive
        definite matrices :math:`S`; if :math:`S \sim W_p(\nu, \Sigma)`, then
        its PDF is given by:

        .. math::

            f(S) = \frac{|S|^{\frac{\nu - p - 1}{2}}}{2^{ \frac{\nu p}{2} }
                   |\Sigma|^\frac{\nu}{2} \Gamma_p \left ( \frac{\nu}{2} \right )}
                   \exp\left( -tr(\Sigma^{-1} S) / 2 \right)

        If :math:`S \sim W_p(\nu, \Sigma)` (Wishart) then
        :math:`S^{-1} \sim W_p^{-1}(\nu, \Sigma^{-1})` (inverse Wishart).

        If the scale matrix is 1-dimensional and equal to one, then the Wishart
        distribution :math:`W_1(\nu, 1)` collapses to the :math:`\chi^2(\nu)`
        distribution.

        The algorithm [2]_ implemented by the `rvs` method may
        produce numerically singular matrices with :math:`p - 1 < \nu < p`; the
        user may wish to check for this condition and generate replacement samples
        as necessary.


        .. versionadded:: 0.16.0

        References
        ----------
        .. [1] M.L. Eaton, "Multivariate Statistics: A Vector Space Approach",
               Wiley, 1983.
        .. [2] W.B. Smith and R.R. Hocking, "Algorithm AS 53: Wishart Variate
               Generator", Applied Statistics, vol. 21, pp. 341-345, 1972.

        Examples
        --------
        >>> import numpy as np
        >>> import matplotlib.pyplot as plt
        >>> from scipy.stats import wishart, chi2
        >>> x = np.linspace(1e-5, 8, 100)
        >>> w = wishart.pdf(x, df=3, scale=1); w[:5]
        array([ 0.00126156,  0.10892176,  0.14793434,  0.17400548,  0.1929669 ])
        >>> c = chi2.pdf(x, 3); c[:5]
        array([ 0.00126156,  0.10892176,  0.14793434,  0.17400548,  0.1929669 ])
        >>> plt.plot(x, w)
        >>> plt.show()

        The input quantiles can be any shape of array, as long as the last
        axis labels the components.

        Alternatively, the object may be called (as a function) to fix the degrees
        of freedom and scale parameters, returning a "frozen" Wishart random
        variable:

        >>> rv = wishart(df=1, scale=1)
        >>> # Frozen object with the same methods but holding the given
        >>> # degrees of freedom and scale fixed.

    wrapcauchy = <scipy.stats._continuous_distns.wrapcauchy_gen object>
        A wrapped Cauchy continuous random variable.

        As an instance of the `rv_continuous` class, `wrapcauchy` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(c, loc=0, scale=1, size=1, random_state=None)
            Random variates.
        pdf(x, c, loc=0, scale=1)
            Probability density function.
        logpdf(x, c, loc=0, scale=1)
            Log of the probability density function.
        cdf(x, c, loc=0, scale=1)
            Cumulative distribution function.
        logcdf(x, c, loc=0, scale=1)
            Log of the cumulative distribution function.
        sf(x, c, loc=0, scale=1)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(x, c, loc=0, scale=1)
            Log of the survival function.
        ppf(q, c, loc=0, scale=1)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, c, loc=0, scale=1)
            Inverse survival function (inverse of ``sf``).
        moment(order, c, loc=0, scale=1)
            Non-central moment of the specified order.
        stats(c, loc=0, scale=1, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(c, loc=0, scale=1)
            (Differential) entropy of the RV.
        fit(data)
            Parameter estimates for generic data.
            See `scipy.stats.rv_continuous.fit <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.fit.html#scipy.stats.rv_continuous.fit>`__ for detailed documentation of the
            keyword arguments.
        expect(func, args=(c,), loc=0, scale=1, lb=None, ub=None, conditional=False, **kwds)
            Expected value of a function (of one argument) with respect to the distribution.
        median(c, loc=0, scale=1)
            Median of the distribution.
        mean(c, loc=0, scale=1)
            Mean of the distribution.
        var(c, loc=0, scale=1)
            Variance of the distribution.
        std(c, loc=0, scale=1)
            Standard deviation of the distribution.
        interval(confidence, c, loc=0, scale=1)
            Confidence interval with equal areas around the median.

        Notes
        -----
        The probability density function for `wrapcauchy` is:

        .. math::

            f(x, c) = \frac{1-c^2}{2\pi (1+c^2 - 2c \cos(x))}

        for :math:`0 \le x \le 2\pi`, :math:`0 < c < 1`.

        `wrapcauchy` takes ``c`` as a shape parameter for :math:`c`.

        The probability density above is defined in the "standardized" form. To shift
        and/or scale the distribution use the ``loc`` and ``scale`` parameters.
        Specifically, ``wrapcauchy.pdf(x, c, loc, scale)`` is identically
        equivalent to ``wrapcauchy.pdf(y, c) / scale`` with
        ``y = (x - loc) / scale``. Note that shifting the location of a distribution
        does not make it a "noncentral" distribution; noncentral generalizations of
        some distributions are available in separate classes.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import wrapcauchy
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> c = 0.0311
        >>> mean, var, skew, kurt = wrapcauchy.stats(c, moments='mvsk')

        Display the probability density function (``pdf``):

        >>> x = np.linspace(wrapcauchy.ppf(0.01, c),
        ...                 wrapcauchy.ppf(0.99, c), 100)
        >>> ax.plot(x, wrapcauchy.pdf(x, c),
        ...        'r-', lw=5, alpha=0.6, label='wrapcauchy pdf')

        Alternatively, the distribution object can be called (as a function)
        to fix the shape, location and scale parameters. This returns a "frozen"
        RV object holding the given parameters fixed.

        Freeze the distribution and display the frozen ``pdf``:

        >>> rv = wrapcauchy(c)
        >>> ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

        Check accuracy of ``cdf`` and ``ppf``:

        >>> vals = wrapcauchy.ppf([0.001, 0.5, 0.999], c)
        >>> np.allclose([0.001, 0.5, 0.999], wrapcauchy.cdf(vals, c))
        True

        Generate random numbers:

        >>> r = wrapcauchy.rvs(c, size=1000)

        And compare the histogram:

        >>> ax.hist(r, density=True, bins='auto', histtype='stepfilled', alpha=0.2)
        >>> ax.set_xlim([x[0], x[-1]])
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

    yulesimon = <scipy.stats._discrete_distns.yulesimon_gen object>
        A Yule-Simon discrete random variable.

        As an instance of the `rv_discrete` class, `yulesimon` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(alpha, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, alpha, loc=0)
            Probability mass function.
        logpmf(k, alpha, loc=0)
            Log of the probability mass function.
        cdf(k, alpha, loc=0)
            Cumulative distribution function.
        logcdf(k, alpha, loc=0)
            Log of the cumulative distribution function.
        sf(k, alpha, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, alpha, loc=0)
            Log of the survival function.
        ppf(q, alpha, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, alpha, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(alpha, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(alpha, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(alpha,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(alpha, loc=0)
            Median of the distribution.
        mean(alpha, loc=0)
            Mean of the distribution.
        var(alpha, loc=0)
            Variance of the distribution.
        std(alpha, loc=0)
            Standard deviation of the distribution.
        interval(confidence, alpha, loc=0)
            Confidence interval with equal areas around the median.

        Notes
        -----

        The probability mass function for the `yulesimon` is:

        .. math::

            f(k) =  \alpha B(k, \alpha+1)

        for :math:`k=1,2,3,...`, where :math:`\alpha>0`.
        Here :math:`B` refers to the `scipy.special.beta` function.

        The sampling of random variates is based on pg 553, Section 6.3 of [1]_.
        Our notation maps to the referenced logic via :math:`\alpha=a-1`.

        For details see the wikipedia entry [2]_.

        References
        ----------
        .. [1] Devroye, Luc. "Non-uniform Random Variate Generation",
             (1986) Springer, New York.

        .. [2] https://en.wikipedia.org/wiki/Yule-Simon_distribution

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``yulesimon.pmf(k, alpha, loc)`` is identically
        equivalent to ``yulesimon.pmf(k - loc, alpha)``.

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import yulesimon
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> alpha = 11
        >>> mean, var, skew, kurt = yulesimon.stats(alpha, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(yulesimon.ppf(0.01, alpha),
        ...               yulesimon.ppf(0.99, alpha))
        >>> ax.plot(x, yulesimon.pmf(x, alpha), 'bo', ms=8, label='yulesimon pmf')
        >>> ax.vlines(x, 0, yulesimon.pmf(x, alpha), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = yulesimon(alpha)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = yulesimon.cdf(x, alpha)
        >>> np.allclose(x, yulesimon.ppf(prob, alpha))
        True

        Generate random numbers:

        >>> r = yulesimon.rvs(alpha, size=1000)

    zipf = <scipy.stats._discrete_distns.zipf_gen object>
        A Zipf (Zeta) discrete random variable.

        As an instance of the `rv_discrete` class, `zipf` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, a, loc=0)
            Probability mass function.
        logpmf(k, a, loc=0)
            Log of the probability mass function.
        cdf(k, a, loc=0)
            Cumulative distribution function.
        logcdf(k, a, loc=0)
            Log of the cumulative distribution function.
        sf(k, a, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, a, loc=0)
            Log of the survival function.
        ppf(q, a, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(a, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(a,), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, loc=0)
            Median of the distribution.
        mean(a, loc=0)
            Mean of the distribution.
        var(a, loc=0)
            Variance of the distribution.
        std(a, loc=0)
            Standard deviation of the distribution.
        interval(confidence, a, loc=0)
            Confidence interval with equal areas around the median.

        See Also
        --------
        zipfian

        Notes
        -----
        The probability mass function for `zipf` is:

        .. math::

            f(k, a) = \frac{1}{\zeta(a) k^a}

        for :math:`k \ge 1`, :math:`a > 1`.

        `zipf` takes :math:`a > 1` as shape parameter. :math:`\zeta` is the
        Riemann zeta function (`scipy.special.zeta`)

        The Zipf distribution is also known as the zeta distribution, which is
        a special case of the Zipfian distribution (`zipfian`).

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``zipf.pmf(k, a, loc)`` is identically
        equivalent to ``zipf.pmf(k - loc, a)``.

        References
        ----------
        .. [1] "Zeta Distribution", Wikipedia,
               https://en.wikipedia.org/wiki/Zeta_distribution

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import zipf
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a = 6.6
        >>> mean, var, skew, kurt = zipf.stats(a, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(zipf.ppf(0.01, a),
        ...               zipf.ppf(0.99, a))
        >>> ax.plot(x, zipf.pmf(x, a), 'bo', ms=8, label='zipf pmf')
        >>> ax.vlines(x, 0, zipf.pmf(x, a), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = zipf(a)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = zipf.cdf(x, a)
        >>> np.allclose(x, zipf.ppf(prob, a))
        True

        Generate random numbers:

        >>> r = zipf.rvs(a, size=1000)

        Confirm that `zipf` is the large `n` limit of `zipfian`.

        >>> import numpy as np
        >>> from scipy.stats import zipf, zipfian
        >>> k = np.arange(11)
        >>> np.allclose(zipf.pmf(k, a), zipfian.pmf(k, a, n=10000000))
        True

    zipfian = <scipy.stats._discrete_distns.zipfian_gen object>
        A Zipfian discrete random variable.

        As an instance of the `rv_discrete` class, `zipfian` object inherits from it
        a collection of generic methods (see below for the full list),
        and completes them with details specific for this particular distribution.

        Methods
        -------
        rvs(a, n, loc=0, size=1, random_state=None)
            Random variates.
        pmf(k, a, n, loc=0)
            Probability mass function.
        logpmf(k, a, n, loc=0)
            Log of the probability mass function.
        cdf(k, a, n, loc=0)
            Cumulative distribution function.
        logcdf(k, a, n, loc=0)
            Log of the cumulative distribution function.
        sf(k, a, n, loc=0)
            Survival function  (also defined as ``1 - cdf``, but `sf` is sometimes more accurate).
        logsf(k, a, n, loc=0)
            Log of the survival function.
        ppf(q, a, n, loc=0)
            Percent point function (inverse of ``cdf`` --- percentiles).
        isf(q, a, n, loc=0)
            Inverse survival function (inverse of ``sf``).
        stats(a, n, loc=0, moments='mv')
            Mean('m'), variance('v'), skew('s'), and/or kurtosis('k').
        entropy(a, n, loc=0)
            (Differential) entropy of the RV.
        expect(func, args=(a, n), loc=0, lb=None, ub=None, conditional=False)
            Expected value of a function (of one argument) with respect to the distribution.
        median(a, n, loc=0)
            Median of the distribution.
        mean(a, n, loc=0)
            Mean of the distribution.
        var(a, n, loc=0)
            Variance of the distribution.
        std(a, n, loc=0)
            Standard deviation of the distribution.
        interval(confidence, a, n, loc=0)
            Confidence interval with equal areas around the median.

        See Also
        --------
        zipf

        Notes
        -----
        The probability mass function for `zipfian` is:

        .. math::

            f(k, a, n) = \frac{1}{H_{n,a} k^a}

        for :math:`k \in \{1, 2, \dots, n-1, n\}`, :math:`a \ge 0`,
        :math:`n \in \{1, 2, 3, \dots\}`.

        `zipfian` takes :math:`a` and :math:`n` as shape parameters.
        :math:`H_{n,a}` is the :math:`n`:sup:`th` generalized harmonic
        number of order :math:`a`.

        The Zipfian distribution reduces to the Zipf (zeta) distribution as
        :math:`n \rightarrow \infty`.

        The probability mass function above is defined in the "standardized" form.
        To shift distribution use the ``loc`` parameter.
        Specifically, ``zipfian.pmf(k, a, n, loc)`` is identically
        equivalent to ``zipfian.pmf(k - loc, a, n)``.

        References
        ----------
        .. [1] "Zipf's Law", Wikipedia, https://en.wikipedia.org/wiki/Zipf's_law
        .. [2] Larry Leemis, "Zipf Distribution", Univariate Distribution
               Relationships. http://www.math.wm.edu/~leemis/chart/UDR/PDFs/Zipf.pdf

        Examples
        --------
        >>> import numpy as np
        >>> from scipy.stats import zipfian
        >>> import matplotlib.pyplot as plt
        >>> fig, ax = plt.subplots(1, 1)

        Calculate the first four moments:

        >>> a, n = 1.25, 10
        >>> mean, var, skew, kurt = zipfian.stats(a, n, moments='mvsk')

        Display the probability mass function (``pmf``):

        >>> x = np.arange(zipfian.ppf(0.01, a, n),
        ...               zipfian.ppf(0.99, a, n))
        >>> ax.plot(x, zipfian.pmf(x, a, n), 'bo', ms=8, label='zipfian pmf')
        >>> ax.vlines(x, 0, zipfian.pmf(x, a, n), colors='b', lw=5, alpha=0.5)

        Alternatively, the distribution object can be called (as a function)
        to fix the shape and location. This returns a "frozen" RV object holding
        the given parameters fixed.

        Freeze the distribution and display the frozen ``pmf``:

        >>> rv = zipfian(a, n)
        >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-', lw=1,
        ...         label='frozen pmf')
        >>> ax.legend(loc='best', frameon=False)
        >>> plt.show()

        Check accuracy of ``cdf`` and ``ppf``:

        >>> prob = zipfian.cdf(x, a, n)
        >>> np.allclose(x, zipfian.ppf(prob, a, n))
        True

        Generate random numbers:

        >>> r = zipfian.rvs(a, n, size=1000)

        Confirm that `zipfian` reduces to `zipf` for large `n`, `a > 1`.

        >>> import numpy as np
        >>> from scipy.stats import zipf, zipfian
        >>> k = np.arange(11)
        >>> np.allclose(zipfian.pmf(k, a=3.5, n=10000000), zipf.pmf(k, a=3.5))
        True

FILE
    c:\users\youse\appdata\local\programs\python\python312\lib\site-packages\scipy\stats\__init__.py

scipy.test
Python Library Documentation: PytestTester in module scipy._lib._testutils object

class PytestTester(builtins.object)
 |  PytestTester(module_name)
 |
 |  Run tests for this namespace
 |
 |  ``scipy.test()`` runs tests for all of SciPy, with the default settings.
 |  When used from a submodule (e.g., ``scipy.cluster.test()``, only the tests
 |  for that namespace are run.
 |
 |  Parameters
 |  ----------
 |  label : {'fast', 'full'}, optional
 |      Whether to run only the fast tests, or also those marked as slow.
 |      Default is 'fast'.
 |  verbose : int, optional
 |      Test output verbosity. Default is 1.
 |  extra_argv : list, optional
 |      Arguments to pass through to Pytest.
 |  doctests : bool, optional
 |      Whether to run doctests or not. Default is False.
 |  coverage : bool, optional
 |      Whether to run tests with code coverage measurements enabled.
 |      Default is False.
 |  tests : list of str, optional
 |      List of module names to run tests for. By default, uses the module
 |      from which the ``test`` function is called.
 |  parallel : int, optional
 |      Run tests in parallel with pytest-xdist, if number given is larger than
 |      1. Default is 1.
 |
 |  Methods defined here:
 |
 |  __call__(self, label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False, tests=None, parallel=None)
 |      Call self as a function.
 |
 |  __init__(self, module_name)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables
 |
 |  __weakref__
 |      list of weak references to the object