Updated script that can be controled by Nodejs web app

This commit is contained in:
mac OS
2024-11-25 12:24:18 +07:00
parent c440eda1f4
commit 8b0ab2bd3a
8662 changed files with 1803808 additions and 34 deletions

View File

@ -0,0 +1,95 @@
"""
``numpy.linalg``
================
The NumPy linear algebra functions rely on BLAS and LAPACK to provide efficient
low level implementations of standard linear algebra algorithms. Those
libraries may be provided by NumPy itself using C versions of a subset of their
reference implementations but, when possible, highly optimized libraries that
take advantage of specialized processor functionality are preferred. Examples
of such libraries are OpenBLAS, MKL (TM), and ATLAS. Because those libraries
are multithreaded and processor dependent, environmental variables and external
packages such as threadpoolctl may be needed to control the number of threads
or specify the processor architecture.
- OpenBLAS: https://www.openblas.net/
- threadpoolctl: https://github.com/joblib/threadpoolctl
Please note that the most-used linear algebra functions in NumPy are present in
the main ``numpy`` namespace rather than in ``numpy.linalg``. There are:
``dot``, ``vdot``, ``inner``, ``outer``, ``matmul``, ``tensordot``, ``einsum``,
``einsum_path`` and ``kron``.
Functions present in numpy.linalg are listed below.
Matrix and vector products
--------------------------
cross
multi_dot
matrix_power
tensordot
matmul
Decompositions
--------------
cholesky
outer
qr
svd
svdvals
Matrix eigenvalues
------------------
eig
eigh
eigvals
eigvalsh
Norms and other numbers
-----------------------
norm
matrix_norm
vector_norm
cond
det
matrix_rank
slogdet
trace (Array API compatible)
Solving equations and inverting matrices
----------------------------------------
solve
tensorsolve
lstsq
inv
pinv
tensorinv
Other matrix operations
-----------------------
diagonal (Array API compatible)
matrix_transpose (Array API compatible)
Exceptions
----------
LinAlgError
"""
# To get sub-modules
from . import linalg # deprecated in NumPy 2.0
from . import _linalg
from ._linalg import *
__all__ = _linalg.__all__.copy()
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
del PytestTester

View File

