Skip to content

Commit d88f7fe

Browse files
authored
fix: add eig and eigvals to function lists
PR-URL: #996 Closes: #992
1 parent 269e59d commit d88f7fe

File tree

4 files changed

+140
-132
lines changed

4 files changed

+140
-132
lines changed

spec/2025.12/extensions/linear_algebra_functions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ A conforming implementation of this ``linalg`` extension must provide and suppor
9595
cross
9696
det
9797
diagonal
98+
eig
9899
eigh
100+
eigvals
99101
eigvalsh
100102
inv
101103
matmul

spec/draft/extensions/linear_algebra_functions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ A conforming implementation of this ``linalg`` extension must provide and suppor
9595
cross
9696
det
9797
diagonal
98+
eig
9899
eigh
100+
eigvals
99101
eigvalsh
100102
inv
101103
matmul

src/array_api_stubs/_2025_12/linalg.py

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"cross",
44
"det",
55
"diagonal",
6+
"eig",
67
"eigh",
8+
"eigvals",
79
"eigvalsh",
810
"inv",
911
"matmul",
@@ -163,29 +165,48 @@ def diagonal(x: array, /, *, offset: int = 0) -> array:
163165
"""
164166

165167

166-
def eigh(x: array, /) -> Tuple[array, array]:
168+
def eig(x: array, /) -> Tuple[array, array]:
167169
r"""
168-
Returns an eigenvalue decomposition of a complex Hermitian or real symmetric matrix (or a stack of matrices) ``x``.
170+
Returns eigenvalues and eigenvectors of a real or complex matrix (or stack of matrices) ``x``.
169171
170-
If ``x`` is real-valued, let :math:`\mathbb{K}` be the set of real numbers :math:`\mathbb{R}`, and, if ``x`` is complex-valued, let :math:`\mathbb{K}` be the set of complex numbers :math:`\mathbb{C}`.
172+
Let :math:`\mathbb{K}` be the union of the set of real numbers :math:`\mathbb{R}`
173+
and the set of complex numbers, :math:`\mathbb{C}`.
171174
172-
The **eigenvalue decomposition** of a complex Hermitian or real symmetric matrix :math:`x \in\ \mathbb{K}^{n \times n}` is defined as
175+
A real or complex value :math:`lambda \in \mathbb{K}` is an **eigenvalue** of a real
176+
or complex matrix :math:`x \in \mathbb{K}^{n \times n}` if there exists a real or complex vector
177+
:math:`v \in \mathbb{K}^{n}`, such that
173178
174179
.. math::
175-
x = Q \Lambda Q^H
176180
177-
with :math:`Q \in \mathbb{K}^{n \times n}` and :math:`\Lambda \in \mathbb{R}^n` and where :math:`Q^H` is the conjugate transpose when :math:`Q` is complex and the transpose when :math:`Q` is real-valued and :math:`\Lambda` is a diagonal matrix whose diagonal elements are the corresponding eigenvalues. When ``x`` is real-valued, :math:`Q` is orthogonal, and, when ``x`` is complex, :math:`Q` is unitary.
181+
x v = \lambda v
182+
183+
Then, :math:`v` is referred to as an **eigenvector** of :math:`x`, corresponding to
184+
the eigenvalue :math:`\lambda`.
185+
186+
A general matrix :math:`x \in \mathbb{K}^{n \times n}`
187+
188+
- has :math:`n` eigenvalues, which are defined as the roots (counted with multiplicity) of the
189+
polynomial :math:`p` of degree :math:`n` given by
190+
191+
.. math::
192+
193+
p(\lambda) = \operatorname{det}(x - \lambda I_n)
194+
195+
- does not in general have :math:`n` linearly independent eigenvectors if it has
196+
eigenvalues with multiplicity larger than one.
178197
179198
.. note::
180-
The eigenvalues of a complex Hermitian or real symmetric matrix are always real.
199+
The eigenvalues of a non-symmetric real matrix are in general complex: for
200+
:math:x \in \mathbb{R}^{n \times n}`, the eigenvalues, :math:`\lambda \in \mathbb{C}`,
201+
may or may not reside on the real axis of the complex plane.
181202
182203
.. warning::
183-
The eigenvectors of a symmetric matrix are not unique and are not continuous with respect to ``x``. Because eigenvectors are not unique, different hardware and software may compute different eigenvectors.
204+
The eigenvectors of a general matrix are not unique and are not continuous with respect to ``x``. Because eigenvectors are not unique, different hardware and software may compute different eigenvectors.
184205
185-
Non-uniqueness stems from the fact that multiplying an eigenvector by :math:`-1` when ``x`` is real-valued and by :math:`e^{\phi j}` (:math:`\phi \in \mathbb{R}`) when ``x`` is complex produces another set of valid eigenvectors.
206+
For eigenvalues of multiplity :math:`s=1`, the non-uniqueness stems from the fact that multiplying an eigenvector by :math:`-1` when ``x`` is real-valued and by :math:`e^{\phi j}` (:math:`\phi \in \mathbb{R}`) when ``x`` is complex produces another set of valid eigenvectors.
186207
187-
.. note::
188-
Whether an array library explicitly checks whether an input array is Hermitian or a symmetric matrix (or a stack of matrices) is implementation-defined.
208+
For eigenvalues of multiplity :math:`s > 1`, the :math:`s` computed eigenvectors may be repeated or
209+
have entries differ by an order of machine epsilon for the data type of :math:`x`.
189210
190211
Parameters
191212
----------
@@ -197,36 +218,43 @@ def eigh(x: array, /) -> Tuple[array, array]:
197218
out: Tuple[array, array]
198219
a namedtuple (``eigenvalues``, ``eigenvectors``) whose
199220
200-
- first element must have the field name ``eigenvalues`` (corresponding to :math:`\operatorname{diag}\Lambda` above) and must be an array consisting of computed eigenvalues. The array containing the eigenvalues must have shape ``(..., M)`` and must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then ``eigenvalues`` must be ``float64``).
201-
- second element must have the field name ``eigenvectors`` (corresponding to :math:`Q` above) and must be an array where the columns of the inner most matrices contain the computed eigenvectors. These matrices must be orthogonal. The array containing the eigenvectors must have shape ``(..., M, M)`` and must have the same data type as ``x``.
221+
- first element must have the field name ``eigenvalues`` (corresponding to :math:`\lambda` above) and must be an array consisting of computed eigenvalues. The array containing the eigenvalues must have shape ``(..., M)`` and must have a complex floating-point array data type having the same precision as that of ``x`` (e.g., if ``x`` has a ``float32`` data type, ``eigenvalues`` must have the ``complex64`` data type; if ``x`` has a ``float64`` data type, ``eigenvalues`` have the ``complex128`` data type).
222+
223+
- second element must have the field name ``eigenvectors`` (corresponding to :math:`v` above) and must be an array where the columns of the inner most matrices contain the computed eigenvectors. These matrices must be orthogonal. The array containing the eigenvectors must have shape ``(..., M, M)`` and must have the same data type as ``eigenvalues``.
202224
203225
Notes
204226
-----
205227
228+
- Eigenvalue sort order is left unspecified and is thus implementation-dependent.
229+
206230
.. note::
207-
Eigenvalue sort order is left unspecified and is thus implementation-dependent.
231+
For real symmetric or complex Hermitian matrices, prefer using the ``eigh`` routine.
208232
209-
.. versionchanged:: 2022.12
210-
Added complex data type support.
233+
.. versionadded:: 2025.12
211234
"""
212235

213236

214-
def eigvalsh(x: array, /) -> array:
237+
def eigh(x: array, /) -> Tuple[array, array]:
215238
r"""
216-
Returns the eigenvalues of a complex Hermitian or real symmetric matrix (or a stack of matrices) ``x``.
239+
Returns an eigenvalue decomposition of a complex Hermitian or real symmetric matrix (or a stack of matrices) ``x``.
217240
218241
If ``x`` is real-valued, let :math:`\mathbb{K}` be the set of real numbers :math:`\mathbb{R}`, and, if ``x`` is complex-valued, let :math:`\mathbb{K}` be the set of complex numbers :math:`\mathbb{C}`.
219242
220-
The **eigenvalues** of a complex Hermitian or real symmetric matrix :math:`x \in\ \mathbb{K}^{n \times n}` are defined as the roots (counted with multiplicity) of the polynomial :math:`p` of degree :math:`n` given by
243+
The **eigenvalue decomposition** of a complex Hermitian or real symmetric matrix :math:`x \in\ \mathbb{K}^{n \times n}` is defined as
221244
222245
.. math::
223-
p(\lambda) = \operatorname{det}(x - \lambda I_n)
246+
x = Q \Lambda Q^H
224247
225-
where :math:`\lambda \in \mathbb{R}` and where :math:`I_n` is the *n*-dimensional identity matrix.
248+
with :math:`Q \in \mathbb{K}^{n \times n}` and :math:`\Lambda \in \mathbb{R}^n` and where :math:`Q^H` is the conjugate transpose when :math:`Q` is complex and the transpose when :math:`Q` is real-valued and :math:`\Lambda` is a diagonal matrix whose diagonal elements are the corresponding eigenvalues. When ``x`` is real-valued, :math:`Q` is orthogonal, and, when ``x`` is complex, :math:`Q` is unitary.
226249
227250
.. note::
228251
The eigenvalues of a complex Hermitian or real symmetric matrix are always real.
229252
253+
.. warning::
254+
The eigenvectors of a symmetric matrix are not unique and are not continuous with respect to ``x``. Because eigenvectors are not unique, different hardware and software may compute different eigenvectors.
255+
256+
Non-uniqueness stems from the fact that multiplying an eigenvector by :math:`-1` when ``x`` is real-valued and by :math:`e^{\phi j}` (:math:`\phi \in \mathbb{R}`) when ``x`` is complex produces another set of valid eigenvectors.
257+
230258
.. note::
231259
Whether an array library explicitly checks whether an input array is Hermitian or a symmetric matrix (or a stack of matrices) is implementation-defined.
232260
@@ -237,8 +265,11 @@ def eigvalsh(x: array, /) -> array:
237265
238266
Returns
239267
-------
240-
out: array
241-
an array containing the computed eigenvalues. The returned array must have shape ``(..., M)`` and have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then must have a ``float64`` data type).
268+
out: Tuple[array, array]
269+
a namedtuple (``eigenvalues``, ``eigenvectors``) whose
270+
271+
- first element must have the field name ``eigenvalues`` (corresponding to :math:`\operatorname{diag}\Lambda` above) and must be an array consisting of computed eigenvalues. The array containing the eigenvalues must have shape ``(..., M)`` and must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then ``eigenvalues`` must be ``float64``).
272+
- second element must have the field name ``eigenvectors`` (corresponding to :math:`Q` above) and must be an array where the columns of the inner most matrices contain the computed eigenvectors. These matrices must be orthogonal. The array containing the eigenvectors must have shape ``(..., M, M)`` and must have the same data type as ``x``.
242273
243274
Notes
244275
-----
@@ -251,48 +282,24 @@ def eigvalsh(x: array, /) -> array:
251282
"""
252283

253284

254-
def eig(x: array, /) -> Tuple[array, array]:
285+
def eigvalsh(x: array, /) -> array:
255286
r"""
256-
Returns eigenvalues and eigenvectors of a real or complex matrix (or stack of matrices) ``x``.
287+
Returns the eigenvalues of a complex Hermitian or real symmetric matrix (or a stack of matrices) ``x``.
257288
258-
Let :math:`\mathbb{K}` be the union of the set of real numbers :math:`\mathbb{R}`
259-
and the set of complex numbers, :math:`\mathbb{C}`.
289+
If ``x`` is real-valued, let :math:`\mathbb{K}` be the set of real numbers :math:`\mathbb{R}`, and, if ``x`` is complex-valued, let :math:`\mathbb{K}` be the set of complex numbers :math:`\mathbb{C}`.
260290
261-
A real or complex value :math:`lambda \in \mathbb{K}` is an **eigenvalue** of a real
262-
or complex matrix :math:`x \in \mathbb{K}^{n \times n}` if there exists a real or complex vector
263-
:math:`v \in \mathbb{K}^{n}`, such that
291+
The **eigenvalues** of a complex Hermitian or real symmetric matrix :math:`x \in\ \mathbb{K}^{n \times n}` are defined as the roots (counted with multiplicity) of the polynomial :math:`p` of degree :math:`n` given by
264292
265293
.. math::
294+
p(\lambda) = \operatorname{det}(x - \lambda I_n)
266295
267-
x v = \lambda v
268-
269-
Then, :math:`v` is referred to as an **eigenvector** of :math:`x`, corresponding to
270-
the eigenvalue :math:`\lambda`.
271-
272-
A general matrix :math:`x \in \mathbb{K}^{n \times n}`
273-
274-
- has :math:`n` eigenvalues, which are defined as the roots (counted with multiplicity) of the
275-
polynomial :math:`p` of degree :math:`n` given by
276-
277-
.. math::
278-
279-
p(\lambda) = \operatorname{det}(x - \lambda I_n)
280-
281-
- does not in general have :math:`n` linearly independent eigenvectors if it has
282-
eigenvalues with multiplicity larger than one.
296+
where :math:`\lambda \in \mathbb{R}` and where :math:`I_n` is the *n*-dimensional identity matrix.
283297
284298
.. note::
285-
The eigenvalues of a non-symmetric real matrix are in general complex: for
286-
:math:x \in \mathbb{R}^{n \times n}`, the eigenvalues, :math:`\lambda \in \mathbb{C}`,
287-
may or may not reside on the real axis of the complex plane.
288-
289-
.. warning::
290-
The eigenvectors of a general matrix are not unique and are not continuous with respect to ``x``. Because eigenvectors are not unique, different hardware and software may compute different eigenvectors.
291-
292-
For eigenvalues of multiplity :math:`s=1`, the non-uniqueness stems from the fact that multiplying an eigenvector by :math:`-1` when ``x`` is real-valued and by :math:`e^{\phi j}` (:math:`\phi \in \mathbb{R}`) when ``x`` is complex produces another set of valid eigenvectors.
299+
The eigenvalues of a complex Hermitian or real symmetric matrix are always real.
293300
294-
For eigenvalues of multiplity :math:`s > 1`, the :math:`s` computed eigenvectors may be repeated or
295-
have entries differ by an order of machine epsilon for the data type of :math:`x`.
301+
.. note::
302+
Whether an array library explicitly checks whether an input array is Hermitian or a symmetric matrix (or a stack of matrices) is implementation-defined.
296303
297304
Parameters
298305
----------
@@ -301,22 +308,17 @@ def eig(x: array, /) -> Tuple[array, array]:
301308
302309
Returns
303310
-------
304-
out: Tuple[array, array]
305-
a namedtuple (``eigenvalues``, ``eigenvectors``) whose
306-
307-
- first element must have the field name ``eigenvalues`` (corresponding to :math:`\lambda` above) and must be an array consisting of computed eigenvalues. The array containing the eigenvalues must have shape ``(..., M)`` and must have a complex floating-point array data type having the same precision as that of ``x`` (e.g., if ``x`` has a ``float32`` data type, ``eigenvalues`` must have the ``complex64`` data type; if ``x`` has a ``float64`` data type, ``eigenvalues`` have the ``complex128`` data type).
308-
309-
- second element must have the field name ``eigenvectors`` (corresponding to :math:`v` above) and must be an array where the columns of the inner most matrices contain the computed eigenvectors. These matrices must be orthogonal. The array containing the eigenvectors must have shape ``(..., M, M)`` and must have the same data type as ``eigenvalues``.
311+
out: array
312+
an array containing the computed eigenvalues. The returned array must have shape ``(..., M)`` and have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then must have a ``float64`` data type).
310313
311314
Notes
312315
-----
313316
314-
- Eigenvalue sort order is left unspecified and is thus implementation-dependent.
315-
316317
.. note::
317-
For real symmetric or complex Hermitian matrices, prefer using the ``eigh`` routine.
318+
Eigenvalue sort order is left unspecified and is thus implementation-dependent.
318319
319-
.. versionadded:: 2025.12
320+
.. versionchanged:: 2022.12
321+
Added complex data type support.
320322
"""
321323

322324

0 commit comments

Comments
 (0)