|
|
|
|
|
|
|
|
|
import math |
|
import pytest |
|
import numpy as np |
|
import numpy.random |
|
from numpy.testing import (assert_equal, assert_almost_equal, assert_, |
|
assert_array_almost_equal, assert_allclose) |
|
from pytest import raises as assert_raises |
|
|
|
from numpy import float32, float64, complex64, complex128, arange, triu, \ |
|
tril, zeros, tril_indices, ones, mod, diag, append, eye, \ |
|
nonzero |
|
|
|
import scipy |
|
from scipy.linalg import _fblas as fblas, get_blas_funcs, toeplitz, solve |
|
|
|
try: |
|
from scipy.linalg import _cblas as cblas |
|
except ImportError: |
|
cblas = None |
|
|
|
REAL_DTYPES = [float32, float64] |
|
COMPLEX_DTYPES = [complex64, complex128] |
|
DTYPES = REAL_DTYPES + COMPLEX_DTYPES |
|
|
|
|
|
def test_get_blas_funcs(): |
|
|
|
|
|
f1, f2, f3 = get_blas_funcs( |
|
('axpy', 'axpy', 'axpy'), |
|
(np.empty((2, 2), dtype=np.complex64, order='F'), |
|
np.empty((2, 2), dtype=np.complex128, order='C')) |
|
) |
|
|
|
|
|
|
|
assert_equal(f1.typecode, 'z') |
|
assert_equal(f2.typecode, 'z') |
|
if cblas is not None: |
|
assert_equal(f1.module_name, 'cblas') |
|
assert_equal(f2.module_name, 'cblas') |
|
|
|
|
|
f1 = get_blas_funcs('rotg') |
|
assert_equal(f1.typecode, 'd') |
|
|
|
|
|
f1 = get_blas_funcs('gemm', dtype=np.complex64) |
|
assert_equal(f1.typecode, 'c') |
|
f1 = get_blas_funcs('gemm', dtype='F') |
|
assert_equal(f1.typecode, 'c') |
|
|
|
|
|
f1 = get_blas_funcs('gemm', dtype=np.clongdouble) |
|
assert_equal(f1.typecode, 'z') |
|
|
|
|
|
f1 = get_blas_funcs('axpy', |
|
(np.empty((2, 2), dtype=np.float64), |
|
np.empty((2, 2), dtype=np.complex64)) |
|
) |
|
assert_equal(f1.typecode, 'z') |
|
|
|
|
|
def test_get_blas_funcs_alias(): |
|
|
|
f, g = get_blas_funcs(('nrm2', 'dot'), dtype=np.complex64) |
|
assert f.typecode == 'c' |
|
assert g.typecode == 'c' |
|
|
|
f, g, h = get_blas_funcs(('dot', 'dotc', 'dotu'), dtype=np.float64) |
|
assert f is g |
|
assert f is h |
|
|
|
|
|
class TestCBLAS1Simple: |
|
|
|
def test_axpy(self): |
|
for p in 'sd': |
|
f = getattr(cblas, p+'axpy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([1, 2, 3], [2, -1, 3], a=5), |
|
[7, 9, 18]) |
|
for p in 'cz': |
|
f = getattr(cblas, p+'axpy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([1, 2j, 3], [2, -1, 3], a=5), |
|
[7, 10j-1, 18]) |
|
|
|
|
|
class TestFBLAS1Simple: |
|
|
|
def test_axpy(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'axpy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([1, 2, 3], [2, -1, 3], a=5), |
|
[7, 9, 18]) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'axpy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([1, 2j, 3], [2, -1, 3], a=5), |
|
[7, 10j-1, 18]) |
|
|
|
def test_copy(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'copy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([3, 4, 5], [8]*3), [3, 4, 5]) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'copy', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f([3, 4j, 5+3j], [8]*3), [3, 4j, 5+3j]) |
|
|
|
def test_asum(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'asum', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3, -4, 5]), 12) |
|
for p in ['sc', 'dz']: |
|
f = getattr(fblas, p+'asum', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3j, -4, 3-4j]), 14) |
|
|
|
def test_dot(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'dot', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3, -4, 5], [2, 5, 1]), -9) |
|
|
|
def test_complex_dotu(self): |
|
for p in 'cz': |
|
f = getattr(fblas, p+'dotu', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3j, -4, 3-4j], [2, 3, 1]), -9+2j) |
|
|
|
def test_complex_dotc(self): |
|
for p in 'cz': |
|
f = getattr(fblas, p+'dotc', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3j, -4, 3-4j], [2, 3j, 1]), 3-14j) |
|
|
|
def test_nrm2(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'nrm2', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3, -4, 5]), math.sqrt(50)) |
|
for p in ['c', 'z', 'sc', 'dz']: |
|
f = getattr(fblas, p+'nrm2', None) |
|
if f is None: |
|
continue |
|
assert_almost_equal(f([3j, -4, 3-4j]), math.sqrt(50)) |
|
|
|
def test_scal(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'scal', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(2, [3, -4, 5]), [6, -8, 10]) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'scal', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3j, [3j, -4, 3-4j]), [-9, -12j, 12+9j]) |
|
for p in ['cs', 'zd']: |
|
f = getattr(fblas, p+'scal', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3, [3j, -4, 3-4j]), [9j, -12, 9-12j]) |
|
|
|
def test_swap(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'swap', None) |
|
if f is None: |
|
continue |
|
x, y = [2, 3, 1], [-2, 3, 7] |
|
x1, y1 = f(x, y) |
|
assert_array_almost_equal(x1, y) |
|
assert_array_almost_equal(y1, x) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'swap', None) |
|
if f is None: |
|
continue |
|
x, y = [2, 3j, 1], [-2, 3, 7-3j] |
|
x1, y1 = f(x, y) |
|
assert_array_almost_equal(x1, y) |
|
assert_array_almost_equal(y1, x) |
|
|
|
def test_amax(self): |
|
for p in 'sd': |
|
f = getattr(fblas, 'i'+p+'amax') |
|
assert_equal(f([-2, 4, 3]), 1) |
|
for p in 'cz': |
|
f = getattr(fblas, 'i'+p+'amax') |
|
assert_equal(f([-5, 4+3j, 6]), 1) |
|
|
|
|
|
|
|
class TestFBLAS2Simple: |
|
|
|
def test_gemv(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'gemv', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3, [[3]], [-4]), [-36]) |
|
assert_array_almost_equal(f(3, [[3]], [-4], 3, [5]), [-21]) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'gemv', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3j, [[3-4j]], [-4]), [-48-36j]) |
|
assert_array_almost_equal(f(3j, [[3-4j]], [-4], 3, [5j]), |
|
[-48-21j]) |
|
|
|
|
|
|
|
@pytest.mark.thread_unsafe |
|
def test_ger(self): |
|
|
|
for p in 'sd': |
|
f = getattr(fblas, p+'ger', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(1, [1, 2], [3, 4]), [[3, 4], [6, 8]]) |
|
assert_array_almost_equal(f(2, [1, 2, 3], [3, 4]), |
|
[[6, 8], [12, 16], [18, 24]]) |
|
|
|
assert_array_almost_equal(f(1, [1, 2], [3, 4], |
|
a=[[1, 2], [3, 4]]), [[4, 6], [9, 12]]) |
|
|
|
for p in 'cz': |
|
f = getattr(fblas, p+'geru', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(1, [1j, 2], [3, 4]), |
|
[[3j, 4j], [6, 8]]) |
|
assert_array_almost_equal(f(-2, [1j, 2j, 3j], [3j, 4j]), |
|
[[6, 8], [12, 16], [18, 24]]) |
|
|
|
for p in 'cz': |
|
for name in ('ger', 'gerc'): |
|
f = getattr(fblas, p+name, None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(1, [1j, 2], [3, 4]), |
|
[[3j, 4j], [6, 8]]) |
|
assert_array_almost_equal(f(2, [1j, 2j, 3j], [3j, 4j]), |
|
[[6, 8], [12, 16], [18, 24]]) |
|
|
|
def test_syr_her(self): |
|
x = np.arange(1, 5, dtype='d') |
|
resx = np.triu(x[:, np.newaxis] * x) |
|
resx_reverse = np.triu(x[::-1, np.newaxis] * x[::-1]) |
|
|
|
y = np.linspace(0, 8.5, 17, endpoint=False) |
|
|
|
z = np.arange(1, 9, dtype='d').view('D') |
|
resz = np.triu(z[:, np.newaxis] * z) |
|
resz_reverse = np.triu(z[::-1, np.newaxis] * z[::-1]) |
|
rehz = np.triu(z[:, np.newaxis] * z.conj()) |
|
rehz_reverse = np.triu(z[::-1, np.newaxis] * z[::-1].conj()) |
|
|
|
w = np.c_[np.zeros(4), z, np.zeros(4)].ravel() |
|
|
|
for p, rtol in zip('sd', [1e-7, 1e-14]): |
|
f = getattr(fblas, p+'syr', None) |
|
if f is None: |
|
continue |
|
assert_allclose(f(1.0, x), resx, rtol=rtol) |
|
assert_allclose(f(1.0, x, lower=True), resx.T, rtol=rtol) |
|
assert_allclose(f(1.0, y, incx=2, offx=2, n=4), resx, rtol=rtol) |
|
|
|
assert_allclose(f(1.0, y, incx=-2, offx=2, n=4), |
|
resx_reverse, rtol=rtol) |
|
|
|
a = np.zeros((4, 4), 'f' if p == 's' else 'd', 'F') |
|
b = f(1.0, x, a=a, overwrite_a=True) |
|
assert_allclose(a, resx, rtol=rtol) |
|
|
|
b = f(2.0, x, a=a) |
|
assert_(a is not b) |
|
assert_allclose(b, 3*resx, rtol=rtol) |
|
|
|
assert_raises(Exception, f, 1.0, x, incx=0) |
|
assert_raises(Exception, f, 1.0, x, offx=5) |
|
assert_raises(Exception, f, 1.0, x, offx=-2) |
|
assert_raises(Exception, f, 1.0, x, n=-2) |
|
assert_raises(Exception, f, 1.0, x, n=5) |
|
assert_raises(Exception, f, 1.0, x, lower=2) |
|
assert_raises(Exception, f, 1.0, x, a=np.zeros((2, 2), 'd', 'F')) |
|
|
|
for p, rtol in zip('cz', [1e-7, 1e-14]): |
|
f = getattr(fblas, p+'syr', None) |
|
if f is None: |
|
continue |
|
assert_allclose(f(1.0, z), resz, rtol=rtol) |
|
assert_allclose(f(1.0, z, lower=True), resz.T, rtol=rtol) |
|
assert_allclose(f(1.0, w, incx=3, offx=1, n=4), resz, rtol=rtol) |
|
|
|
assert_allclose(f(1.0, w, incx=-3, offx=1, n=4), |
|
resz_reverse, rtol=rtol) |
|
|
|
a = np.zeros((4, 4), 'F' if p == 'c' else 'D', 'F') |
|
b = f(1.0, z, a=a, overwrite_a=True) |
|
assert_allclose(a, resz, rtol=rtol) |
|
|
|
b = f(2.0, z, a=a) |
|
assert_(a is not b) |
|
assert_allclose(b, 3*resz, rtol=rtol) |
|
|
|
assert_raises(Exception, f, 1.0, x, incx=0) |
|
assert_raises(Exception, f, 1.0, x, offx=5) |
|
assert_raises(Exception, f, 1.0, x, offx=-2) |
|
assert_raises(Exception, f, 1.0, x, n=-2) |
|
assert_raises(Exception, f, 1.0, x, n=5) |
|
assert_raises(Exception, f, 1.0, x, lower=2) |
|
assert_raises(Exception, f, 1.0, x, a=np.zeros((2, 2), 'd', 'F')) |
|
|
|
for p, rtol in zip('cz', [1e-7, 1e-14]): |
|
f = getattr(fblas, p+'her', None) |
|
if f is None: |
|
continue |
|
assert_allclose(f(1.0, z), rehz, rtol=rtol) |
|
assert_allclose(f(1.0, z, lower=True), rehz.T.conj(), rtol=rtol) |
|
assert_allclose(f(1.0, w, incx=3, offx=1, n=4), rehz, rtol=rtol) |
|
|
|
assert_allclose(f(1.0, w, incx=-3, offx=1, n=4), |
|
rehz_reverse, rtol=rtol) |
|
|
|
a = np.zeros((4, 4), 'F' if p == 'c' else 'D', 'F') |
|
b = f(1.0, z, a=a, overwrite_a=True) |
|
assert_allclose(a, rehz, rtol=rtol) |
|
|
|
b = f(2.0, z, a=a) |
|
assert_(a is not b) |
|
assert_allclose(b, 3*rehz, rtol=rtol) |
|
|
|
assert_raises(Exception, f, 1.0, x, incx=0) |
|
assert_raises(Exception, f, 1.0, x, offx=5) |
|
assert_raises(Exception, f, 1.0, x, offx=-2) |
|
assert_raises(Exception, f, 1.0, x, n=-2) |
|
assert_raises(Exception, f, 1.0, x, n=5) |
|
assert_raises(Exception, f, 1.0, x, lower=2) |
|
assert_raises(Exception, f, 1.0, x, a=np.zeros((2, 2), 'd', 'F')) |
|
|
|
def test_syr2(self): |
|
x = np.arange(1, 5, dtype='d') |
|
y = np.arange(5, 9, dtype='d') |
|
resxy = np.triu(x[:, np.newaxis] * y + y[:, np.newaxis] * x) |
|
resxy_reverse = np.triu(x[::-1, np.newaxis] * y[::-1] |
|
+ y[::-1, np.newaxis] * x[::-1]) |
|
|
|
q = np.linspace(0, 8.5, 17, endpoint=False) |
|
|
|
for p, rtol in zip('sd', [1e-7, 1e-14]): |
|
f = getattr(fblas, p+'syr2', None) |
|
if f is None: |
|
continue |
|
assert_allclose(f(1.0, x, y), resxy, rtol=rtol) |
|
assert_allclose(f(1.0, x, y, n=3), resxy[:3, :3], rtol=rtol) |
|
assert_allclose(f(1.0, x, y, lower=True), resxy.T, rtol=rtol) |
|
|
|
assert_allclose(f(1.0, q, q, incx=2, offx=2, incy=2, offy=10), |
|
resxy, rtol=rtol) |
|
assert_allclose(f(1.0, q, q, incx=2, offx=2, incy=2, offy=10, n=3), |
|
resxy[:3, :3], rtol=rtol) |
|
|
|
assert_allclose(f(1.0, q, q, incx=-2, offx=2, incy=-2, offy=10), |
|
resxy_reverse, rtol=rtol) |
|
|
|
a = np.zeros((4, 4), 'f' if p == 's' else 'd', 'F') |
|
b = f(1.0, x, y, a=a, overwrite_a=True) |
|
assert_allclose(a, resxy, rtol=rtol) |
|
|
|
b = f(2.0, x, y, a=a) |
|
assert_(a is not b) |
|
assert_allclose(b, 3*resxy, rtol=rtol) |
|
|
|
assert_raises(Exception, f, 1.0, x, y, incx=0) |
|
assert_raises(Exception, f, 1.0, x, y, offx=5) |
|
assert_raises(Exception, f, 1.0, x, y, offx=-2) |
|
assert_raises(Exception, f, 1.0, x, y, incy=0) |
|
assert_raises(Exception, f, 1.0, x, y, offy=5) |
|
assert_raises(Exception, f, 1.0, x, y, offy=-2) |
|
assert_raises(Exception, f, 1.0, x, y, n=-2) |
|
assert_raises(Exception, f, 1.0, x, y, n=5) |
|
assert_raises(Exception, f, 1.0, x, y, lower=2) |
|
assert_raises(Exception, f, 1.0, x, y, |
|
a=np.zeros((2, 2), 'd', 'F')) |
|
|
|
def test_her2(self): |
|
x = np.arange(1, 9, dtype='d').view('D') |
|
y = np.arange(9, 17, dtype='d').view('D') |
|
resxy = x[:, np.newaxis] * y.conj() + y[:, np.newaxis] * x.conj() |
|
resxy = np.triu(resxy) |
|
|
|
resxy_reverse = x[::-1, np.newaxis] * y[::-1].conj() |
|
resxy_reverse += y[::-1, np.newaxis] * x[::-1].conj() |
|
resxy_reverse = np.triu(resxy_reverse) |
|
|
|
u = np.c_[np.zeros(4), x, np.zeros(4)].ravel() |
|
v = np.c_[np.zeros(4), y, np.zeros(4)].ravel() |
|
|
|
for p, rtol in zip('cz', [1e-7, 1e-14]): |
|
f = getattr(fblas, p+'her2', None) |
|
if f is None: |
|
continue |
|
assert_allclose(f(1.0, x, y), resxy, rtol=rtol) |
|
assert_allclose(f(1.0, x, y, n=3), resxy[:3, :3], rtol=rtol) |
|
assert_allclose(f(1.0, x, y, lower=True), resxy.T.conj(), |
|
rtol=rtol) |
|
|
|
assert_allclose(f(1.0, u, v, incx=3, offx=1, incy=3, offy=1), |
|
resxy, rtol=rtol) |
|
assert_allclose(f(1.0, u, v, incx=3, offx=1, incy=3, offy=1, n=3), |
|
resxy[:3, :3], rtol=rtol) |
|
|
|
assert_allclose(f(1.0, u, v, incx=-3, offx=1, incy=-3, offy=1), |
|
resxy_reverse, rtol=rtol) |
|
|
|
a = np.zeros((4, 4), 'F' if p == 'c' else 'D', 'F') |
|
b = f(1.0, x, y, a=a, overwrite_a=True) |
|
assert_allclose(a, resxy, rtol=rtol) |
|
|
|
b = f(2.0, x, y, a=a) |
|
assert_(a is not b) |
|
assert_allclose(b, 3*resxy, rtol=rtol) |
|
|
|
assert_raises(Exception, f, 1.0, x, y, incx=0) |
|
assert_raises(Exception, f, 1.0, x, y, offx=5) |
|
assert_raises(Exception, f, 1.0, x, y, offx=-2) |
|
assert_raises(Exception, f, 1.0, x, y, incy=0) |
|
assert_raises(Exception, f, 1.0, x, y, offy=5) |
|
assert_raises(Exception, f, 1.0, x, y, offy=-2) |
|
assert_raises(Exception, f, 1.0, x, y, n=-2) |
|
assert_raises(Exception, f, 1.0, x, y, n=5) |
|
assert_raises(Exception, f, 1.0, x, y, lower=2) |
|
assert_raises(Exception, f, 1.0, x, y, |
|
a=np.zeros((2, 2), 'd', 'F')) |
|
|
|
def test_gbmv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 7 |
|
m = 5 |
|
kl = 1 |
|
ku = 2 |
|
|
|
A = toeplitz(append(rng.random(kl+1), zeros(m-kl-1)), |
|
append(rng.random(ku+1), zeros(n-ku-1))) |
|
A = A.astype(dtype) |
|
Ab = zeros((kl+ku+1, n), dtype=dtype) |
|
|
|
|
|
Ab[2, :5] = A[0, 0] |
|
Ab[1, 1:6] = A[0, 1] |
|
Ab[0, 2:7] = A[0, 2] |
|
Ab[3, :4] = A[1, 0] |
|
|
|
x = rng.random(n).astype(dtype) |
|
y = rng.random(m).astype(dtype) |
|
alpha, beta = dtype(3), dtype(-5) |
|
|
|
func, = get_blas_funcs(('gbmv',), dtype=dtype) |
|
y1 = func(m=m, n=n, ku=ku, kl=kl, alpha=alpha, a=Ab, |
|
x=x, y=y, beta=beta) |
|
y2 = alpha * A.dot(x) + beta * y |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(m=m, n=n, ku=ku, kl=kl, alpha=alpha, a=Ab, |
|
x=y, y=x, beta=beta, trans=1) |
|
y2 = alpha * A.T.dot(y) + beta * x |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_sbmv_hbmv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 6 |
|
k = 2 |
|
A = zeros((n, n), dtype=dtype) |
|
Ab = zeros((k+1, n), dtype=dtype) |
|
|
|
|
|
A[arange(n), arange(n)] = rng.random(n) |
|
for ind2 in range(1, k+1): |
|
temp = rng.random(n-ind2) |
|
A[arange(n-ind2), arange(ind2, n)] = temp |
|
Ab[-1-ind2, ind2:] = temp |
|
A = A.astype(dtype) |
|
A = A + A.T if ind < 2 else A + A.conj().T |
|
Ab[-1, :] = diag(A) |
|
x = rng.random(n).astype(dtype) |
|
y = rng.random(n).astype(dtype) |
|
alpha, beta = dtype(1.25), dtype(3) |
|
|
|
if ind > 1: |
|
func, = get_blas_funcs(('hbmv',), dtype=dtype) |
|
else: |
|
func, = get_blas_funcs(('sbmv',), dtype=dtype) |
|
y1 = func(k=k, alpha=alpha, a=Ab, x=x, y=y, beta=beta) |
|
y2 = alpha * A.dot(x) + beta * y |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_spmv_hpmv(self): |
|
rng = np.random.default_rng(12345698) |
|
for ind, dtype in enumerate(DTYPES+COMPLEX_DTYPES): |
|
n = 3 |
|
A = rng.random((n, n)).astype(dtype) |
|
if ind > 1: |
|
A += rng.random((n, n))*1j |
|
A = A.astype(dtype) |
|
A = A + A.T if ind < 4 else A + A.conj().T |
|
c, r = tril_indices(n) |
|
Ap = A[r, c] |
|
x = rng.random(n).astype(dtype) |
|
y = rng.random(n).astype(dtype) |
|
xlong = arange(2*n).astype(dtype) |
|
ylong = ones(2*n).astype(dtype) |
|
alpha, beta = dtype(1.25), dtype(2) |
|
|
|
if ind > 3: |
|
func, = get_blas_funcs(('hpmv',), dtype=dtype) |
|
else: |
|
func, = get_blas_funcs(('spmv',), dtype=dtype) |
|
y1 = func(n=n, alpha=alpha, ap=Ap, x=x, y=y, beta=beta) |
|
y2 = alpha * A.dot(x) + beta * y |
|
assert_array_almost_equal(y1, y2) |
|
|
|
|
|
y1 = func(n=n-1, alpha=alpha, beta=beta, x=xlong, y=ylong, ap=Ap, |
|
incx=2, incy=2, offx=n, offy=n) |
|
y2 = (alpha * A[:-1, :-1]).dot(xlong[3::2]) + beta * ylong[3::2] |
|
assert_array_almost_equal(y1[3::2], y2) |
|
assert_almost_equal(y1[4], ylong[4]) |
|
|
|
def test_spr_hpr(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES+COMPLEX_DTYPES): |
|
n = 3 |
|
A = rng.random((n, n)).astype(dtype) |
|
if ind > 1: |
|
A += rng.random((n, n))*1j |
|
A = A.astype(dtype) |
|
A = A + A.T if ind < 4 else A + A.conj().T |
|
c, r = tril_indices(n) |
|
Ap = A[r, c] |
|
x = rng.random(n).astype(dtype) |
|
alpha = (DTYPES+COMPLEX_DTYPES)[mod(ind, 4)](2.5) |
|
|
|
if ind > 3: |
|
func, = get_blas_funcs(('hpr',), dtype=dtype) |
|
y2 = alpha * x[:, None].dot(x[None, :].conj()) + A |
|
else: |
|
func, = get_blas_funcs(('spr',), dtype=dtype) |
|
y2 = alpha * x[:, None].dot(x[None, :]) + A |
|
|
|
y1 = func(n=n, alpha=alpha, ap=Ap, x=x) |
|
y1f = zeros((3, 3), dtype=dtype) |
|
y1f[r, c] = y1 |
|
y1f[c, r] = y1.conj() if ind > 3 else y1 |
|
assert_array_almost_equal(y1f, y2) |
|
|
|
def test_spr2_hpr2(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 3 |
|
A = rng.random((n, n)).astype(dtype) |
|
if ind > 1: |
|
A += rng.random((n, n))*1j |
|
A = A.astype(dtype) |
|
A = A + A.T if ind < 2 else A + A.conj().T |
|
c, r = tril_indices(n) |
|
Ap = A[r, c] |
|
x = rng.random(n).astype(dtype) |
|
y = rng.random(n).astype(dtype) |
|
alpha = dtype(2) |
|
|
|
if ind > 1: |
|
func, = get_blas_funcs(('hpr2',), dtype=dtype) |
|
else: |
|
func, = get_blas_funcs(('spr2',), dtype=dtype) |
|
|
|
u = alpha.conj() * x[:, None].dot(y[None, :].conj()) |
|
y2 = A + u + u.conj().T |
|
y1 = func(n=n, alpha=alpha, x=x, y=y, ap=Ap) |
|
y1f = zeros((3, 3), dtype=dtype) |
|
y1f[r, c] = y1 |
|
y1f[[1, 2, 2], [0, 0, 1]] = y1[[1, 3, 4]].conj() |
|
assert_array_almost_equal(y1f, y2) |
|
|
|
def test_tbmv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 10 |
|
k = 3 |
|
x = rng.random(n).astype(dtype) |
|
A = zeros((n, n), dtype=dtype) |
|
|
|
for sup in range(k+1): |
|
A[arange(n-sup), arange(sup, n)] = rng.random(n-sup) |
|
|
|
|
|
if ind > 1: |
|
A[nonzero(A)] += 1j * rng.random((k+1)*n-(k*(k+1)//2)).astype(dtype) |
|
|
|
|
|
Ab = zeros((k+1, n), dtype=dtype) |
|
for row in range(k+1): |
|
Ab[-row-1, row:] = diag(A, k=row) |
|
func, = get_blas_funcs(('tbmv',), dtype=dtype) |
|
|
|
y1 = func(k=k, a=Ab, x=x) |
|
y2 = A.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = A.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1, trans=1) |
|
y2 = A.T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1, trans=2) |
|
y2 = A.conj().T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_tbsv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 6 |
|
k = 3 |
|
x = rng.random(n).astype(dtype) |
|
A = zeros((n, n), dtype=dtype) |
|
|
|
for sup in range(k+1): |
|
A[arange(n-sup), arange(sup, n)] = rng.random(n-sup) |
|
|
|
|
|
if ind > 1: |
|
A[nonzero(A)] += 1j * rng.random((k+1)*n-(k*(k+1)//2)).astype(dtype) |
|
|
|
|
|
Ab = zeros((k+1, n), dtype=dtype) |
|
for row in range(k+1): |
|
Ab[-row-1, row:] = diag(A, k=row) |
|
func, = get_blas_funcs(('tbsv',), dtype=dtype) |
|
|
|
y1 = func(k=k, a=Ab, x=x) |
|
y2 = solve(A, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = solve(A, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1, trans=1) |
|
y2 = solve(A.T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(k=k, a=Ab, x=x, diag=1, trans=2) |
|
y2 = solve(A.conj().T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_tpmv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 10 |
|
x = rng.random(n).astype(dtype) |
|
|
|
if ind < 2: |
|
A = triu(rng.random((n, n))) |
|
else: |
|
A = triu(rng.random((n, n)) + rng.random((n, n))*1j) |
|
|
|
|
|
c, r = tril_indices(n) |
|
Ap = A[r, c] |
|
func, = get_blas_funcs(('tpmv',), dtype=dtype) |
|
|
|
y1 = func(n=n, ap=Ap, x=x) |
|
y2 = A.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = A.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1, trans=1) |
|
y2 = A.T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1, trans=2) |
|
y2 = A.conj().T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_tpsv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 10 |
|
x = rng.random(n).astype(dtype) |
|
|
|
if ind < 2: |
|
A = triu(rng.random((n, n))) |
|
else: |
|
A = triu(rng.random((n, n)) + rng.random((n, n))*1j) |
|
A += eye(n) |
|
|
|
c, r = tril_indices(n) |
|
Ap = A[r, c] |
|
func, = get_blas_funcs(('tpsv',), dtype=dtype) |
|
|
|
y1 = func(n=n, ap=Ap, x=x) |
|
y2 = solve(A, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = solve(A, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1, trans=1) |
|
y2 = solve(A.T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(n=n, ap=Ap, x=x, diag=1, trans=2) |
|
y2 = solve(A.conj().T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_trmv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 3 |
|
A = (rng.random((n, n))+eye(n)).astype(dtype) |
|
x = rng.random(3).astype(dtype) |
|
func, = get_blas_funcs(('trmv',), dtype=dtype) |
|
|
|
y1 = func(a=A, x=x) |
|
y2 = triu(A).dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = triu(A).dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1, trans=1) |
|
y2 = triu(A).T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1, trans=2) |
|
y2 = triu(A).conj().T.dot(x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
def test_trsv(self): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
n = 15 |
|
A = (rng.random((n, n))+eye(n)).astype(dtype) |
|
x = rng.random(n).astype(dtype) |
|
func, = get_blas_funcs(('trsv',), dtype=dtype) |
|
|
|
y1 = func(a=A, x=x) |
|
y2 = solve(triu(A), x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, lower=1) |
|
y2 = solve(tril(A), x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1) |
|
A[arange(n), arange(n)] = dtype(1) |
|
y2 = solve(triu(A), x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1, trans=1) |
|
y2 = solve(triu(A).T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
y1 = func(a=A, x=x, diag=1, trans=2) |
|
y2 = solve(triu(A).conj().T, x) |
|
assert_array_almost_equal(y1, y2) |
|
|
|
|
|
class TestFBLAS3Simple: |
|
|
|
def test_gemm(self): |
|
for p in 'sd': |
|
f = getattr(fblas, p+'gemm', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3, [3], [-4]), [[-36]]) |
|
assert_array_almost_equal(f(3, [3], [-4], 3, [5]), [-21]) |
|
for p in 'cz': |
|
f = getattr(fblas, p+'gemm', None) |
|
if f is None: |
|
continue |
|
assert_array_almost_equal(f(3j, [3-4j], [-4]), [[-48-36j]]) |
|
assert_array_almost_equal(f(3j, [3-4j], [-4], 3, [5j]), [-48-21j]) |
|
|
|
|
|
def _get_func(func, ps='sdzc'): |
|
"""Just a helper: return a specified BLAS function w/typecode.""" |
|
for p in ps: |
|
f = getattr(fblas, p+func, None) |
|
if f is None: |
|
continue |
|
yield f |
|
|
|
|
|
class TestBLAS3Symm: |
|
|
|
def setup_method(self): |
|
self.a = np.array([[1., 2.], |
|
[0., 1.]]) |
|
self.b = np.array([[1., 0., 3.], |
|
[0., -1., 2.]]) |
|
self.c = np.ones((2, 3)) |
|
self.t = np.array([[2., -1., 8.], |
|
[3., 0., 9.]]) |
|
|
|
def test_symm(self): |
|
for f in _get_func('symm'): |
|
res = f(a=self.a, b=self.b, c=self.c, alpha=1., beta=1.) |
|
assert_array_almost_equal(res, self.t) |
|
|
|
res = f(a=self.a.T, b=self.b, lower=1, c=self.c, alpha=1., beta=1.) |
|
assert_array_almost_equal(res, self.t) |
|
|
|
res = f(a=self.a, b=self.b.T, side=1, c=self.c.T, |
|
alpha=1., beta=1.) |
|
assert_array_almost_equal(res, self.t.T) |
|
|
|
def test_summ_wrong_side(self): |
|
f = getattr(fblas, 'dsymm', None) |
|
if f is not None: |
|
assert_raises(Exception, f, **{'a': self.a, 'b': self.b, |
|
'alpha': 1, 'side': 1}) |
|
|
|
|
|
|
|
def test_symm_wrong_uplo(self): |
|
"""SYMM only considers the upper/lower part of A. Hence setting |
|
wrong value for `lower` (default is lower=0, meaning upper triangle) |
|
gives a wrong result. |
|
""" |
|
f = getattr(fblas, 'dsymm', None) |
|
if f is not None: |
|
res = f(a=self.a, b=self.b, c=self.c, alpha=1., beta=1.) |
|
assert np.allclose(res, self.t) |
|
|
|
res = f(a=self.a, b=self.b, lower=1, c=self.c, alpha=1., beta=1.) |
|
assert not np.allclose(res, self.t) |
|
|
|
|
|
class TestBLAS3Syrk: |
|
def setup_method(self): |
|
self.a = np.array([[1., 0.], |
|
[0., -2.], |
|
[2., 3.]]) |
|
self.t = np.array([[1., 0., 2.], |
|
[0., 4., -6.], |
|
[2., -6., 13.]]) |
|
self.tt = np.array([[5., 6.], |
|
[6., 13.]]) |
|
|
|
def test_syrk(self): |
|
for f in _get_func('syrk'): |
|
c = f(a=self.a, alpha=1.) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.t)) |
|
|
|
c = f(a=self.a, alpha=1., lower=1) |
|
assert_array_almost_equal(np.tril(c), np.tril(self.t)) |
|
|
|
c0 = np.ones(self.t.shape) |
|
c = f(a=self.a, alpha=1., beta=1., c=c0) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.t+c0)) |
|
|
|
c = f(a=self.a, alpha=1., trans=1) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.tt)) |
|
|
|
|
|
|
|
|
|
def test_syrk_wrong_c(self): |
|
f = getattr(fblas, 'dsyrk', None) |
|
if f is not None: |
|
assert_raises(Exception, f, **{'a': self.a, 'alpha': 1., |
|
'c': np.ones((5, 8))}) |
|
|
|
|
|
|
|
class TestBLAS3Syr2k: |
|
def setup_method(self): |
|
self.a = np.array([[1., 0.], |
|
[0., -2.], |
|
[2., 3.]]) |
|
self.b = np.array([[0., 1.], |
|
[1., 0.], |
|
[0, 1.]]) |
|
self.t = np.array([[0., -1., 3.], |
|
[-1., 0., 0.], |
|
[3., 0., 6.]]) |
|
self.tt = np.array([[0., 1.], |
|
[1., 6]]) |
|
|
|
def test_syr2k(self): |
|
for f in _get_func('syr2k'): |
|
c = f(a=self.a, b=self.b, alpha=1.) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.t)) |
|
|
|
c = f(a=self.a, b=self.b, alpha=1., lower=1) |
|
assert_array_almost_equal(np.tril(c), np.tril(self.t)) |
|
|
|
c0 = np.ones(self.t.shape) |
|
c = f(a=self.a, b=self.b, alpha=1., beta=1., c=c0) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.t+c0)) |
|
|
|
c = f(a=self.a, b=self.b, alpha=1., trans=1) |
|
assert_array_almost_equal(np.triu(c), np.triu(self.tt)) |
|
|
|
|
|
def test_syr2k_wrong_c(self): |
|
f = getattr(fblas, 'dsyr2k', None) |
|
if f is not None: |
|
assert_raises(Exception, f, **{'a': self.a, |
|
'b': self.b, |
|
'alpha': 1., |
|
'c': np.zeros((15, 8))}) |
|
|
|
|
|
|
|
class TestSyHe: |
|
"""Quick and simple tests for (zc)-symm, syrk, syr2k.""" |
|
|
|
def setup_method(self): |
|
self.sigma_y = np.array([[0., -1.j], |
|
[1.j, 0.]]) |
|
|
|
def test_symm_zc(self): |
|
for f in _get_func('symm', 'zc'): |
|
|
|
res = f(a=self.sigma_y, b=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), np.diag([1, -1])) |
|
|
|
def test_hemm_zc(self): |
|
for f in _get_func('hemm', 'zc'): |
|
|
|
res = f(a=self.sigma_y, b=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), np.diag([1, 1])) |
|
|
|
def test_syrk_zr(self): |
|
for f in _get_func('syrk', 'zc'): |
|
res = f(a=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), np.diag([-1, -1])) |
|
|
|
def test_herk_zr(self): |
|
for f in _get_func('herk', 'zc'): |
|
res = f(a=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), np.diag([1, 1])) |
|
|
|
def test_syr2k_zr(self): |
|
for f in _get_func('syr2k', 'zc'): |
|
res = f(a=self.sigma_y, b=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), 2.*np.diag([-1, -1])) |
|
|
|
def test_her2k_zr(self): |
|
for f in _get_func('her2k', 'zc'): |
|
res = f(a=self.sigma_y, b=self.sigma_y, alpha=1.) |
|
assert_array_almost_equal(np.triu(res), 2.*np.diag([1, 1])) |
|
|
|
|
|
class TestTRMM: |
|
"""Quick and simple tests for dtrmm.""" |
|
|
|
def setup_method(self): |
|
self.a = np.array([[1., 2., ], |
|
[-2., 1.]]) |
|
self.b = np.array([[3., 4., -1.], |
|
[5., 6., -2.]]) |
|
|
|
self.a2 = np.array([[1, 1, 2, 3], |
|
[0, 1, 4, 5], |
|
[0, 0, 1, 6], |
|
[0, 0, 0, 1]], order="f") |
|
self.b2 = np.array([[1, 4], [2, 5], [3, 6], [7, 8], [9, 10]], |
|
order="f") |
|
|
|
@pytest.mark.parametrize("dtype_", DTYPES) |
|
def test_side(self, dtype_): |
|
trmm = get_blas_funcs("trmm", dtype=dtype_) |
|
|
|
assert_raises(Exception, trmm, 1.0, self.a2, self.b2) |
|
res = trmm(1.0, self.a2.astype(dtype_), self.b2.astype(dtype_), |
|
side=1) |
|
k = self.b2.shape[1] |
|
assert_allclose(res, self.b2 @ self.a2[:k, :k], rtol=0., |
|
atol=100*np.finfo(dtype_).eps) |
|
|
|
def test_ab(self): |
|
f = getattr(fblas, 'dtrmm', None) |
|
if f is not None: |
|
result = f(1., self.a, self.b) |
|
|
|
expected = np.array([[13., 16., -5.], |
|
[5., 6., -2.]]) |
|
assert_array_almost_equal(result, expected) |
|
|
|
def test_ab_lower(self): |
|
f = getattr(fblas, 'dtrmm', None) |
|
if f is not None: |
|
result = f(1., self.a, self.b, lower=True) |
|
expected = np.array([[3., 4., -1.], |
|
[-1., -2., 0.]]) |
|
assert_array_almost_equal(result, expected) |
|
|
|
def test_b_overwrites(self): |
|
|
|
|
|
f = getattr(fblas, 'dtrmm', None) |
|
if f is not None: |
|
for overwr in [True, False]: |
|
bcopy = self.b.copy() |
|
result = f(1., self.a, bcopy, overwrite_b=overwr) |
|
|
|
assert_(bcopy.flags.f_contiguous is False and |
|
np.may_share_memory(bcopy, result) is False) |
|
assert_equal(bcopy, self.b) |
|
|
|
bcopy = np.asfortranarray(self.b.copy()) |
|
result = f(1., self.a, bcopy, overwrite_b=True) |
|
assert_(bcopy.flags.f_contiguous is True and |
|
np.may_share_memory(bcopy, result) is True) |
|
assert_array_almost_equal(bcopy, result) |
|
|
|
|
|
def test_trsm(): |
|
rng = np.random.default_rng(1234) |
|
for ind, dtype in enumerate(DTYPES): |
|
tol = np.finfo(dtype).eps*1000 |
|
func, = get_blas_funcs(('trsm',), dtype=dtype) |
|
|
|
|
|
A = rng.random((4, 5)).astype(dtype) |
|
B = rng.random((4, 4)).astype(dtype) |
|
alpha = dtype(1) |
|
assert_raises(Exception, func, alpha, A, B) |
|
assert_raises(Exception, func, alpha, A.T, B) |
|
|
|
n = 8 |
|
m = 7 |
|
alpha = dtype(-2.5) |
|
if ind < 2: |
|
A = rng.random((m, m)) + eye(m) |
|
else: |
|
A = (rng.random((m, m)) + rng.random((m, m))*1j) + eye(m) |
|
A = A.astype(dtype) |
|
Au = triu(A) |
|
Al = tril(A) |
|
B1 = rng.random((m, n)).astype(dtype) |
|
B2 = rng.random((n, m)).astype(dtype) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B1) |
|
assert_equal(B1.shape, x1.shape) |
|
x2 = solve(Au, alpha*B1) |
|
assert_allclose(x1, x2, atol=tol) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B1, trans_a=1) |
|
x2 = solve(Au.T, alpha*B1) |
|
assert_allclose(x1, x2, atol=tol) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B1, trans_a=2) |
|
x2 = solve(Au.conj().T, alpha*B1) |
|
assert_allclose(x1, x2, atol=tol) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B1, diag=1) |
|
Au[arange(m), arange(m)] = dtype(1) |
|
x2 = solve(Au, alpha*B1) |
|
assert_allclose(x1, x2, atol=tol) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B2, diag=1, side=1) |
|
x2 = solve(Au.conj().T, alpha*B2.conj().T) |
|
assert_allclose(x1, x2.conj().T, atol=tol) |
|
|
|
x1 = func(alpha=alpha, a=A, b=B2, diag=1, side=1, lower=1) |
|
Al[arange(m), arange(m)] = dtype(1) |
|
x2 = solve(Al.conj().T, alpha*B2.conj().T) |
|
assert_allclose(x1, x2.conj().T, atol=tol) |
|
|
|
|
|
@pytest.mark.xfail(run=False, |
|
reason="gh-16930") |
|
def test_gh_169309(): |
|
x = np.repeat(10, 9) |
|
actual = scipy.linalg.blas.dnrm2(x, 5, 3, -1) |
|
expected = math.sqrt(500) |
|
assert_allclose(actual, expected) |
|
|
|
|
|
def test_dnrm2_neg_incx(): |
|
|
|
|
|
|
|
x = np.repeat(10, 9) |
|
incx = -1 |
|
with assert_raises(fblas.__fblas_error): |
|
scipy.linalg.blas.dnrm2(x, 5, 3, incx) |
|
|