@ -0,0 +1,44 @@
from numpy.linalg._linalg import (
matrix_power as matrix_power,
solve as solve,
tensorsolve as tensorsolve,
tensorinv as tensorinv,
inv as inv,
cholesky as cholesky,
outer as outer,
eigvals as eigvals,
eigvalsh as eigvalsh,
pinv as pinv,
slogdet as slogdet,
det as det,
svd as svd,
svdvals as svdvals,
eig as eig,
eigh as eigh,
lstsq as lstsq,
norm as norm,
matrix_norm as matrix_norm,
vector_norm as vector_norm,
qr as qr,
cond as cond,
matrix_rank as matrix_rank,
multi_dot as multi_dot,
matmul as matmul,
trace as trace,
diagonal as diagonal,
cross as cross,
)
from numpy._core.fromnumeric import (
matrix_transpose as matrix_transpose
)
from numpy._core.numeric import (
tensordot as tensordot, vecdot as vecdot
)
from numpy._pytesttester import PytestTester
__all__: list[str]
test: PytestTester
class LinAlgError(Exception): ...

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,427 @@
from collections.abc import Iterable
from typing import (
Literal as L,
overload,
TypeAlias,
TypeVar,
Any,
SupportsIndex,
SupportsInt,
NamedTuple,
Generic,
)
import numpy as np
from numpy import (
generic,
floating,
complexfloating,
signedinteger,
unsignedinteger,
timedelta64,
object_,
int32,
float64,
complex128,
)
from numpy.linalg import LinAlgError as LinAlgError
from numpy._typing import (
NDArray,
ArrayLike,
_ArrayLikeUnknown,
_ArrayLikeBool_co,
_ArrayLikeInt_co,
_ArrayLikeUInt_co,
_ArrayLikeFloat_co,
_ArrayLikeComplex_co,
_ArrayLikeTD64_co,
_ArrayLikeObject_co,
DTypeLike,
)
_T = TypeVar("_T")
_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
_SCT = TypeVar("_SCT", bound=generic, covariant=True)
_SCT2 = TypeVar("_SCT2", bound=generic, covariant=True)
_2Tuple: TypeAlias = tuple[_T, _T]
_ModeKind: TypeAlias = L["reduced", "complete", "r", "raw"]
__all__: list[str]
class EigResult(NamedTuple):
eigenvalues: NDArray[Any]
eigenvectors: NDArray[Any]
class EighResult(NamedTuple):
eigenvalues: NDArray[Any]
eigenvectors: NDArray[Any]
class QRResult(NamedTuple):
Q: NDArray[Any]
R: NDArray[Any]
class SlogdetResult(NamedTuple):
# TODO: `sign` and `logabsdet` are scalars for input 2D arrays and
# a `(x.ndim - 2)`` dimensionl arrays otherwise
sign: Any
logabsdet: Any
class SVDResult(NamedTuple):
U: NDArray[Any]
S: NDArray[Any]
Vh: NDArray[Any]
@overload
def tensorsolve(
a: _ArrayLikeInt_co,
b: _ArrayLikeInt_co,
axes: None | Iterable[int] =...,
) -> NDArray[float64]: ...
@overload
def tensorsolve(
a: _ArrayLikeFloat_co,
b: _ArrayLikeFloat_co,
axes: None | Iterable[int] =...,
) -> NDArray[floating[Any]]: ...
@overload
def tensorsolve(
a: _ArrayLikeComplex_co,
b: _ArrayLikeComplex_co,
axes: None | Iterable[int] =...,
) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def solve(
a: _ArrayLikeInt_co,
b: _ArrayLikeInt_co,
) -> NDArray[float64]: ...
@overload
def solve(
a: _ArrayLikeFloat_co,
b: _ArrayLikeFloat_co,
) -> NDArray[floating[Any]]: ...
@overload
def solve(
a: _ArrayLikeComplex_co,
b: _ArrayLikeComplex_co,
) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def tensorinv(
a: _ArrayLikeInt_co,
ind: int = ...,
) -> NDArray[float64]: ...
@overload
def tensorinv(
a: _ArrayLikeFloat_co,
ind: int = ...,
) -> NDArray[floating[Any]]: ...
@overload
def tensorinv(
a: _ArrayLikeComplex_co,
ind: int = ...,
) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def inv(a: _ArrayLikeInt_co) -> NDArray[float64]: ...
@overload
def inv(a: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ...
@overload
def inv(a: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
# TODO: The supported input and output dtypes are dependent on the value of `n`.
# For example: `n < 0` always casts integer types to float64
def matrix_power(
a: _ArrayLikeComplex_co | _ArrayLikeObject_co,
n: SupportsIndex,
) -> NDArray[Any]: ...
@overload
def cholesky(a: _ArrayLikeInt_co) -> NDArray[float64]: ...
@overload
def cholesky(a: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ...
@overload
def cholesky(a: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def outer(x1: _ArrayLikeUnknown, x2: _ArrayLikeUnknown) -> NDArray[Any]: ...
@overload
def outer(x1: _ArrayLikeBool_co, x2: _ArrayLikeBool_co) -> NDArray[np.bool]: ...
@overload
def outer(x1: _ArrayLikeUInt_co, x2: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ...
@overload
def outer(x1: _ArrayLikeInt_co, x2: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
@overload
def outer(x1: _ArrayLikeFloat_co, x2: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ...
@overload
def outer(
x1: _ArrayLikeComplex_co,
x2: _ArrayLikeComplex_co,
) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def outer(
x1: _ArrayLikeTD64_co,
x2: _ArrayLikeTD64_co,
out: None = ...,
) -> NDArray[timedelta64]: ...
@overload
def outer(x1: _ArrayLikeObject_co, x2: _ArrayLikeObject_co) -> NDArray[object_]: ...
@overload
def outer(
x1: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co,
x2: _ArrayLikeComplex_co | _ArrayLikeTD64_co | _ArrayLikeObject_co,
) -> _ArrayType: ...
@overload
def qr(a: _ArrayLikeInt_co, mode: _ModeKind = ...) -> QRResult: ...
@overload
def qr(a: _ArrayLikeFloat_co, mode: _ModeKind = ...) -> QRResult: ...
@overload
def qr(a: _ArrayLikeComplex_co, mode: _ModeKind = ...) -> QRResult: ...
@overload
def eigvals(a: _ArrayLikeInt_co) -> NDArray[float64] | NDArray[complex128]: ...
@overload
def eigvals(a: _ArrayLikeFloat_co) -> NDArray[floating[Any]] | NDArray[complexfloating[Any, Any]]: ...
@overload
def eigvals(a: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def eigvalsh(a: _ArrayLikeInt_co, UPLO: L["L", "U", "l", "u"] = ...) -> NDArray[float64]: ...
@overload
def eigvalsh(a: _ArrayLikeComplex_co, UPLO: L["L", "U", "l", "u"] = ...) -> NDArray[floating[Any]]: ...
@overload
def eig(a: _ArrayLikeInt_co) -> EigResult: ...
@overload
def eig(a: _ArrayLikeFloat_co) -> EigResult: ...
@overload
def eig(a: _ArrayLikeComplex_co) -> EigResult: ...
@overload
def eigh(
a: _ArrayLikeInt_co,
UPLO: L["L", "U", "l", "u"] = ...,
) -> EighResult: ...
@overload
def eigh(
a: _ArrayLikeFloat_co,
UPLO: L["L", "U", "l", "u"] = ...,
) -> EighResult: ...
@overload
def eigh(
a: _ArrayLikeComplex_co,
UPLO: L["L", "U", "l", "u"] = ...,
) -> EighResult: ...
@overload
def svd(
a: _ArrayLikeInt_co,
full_matrices: bool = ...,
compute_uv: L[True] = ...,
hermitian: bool = ...,
) -> SVDResult: ...
@overload
def svd(
a: _ArrayLikeFloat_co,
full_matrices: bool = ...,
compute_uv: L[True] = ...,
hermitian: bool = ...,
) -> SVDResult: ...
@overload
def svd(
a: _ArrayLikeComplex_co,
full_matrices: bool = ...,
compute_uv: L[True] = ...,
hermitian: bool = ...,
) -> SVDResult: ...
@overload
def svd(
a: _ArrayLikeInt_co,
full_matrices: bool = ...,
compute_uv: L[False] = ...,
hermitian: bool = ...,
) -> NDArray[float64]: ...
@overload
def svd(
a: _ArrayLikeComplex_co,
full_matrices: bool = ...,
compute_uv: L[False] = ...,
hermitian: bool = ...,
) -> NDArray[floating[Any]]: ...
def svdvals(
x: _ArrayLikeInt_co | _ArrayLikeFloat_co | _ArrayLikeComplex_co
) -> NDArray[floating[Any]]: ...
# TODO: Returns a scalar for 2D arrays and
# a `(x.ndim - 2)`` dimensionl array otherwise
def cond(x: _ArrayLikeComplex_co, p: None | float | L["fro", "nuc"] = ...) -> Any: ...
# TODO: Returns `int` for <2D arrays and `intp` otherwise
def matrix_rank(
A: _ArrayLikeComplex_co,
tol: None | _ArrayLikeFloat_co = ...,
hermitian: bool = ...,
*,
rtol: None | _ArrayLikeFloat_co = ...,
) -> Any: ...
@overload
def pinv(
a: _ArrayLikeInt_co,
rcond: _ArrayLikeFloat_co = ...,
hermitian: bool = ...,
) -> NDArray[float64]: ...
@overload
def pinv(
a: _ArrayLikeFloat_co,
rcond: _ArrayLikeFloat_co = ...,
hermitian: bool = ...,
) -> NDArray[floating[Any]]: ...
@overload
def pinv(
a: _ArrayLikeComplex_co,
rcond: _ArrayLikeFloat_co = ...,
hermitian: bool = ...,
) -> NDArray[complexfloating[Any, Any]]: ...
# TODO: Returns a 2-tuple of scalars for 2D arrays and
# a 2-tuple of `(a.ndim - 2)`` dimensionl arrays otherwise
def slogdet(a: _ArrayLikeComplex_co) -> SlogdetResult: ...
# TODO: Returns a 2-tuple of scalars for 2D arrays and
# a 2-tuple of `(a.ndim - 2)`` dimensionl arrays otherwise
def det(a: _ArrayLikeComplex_co) -> Any: ...
@overload
def lstsq(a: _ArrayLikeInt_co, b: _ArrayLikeInt_co, rcond: None | float = ...) -> tuple[
NDArray[float64],
NDArray[float64],
int32,
NDArray[float64],
]: ...
@overload
def lstsq(a: _ArrayLikeFloat_co, b: _ArrayLikeFloat_co, rcond: None | float = ...) -> tuple[
NDArray[floating[Any]],
NDArray[floating[Any]],
int32,
NDArray[floating[Any]],
]: ...
@overload
def lstsq(a: _ArrayLikeComplex_co, b: _ArrayLikeComplex_co, rcond: None | float = ...) -> tuple[
NDArray[complexfloating[Any, Any]],
NDArray[floating[Any]],
int32,
NDArray[floating[Any]],
]: ...
@overload
def norm(
x: ArrayLike,
ord: None | float | L["fro", "nuc"] = ...,
axis: None = ...,
keepdims: bool = ...,
) -> floating[Any]: ...
@overload
def norm(
x: ArrayLike,
ord: None | float | L["fro", "nuc"] = ...,
axis: SupportsInt | SupportsIndex | tuple[int, ...] = ...,
keepdims: bool = ...,
) -> Any: ...
@overload
def matrix_norm(
x: ArrayLike,
ord: None | float | L["fro", "nuc"] = ...,
keepdims: bool = ...,
) -> floating[Any]: ...
@overload
def matrix_norm(
x: ArrayLike,
ord: None | float | L["fro", "nuc"] = ...,
keepdims: bool = ...,
) -> Any: ...
@overload
def vector_norm(
x: ArrayLike,
axis: None = ...,
ord: None | float = ...,
keepdims: bool = ...,
) -> floating[Any]: ...
@overload
def vector_norm(
x: ArrayLike,
axis: SupportsInt | SupportsIndex | tuple[int, ...] = ...,
ord: None | float = ...,
keepdims: bool = ...,
) -> Any: ...
# TODO: Returns a scalar or array
def multi_dot(
arrays: Iterable[_ArrayLikeComplex_co | _ArrayLikeObject_co | _ArrayLikeTD64_co],
*,
out: None | NDArray[Any] = ...,
) -> Any: ...
def diagonal(
x: ArrayLike, # >= 2D array
offset: SupportsIndex = ...,
) -> NDArray[Any]: ...
def trace(
x: ArrayLike, # >= 2D array
offset: SupportsIndex = ...,
dtype: DTypeLike = ...,
) -> Any: ...
@overload
def cross(
a: _ArrayLikeUInt_co,
b: _ArrayLikeUInt_co,
axis: int = ...,
) -> NDArray[unsignedinteger[Any]]: ...
@overload
def cross(
a: _ArrayLikeInt_co,
b: _ArrayLikeInt_co,
axis: int = ...,
) -> NDArray[signedinteger[Any]]: ...
@overload
def cross(
a: _ArrayLikeFloat_co,
b: _ArrayLikeFloat_co,
axis: int = ...,
) -> NDArray[floating[Any]]: ...
@overload
def cross(
a: _ArrayLikeComplex_co,
b: _ArrayLikeComplex_co,
axis: int = ...,
) -> NDArray[complexfloating[Any, Any]]: ...
@overload
def matmul(
x1: _ArrayLikeInt_co,
x2: _ArrayLikeInt_co,
) -> NDArray[signedinteger[Any]]: ...
@overload
def matmul(
x1: _ArrayLikeUInt_co,
x2: _ArrayLikeUInt_co,
) -> NDArray[unsignedinteger[Any]]: ...
@overload
def matmul(
x1: _ArrayLikeFloat_co,
x2: _ArrayLikeFloat_co,
) -> NDArray[floating[Any]]: ...
@overload
def matmul(
x1: _ArrayLikeComplex_co,
x2: _ArrayLikeComplex_co,
) -> NDArray[complexfloating[Any, Any]]: ...

View File

@ -0,0 +1,16 @@
def __getattr__(attr_name):
import warnings
from numpy.linalg import _linalg
ret = getattr(_linalg, attr_name, None)
if ret is None:
raise AttributeError(
f"module 'numpy.linalg.linalg' has no attribute {attr_name}")
warnings.warn(
"The numpy.linalg.linalg has been made private and renamed to "
"numpy.linalg._linalg. All public functions exported by it are "
f"available from numpy.linalg. Please use numpy.linalg.{attr_name} "
"instead.",
DeprecationWarning,
stacklevel=3
)
return ret

View File

@ -0,0 +1,20 @@
"""Test deprecation and future warnings.
"""
import numpy as np
from numpy.testing import assert_warns
def test_qr_mode_full_future_warning():
"""Check mode='full' FutureWarning.
In numpy 1.8 the mode options 'full' and 'economic' in linalg.qr were
deprecated. The release date will probably be sometime in the summer
of 2013.
"""
a = np.eye(2)
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='full')
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='f')
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='economic')
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='e')

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,178 @@
""" Test functions for linalg module
"""
import warnings
import pytest
import numpy as np
from numpy import linalg, arange, float64, array, dot, transpose
from numpy.testing import (
assert_, assert_raises, assert_equal, assert_array_equal,
assert_array_almost_equal, assert_array_less
)
class TestRegression:
def test_eig_build(self):
# Ticket #652
rva = array([1.03221168e+02 + 0.j,
-1.91843603e+01 + 0.j,
-6.04004526e-01 + 15.84422474j,
-6.04004526e-01 - 15.84422474j,
-1.13692929e+01 + 0.j,
-6.57612485e-01 + 10.41755503j,
-6.57612485e-01 - 10.41755503j,
1.82126812e+01 + 0.j,
1.06011014e+01 + 0.j,
7.80732773e+00 + 0.j,
-7.65390898e-01 + 0.j,
1.51971555e-15 + 0.j,
-1.51308713e-15 + 0.j])
a = arange(13 * 13, dtype=float64)
a.shape = (13, 13)
a = a % 17
va, ve = linalg.eig(a)
va.sort()
rva.sort()
assert_array_almost_equal(va, rva)
def test_eigh_build(self):
# Ticket 662.
rvals = [68.60568999, 89.57756725, 106.67185574]
cov = array([[77.70273908, 3.51489954, 15.64602427],
[3.51489954, 88.97013878, -1.07431931],
[15.64602427, -1.07431931, 98.18223512]])
vals, vecs = linalg.eigh(cov)
assert_array_almost_equal(vals, rvals)
def test_svd_build(self):
# Ticket 627.
a = array([[0., 1.], [1., 1.], [2., 1.], [3., 1.]])
m, n = a.shape
u, s, vh = linalg.svd(a)
b = dot(transpose(u[:, n:]), a)
assert_array_almost_equal(b, np.zeros((2, 2)))
def test_norm_vector_badarg(self):
# Regression for #786: Frobenius norm for vectors raises
# ValueError.
assert_raises(ValueError, linalg.norm, array([1., 2., 3.]), 'fro')
def test_lapack_endian(self):
# For bug #1482
a = array([[5.7998084, -2.1825367],
[-2.1825367, 9.85910595]], dtype='>f8')
b = array(a, dtype='<f8')
ap = linalg.cholesky(a)
bp = linalg.cholesky(b)
assert_array_equal(ap, bp)
def test_large_svd_32bit(self):
# See gh-4442, 64bit would require very large/slow matrices.
x = np.eye(1000, 66)
np.linalg.svd(x)
def test_svd_no_uv(self):
# gh-4733
for shape in (3, 4), (4, 4), (4, 3):
for t in float, complex:
a = np.ones(shape, dtype=t)
w = linalg.svd(a, compute_uv=False)
c = np.count_nonzero(np.absolute(w) > 0.5)
assert_equal(c, 1)
assert_equal(np.linalg.matrix_rank(a), 1)
assert_array_less(1, np.linalg.norm(a, ord=2))
w_svdvals = linalg.svdvals(a)
assert_array_almost_equal(w, w_svdvals)
def test_norm_object_array(self):
# gh-7575
testvector = np.array([np.array([0, 1]), 0, 0], dtype=object)
norm = linalg.norm(testvector)
assert_array_equal(norm, [0, 1])
assert_(norm.dtype == np.dtype('float64'))
norm = linalg.norm(testvector, ord=1)
assert_array_equal(norm, [0, 1])
assert_(norm.dtype != np.dtype('float64'))
norm = linalg.norm(testvector, ord=2)
assert_array_equal(norm, [0, 1])
assert_(norm.dtype == np.dtype('float64'))
assert_raises(ValueError, linalg.norm, testvector, ord='fro')
assert_raises(ValueError, linalg.norm, testvector, ord='nuc')
assert_raises(ValueError, linalg.norm, testvector, ord=np.inf)
assert_raises(ValueError, linalg.norm, testvector, ord=-np.inf)
assert_raises(ValueError, linalg.norm, testvector, ord=0)
assert_raises(ValueError, linalg.norm, testvector, ord=-1)
assert_raises(ValueError, linalg.norm, testvector, ord=-2)
testmatrix = np.array([[np.array([0, 1]), 0, 0],
[0, 0, 0]], dtype=object)
norm = linalg.norm(testmatrix)
assert_array_equal(norm, [0, 1])
assert_(norm.dtype == np.dtype('float64'))
norm = linalg.norm(testmatrix, ord='fro')
assert_array_equal(norm, [0, 1])
assert_(norm.dtype == np.dtype('float64'))
assert_raises(TypeError, linalg.norm, testmatrix, ord='nuc')
assert_raises(ValueError, linalg.norm, testmatrix, ord=np.inf)
assert_raises(ValueError, linalg.norm, testmatrix, ord=-np.inf)
assert_raises(ValueError, linalg.norm, testmatrix, ord=0)
assert_raises(ValueError, linalg.norm, testmatrix, ord=1)
assert_raises(ValueError, linalg.norm, testmatrix, ord=-1)
assert_raises(TypeError, linalg.norm, testmatrix, ord=2)
assert_raises(TypeError, linalg.norm, testmatrix, ord=-2)
assert_raises(ValueError, linalg.norm, testmatrix, ord=3)
def test_lstsq_complex_larger_rhs(self):
# gh-9891
size = 20
n_rhs = 70
G = np.random.randn(size, size) + 1j * np.random.randn(size, size)
u = np.random.randn(size, n_rhs) + 1j * np.random.randn(size, n_rhs)
b = G.dot(u)
# This should work without segmentation fault.
u_lstsq, res, rank, sv = linalg.lstsq(G, b, rcond=None)
# check results just in case
assert_array_almost_equal(u_lstsq, u)
@pytest.mark.parametrize("upper", [True, False])
def test_cholesky_empty_array(self, upper):
# gh-25840 - upper=True hung before.
res = np.linalg.cholesky(np.zeros((0, 0)), upper=upper)
assert res.size == 0
@pytest.mark.parametrize("rtol", [0.0, [0.0] * 4, np.zeros((4,))])
def test_matrix_rank_rtol_argument(self, rtol):
# gh-25877
x = np.zeros((4, 3, 2))
res = np.linalg.matrix_rank(x, rtol=rtol)
assert res.shape == (4,)
def test_openblas_threading(self):
# gh-27036
# Test whether matrix multiplication involving a large matrix always
# gives the same (correct) answer
x = np.arange(500000, dtype=np.float64)
src = np.vstack((x, -10*x)).T
matrix = np.array([[0, 1], [1, 0]])
expected = np.vstack((-10*x, x)).T # src @ matrix
for i in range(200):
result = src @ matrix
mismatches = (~np.isclose(result, expected)).sum()
if mismatches != 0:
assert False, ("unexpected result from matmul, "
"probably due to OpenBLAS threading issues")