You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
8.5 KiB
Python
396 lines
8.5 KiB
Python
"""
|
|
Low-level BLAS functions (:mod:`scipy.linalg.blas`)
|
|
===================================================
|
|
|
|
This module contains low-level functions from the BLAS library.
|
|
|
|
.. versionadded:: 0.12.0
|
|
|
|
.. note::
|
|
|
|
The common ``overwrite_<>`` option in many routines, allows the
|
|
input arrays to be overwritten to avoid extra memory allocation.
|
|
However this requires the array to satisfy two conditions
|
|
which are memory order and the data type to match exactly the
|
|
order and the type expected by the routine.
|
|
|
|
As an example, if you pass a double precision float array to any
|
|
``S....`` routine which expects single precision arguments, f2py
|
|
will create an intermediate array to match the argument types and
|
|
overwriting will be performed on that intermediate array.
|
|
|
|
Similarly, if a C-contiguous array is passed, f2py will pass a
|
|
FORTRAN-contiguous array internally. Please make sure that these
|
|
details are satisfied. More information can be found in the f2py
|
|
documentation.
|
|
|
|
.. warning::
|
|
|
|
These functions do little to no error checking.
|
|
It is possible to cause crashes by mis-using them,
|
|
so prefer using the higher-level routines in `scipy.linalg`.
|
|
|
|
Finding functions
|
|
-----------------
|
|
|
|
.. autosummary::
|
|
:toctree: generated/
|
|
|
|
get_blas_funcs
|
|
find_best_blas_type
|
|
|
|
BLAS Level 1 functions
|
|
----------------------
|
|
|
|
.. autosummary::
|
|
:toctree: generated/
|
|
|
|
caxpy
|
|
ccopy
|
|
cdotc
|
|
cdotu
|
|
crotg
|
|
cscal
|
|
csrot
|
|
csscal
|
|
cswap
|
|
dasum
|
|
daxpy
|
|
dcopy
|
|
ddot
|
|
dnrm2
|
|
drot
|
|
drotg
|
|
drotm
|
|
drotmg
|
|
dscal
|
|
dswap
|
|
dzasum
|
|
dznrm2
|
|
icamax
|
|
idamax
|
|
isamax
|
|
izamax
|
|
sasum
|
|
saxpy
|
|
scasum
|
|
scnrm2
|
|
scopy
|
|
sdot
|
|
snrm2
|
|
srot
|
|
srotg
|
|
srotm
|
|
srotmg
|
|
sscal
|
|
sswap
|
|
zaxpy
|
|
zcopy
|
|
zdotc
|
|
zdotu
|
|
zdrot
|
|
zdscal
|
|
zrotg
|
|
zscal
|
|
zswap
|
|
|
|
BLAS Level 2 functions
|
|
----------------------
|
|
|
|
.. autosummary::
|
|
:toctree: generated/
|
|
|
|
sgbmv
|
|
sgemv
|
|
sger
|
|
ssbmv
|
|
sspr
|
|
sspr2
|
|
ssymv
|
|
ssyr
|
|
ssyr2
|
|
stbmv
|
|
stpsv
|
|
strmv
|
|
strsv
|
|
dgbmv
|
|
dgemv
|
|
dger
|
|
dsbmv
|
|
dspr
|
|
dspr2
|
|
dsymv
|
|
dsyr
|
|
dsyr2
|
|
dtbmv
|
|
dtpsv
|
|
dtrmv
|
|
dtrsv
|
|
cgbmv
|
|
cgemv
|
|
cgerc
|
|
cgeru
|
|
chbmv
|
|
chemv
|
|
cher
|
|
cher2
|
|
chpmv
|
|
chpr
|
|
chpr2
|
|
ctbmv
|
|
ctbsv
|
|
ctpmv
|
|
ctpsv
|
|
ctrmv
|
|
ctrsv
|
|
csyr
|
|
zgbmv
|
|
zgemv
|
|
zgerc
|
|
zgeru
|
|
zhbmv
|
|
zhemv
|
|
zher
|
|
zher2
|
|
zhpmv
|
|
zhpr
|
|
zhpr2
|
|
ztbmv
|
|
ztbsv
|
|
ztpmv
|
|
ztrmv
|
|
ztrsv
|
|
zsyr
|
|
|
|
BLAS Level 3 functions
|
|
----------------------
|
|
|
|
.. autosummary::
|
|
:toctree: generated/
|
|
|
|
sgemm
|
|
ssymm
|
|
ssyr2k
|
|
ssyrk
|
|
strmm
|
|
strsm
|
|
dgemm
|
|
dsymm
|
|
dsyr2k
|
|
dsyrk
|
|
dtrmm
|
|
dtrsm
|
|
cgemm
|
|
chemm
|
|
cher2k
|
|
cherk
|
|
csymm
|
|
csyr2k
|
|
csyrk
|
|
ctrmm
|
|
ctrsm
|
|
zgemm
|
|
zhemm
|
|
zher2k
|
|
zherk
|
|
zsymm
|
|
zsyr2k
|
|
zsyrk
|
|
ztrmm
|
|
ztrsm
|
|
|
|
"""
|
|
#
|
|
# Author: Pearu Peterson, March 2002
|
|
# refactoring by Fabian Pedregosa, March 2010
|
|
#
|
|
|
|
from __future__ import division, print_function, absolute_import
|
|
|
|
__all__ = ['get_blas_funcs', 'find_best_blas_type']
|
|
|
|
import numpy as _np
|
|
|
|
from scipy.linalg import _fblas
|
|
try:
|
|
from scipy.linalg import _cblas
|
|
except ImportError:
|
|
_cblas = None
|
|
|
|
# Expose all functions (only fblas --- cblas is an implementation detail)
|
|
empty_module = None
|
|
from scipy.linalg._fblas import *
|
|
del empty_module
|
|
|
|
# 'd' will be default for 'i',..
|
|
_type_conv = {'f': 's', 'd': 'd', 'F': 'c', 'D': 'z', 'G': 'z'}
|
|
|
|
# some convenience alias for complex functions
|
|
_blas_alias = {'cnrm2': 'scnrm2', 'znrm2': 'dznrm2',
|
|
'cdot': 'cdotc', 'zdot': 'zdotc',
|
|
'cger': 'cgerc', 'zger': 'zgerc',
|
|
'sdotc': 'sdot', 'sdotu': 'sdot',
|
|
'ddotc': 'ddot', 'ddotu': 'ddot'}
|
|
|
|
|
|
def 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 scipy.linalg.blas as bla
|
|
>>> a = np.random.rand(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)
|
|
|
|
"""
|
|
dtype = _np.dtype(dtype)
|
|
prefer_fortran = False
|
|
|
|
if arrays:
|
|
# use the most generic type in arrays
|
|
dtypes = [ar.dtype for ar in arrays]
|
|
dtype = _np.find_common_type(dtypes, ())
|
|
try:
|
|
index = dtypes.index(dtype)
|
|
except ValueError:
|
|
index = 0
|
|
if arrays[index].flags['FORTRAN']:
|
|
# prefer Fortran for leading array with column major order
|
|
prefer_fortran = True
|
|
|
|
prefix = _type_conv.get(dtype.char, 'd')
|
|
if dtype.char == 'G':
|
|
# complex256 -> complex128 (i.e., C long double -> C double)
|
|
dtype = _np.dtype('D')
|
|
elif dtype.char not in 'fdFD':
|
|
dtype = _np.dtype('d')
|
|
|
|
return prefix, dtype, prefer_fortran
|
|
|
|
|
|
def _get_funcs(names, arrays, dtype,
|
|
lib_name, fmodule, cmodule,
|
|
fmodule_name, cmodule_name, alias):
|
|
"""
|
|
Return available BLAS/LAPACK functions.
|
|
|
|
Used also in lapack.py. See get_blas_funcs for docstring.
|
|
"""
|
|
|
|
funcs = []
|
|
unpack = False
|
|
dtype = _np.dtype(dtype)
|
|
module1 = (cmodule, cmodule_name)
|
|
module2 = (fmodule, fmodule_name)
|
|
|
|
if isinstance(names, str):
|
|
names = (names,)
|
|
unpack = True
|
|
|
|
prefix, dtype, prefer_fortran = find_best_blas_type(arrays, dtype)
|
|
|
|
if prefer_fortran:
|
|
module1, module2 = module2, module1
|
|
|
|
for i, name in enumerate(names):
|
|
func_name = prefix + name
|
|
func_name = alias.get(func_name, func_name)
|
|
func = getattr(module1[0], func_name, None)
|
|
module_name = module1[1]
|
|
if func is None:
|
|
func = getattr(module2[0], func_name, None)
|
|
module_name = module2[1]
|
|
if func is None:
|
|
raise ValueError(
|
|
'%s function %s could not be found' % (lib_name, func_name))
|
|
func.module_name, func.typecode = module_name, prefix
|
|
func.dtype = dtype
|
|
func.prefix = prefix # Backward compatibility
|
|
funcs.append(func)
|
|
|
|
if unpack:
|
|
return funcs[0]
|
|
else:
|
|
return funcs
|
|
|
|
|
|
def get_blas_funcs(names, arrays=(), dtype=None):
|
|
"""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.
|
|
|
|
|
|
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 scipy.linalg as LA
|
|
>>> a = np.random.rand(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'
|
|
|
|
"""
|
|
return _get_funcs(names, arrays, dtype,
|
|
"BLAS", _fblas, _cblas, "fblas", "cblas",
|
|
_blas_alias)
|