feat: CMA P1+P2 Round1 — 成本法对比+杜邦分析+本量利

This commit is contained in:
Hermes CI Fix
2026-07-16 16:39:24 +08:00
parent 46fa811d52
commit 4b25f46124
8728 changed files with 1772671 additions and 151 deletions
@@ -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
outer
Decompositions
--------------
cholesky
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
from ._linalg import *
__all__ = _linalg.__all__.copy() # noqa: PLE0605
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
del PytestTester
@@ -0,0 +1,71 @@
from . import _linalg as _linalg, _umath_linalg as _umath_linalg
from ._linalg import (
cholesky,
cond,
cross,
det,
diagonal,
eig,
eigh,
eigvals,
eigvalsh,
inv,
lstsq,
matmul,
matrix_norm,
matrix_power,
matrix_rank,
matrix_transpose,
multi_dot,
norm,
outer,
pinv,
qr,
slogdet,
solve,
svd,
svdvals,
tensordot,
tensorinv,
tensorsolve,
trace,
vecdot,
vector_norm,
)
__all__ = [
"LinAlgError",
"cholesky",
"cond",
"cross",
"det",
"diagonal",
"eig",
"eigh",
"eigvals",
"eigvalsh",
"inv",
"lstsq",
"matmul",
"matrix_norm",
"matrix_power",
"matrix_rank",
"matrix_transpose",
"multi_dot",
"norm",
"outer",
"pinv",
"qr",
"slogdet",
"solve",
"svd",
"svdvals",
"tensordot",
"tensorinv",
"tensorsolve",
"trace",
"vecdot",
"vector_norm",
]
class LinAlgError(ValueError): ...
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,60 @@
from typing import Final, Literal as L
import numpy as np
from numpy._typing._ufunc import _GUFunc_Nin2_Nout1
__version__: Final[str] = ...
_ilp64: Final[bool] = ...
###
# 1 -> 1
# (m,m) -> ()
det: Final[np.ufunc] = ...
# (m,m) -> (m)
cholesky_lo: Final[np.ufunc] = ...
cholesky_up: Final[np.ufunc] = ...
eigvals: Final[np.ufunc] = ...
eigvalsh_lo: Final[np.ufunc] = ...
eigvalsh_up: Final[np.ufunc] = ...
# (m,m) -> (m,m)
inv: Final[np.ufunc] = ...
# (m,n) -> (p)
qr_r_raw: Final[np.ufunc] = ...
svd: Final[np.ufunc] = ...
###
# 1 -> 2
# (m,m) -> (), ()
slogdet: Final[np.ufunc] = ...
# (m,m) -> (m), (m,m)
eig: Final[np.ufunc] = ...
eigh_lo: Final[np.ufunc] = ...
eigh_up: Final[np.ufunc] = ...
###
# 2 -> 1
# (m,n), (n) -> (m,m)
qr_complete: Final[_GUFunc_Nin2_Nout1[L["qr_complete"], L[2], None, L["(m,n),(n)->(m,m)"]]] = ...
# (m,n), (k) -> (m,k)
qr_reduced: Final[_GUFunc_Nin2_Nout1[L["qr_reduced"], L[2], None, L["(m,n),(k)->(m,k)"]]] = ...
# (m,m), (m,n) -> (m,n)
solve: Final[_GUFunc_Nin2_Nout1[L["solve"], L[4], None, L["(m,m),(m,n)->(m,n)"]]] = ...
# (m,m), (m) -> (m)
solve1: Final[_GUFunc_Nin2_Nout1[L["solve1"], L[4], None, L["(m,m),(m)->(m)"]]] = ...
###
# 1 -> 3
# (m,n) -> (m,m), (p), (n,n)
svd_f: Final[np.ufunc] = ...
# (m,n) -> (m,p), (p), (p,n)
svd_s: Final[np.ufunc] = ...
###
# 3 -> 4
# (m,n), (m,k), () -> (n,k), (k), (), (p)
lstsq: Final[np.ufunc] = ...
@@ -0,0 +1,143 @@
from typing import Final, TypedDict, type_check_only
import numpy as np
from numpy._typing import NDArray
from ._linalg import fortran_int
###
@type_check_only
class _GELSD(TypedDict):
m: int
n: int
nrhs: int
lda: int
ldb: int
rank: int
lwork: int
info: int
@type_check_only
class _DGELSD(_GELSD):
dgelsd_: int
rcond: float
@type_check_only
class _ZGELSD(_GELSD):
zgelsd_: int
@type_check_only
class _GEQRF(TypedDict):
m: int
n: int
lda: int
lwork: int
info: int
@type_check_only
class _DGEQRF(_GEQRF):
dgeqrf_: int
@type_check_only
class _ZGEQRF(_GEQRF):
zgeqrf_: int
@type_check_only
class _DORGQR(TypedDict):
dorgqr_: int
info: int
@type_check_only
class _ZUNGQR(TypedDict):
zungqr_: int
info: int
###
_ilp64: Final[bool] = ...
class LapackError(Exception): ...
def dgelsd(
m: int,
n: int,
nrhs: int,
a: NDArray[np.float64],
lda: int,
b: NDArray[np.float64],
ldb: int,
s: NDArray[np.float64],
rcond: float,
rank: int,
work: NDArray[np.float64],
lwork: int,
iwork: NDArray[fortran_int],
info: int,
) -> _DGELSD: ...
def zgelsd(
m: int,
n: int,
nrhs: int,
a: NDArray[np.complex128],
lda: int,
b: NDArray[np.complex128],
ldb: int,
s: NDArray[np.float64],
rcond: float,
rank: int,
work: NDArray[np.complex128],
lwork: int,
rwork: NDArray[np.float64],
iwork: NDArray[fortran_int],
info: int,
) -> _ZGELSD: ...
#
def dgeqrf(
m: int,
n: int,
a: NDArray[np.float64], # in/out, shape: (lda, n)
lda: int,
tau: NDArray[np.float64], # out, shape: (min(m, n),)
work: NDArray[np.float64], # out, shape: (max(1, lwork),)
lwork: int,
info: int, # out
) -> _DGEQRF: ...
def zgeqrf(
m: int,
n: int,
a: NDArray[np.complex128], # in/out, shape: (lda, n)
lda: int,
tau: NDArray[np.complex128], # out, shape: (min(m, n),)
work: NDArray[np.complex128], # out, shape: (max(1, lwork),)
lwork: int,
info: int, # out
) -> _ZGEQRF: ...
#
def dorgqr(
m: int, # >=0
n: int, # m >= n >= 0
k: int, # n >= k >= 0
a: NDArray[np.float64], # in/out, shape: (lda, n)
lda: int, # >= max(1, m)
tau: NDArray[np.float64], # in, shape: (k,)
work: NDArray[np.float64], # out, shape: (max(1, lwork),)
lwork: int,
info: int, # out
) -> _DORGQR: ...
def zungqr(
m: int,
n: int,
k: int,
a: NDArray[np.complex128],
lda: int,
tau: NDArray[np.complex128],
work: NDArray[np.complex128],
lwork: int,
info: int,
) -> _ZUNGQR: ...
#
def xerbla(srname: object, info: int) -> None: ...
@@ -0,0 +1,21 @@
"""Test deprecation and future warnings.
"""
import pytest
import numpy as np
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)
pytest.warns(DeprecationWarning, np.linalg.qr, a, mode='full')
pytest.warns(DeprecationWarning, np.linalg.qr, a, mode='f')
pytest.warns(DeprecationWarning, np.linalg.qr, a, mode='economic')
pytest.warns(DeprecationWarning, np.linalg.qr, a, mode='e')
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,191 @@
""" Test functions for linalg module
"""
import pytest
import numpy as np
from numpy import arange, array, dot, float64, linalg, transpose
from numpy.testing import (
assert_,
assert_almost_equal,
assert_array_almost_equal,
assert_array_equal,
assert_array_less,
assert_equal,
assert_raises,
)
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 = a.reshape((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,)
@pytest.mark.thread_unsafe(reason="test is already testing threads with openblas")
@pytest.mark.slow
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")
def test_norm_linux_arm(self):
# gh-30816
a = np.arange(20000) / 50000
b = a + 1j * np.roll(np.flip(a), 12345)
norm = np.linalg.norm(b)
assert_almost_equal(norm, 46.18628948075393)