1.4 BLAS (BLAS routines for MLlib's vectors and matrices.)
BLAS(Basic Linear Algebra Subprograms,基礎線性代數程序集)是一個應用程序接口(API)標準,用以規範發佈基礎線性代數操作的數值庫(如矢量或矩陣乘法)。
BLAS按照功能被分爲三個級別:
Level 1:矢量-矢量運算
Level 2:矩陣-矢量運算
Level 3:矩陣-矩陣運算
在Spark Mlib 中,採用了BLAS線性代數運算庫,下面對BLAS中基本運算進行簡單介紹。
函數 |
名稱 |
點積 |
dot |
常數乘以向量加另一個向量 |
axpy |
準備Givens旋轉 |
rotg |
實施旋轉 |
rot |
準備修改過的Givens旋轉 |
rotmg |
實施修改過的旋轉 |
gotm |
把x複製到y |
copy |
交換x和y |
swap |
2-範數(歐幾里得長度) |
nrm2 |
絕對值求和 |
asum |
常數乘以向量 |
scal |
最大絕對值元素的索引 |
amax |
等等 |
…… |
參考文獻:
http://zh.wikipedia.org/wiki/BLAS
http://blog.csdn.net/q673327335/article/details/8547576
Spark Mlib BLAS源碼函數功能如下:
1.4.1 axpy
axpy函數功能:y += a * x,x、y爲相同維度向量,a爲係數。
/**
* y += a * x
*/
privatedef axpy(a: Double, x: DenseVector, y: DenseVector): Unit = {
val n = x.size
f2jBLAS.daxpy(n, a, x.values, 1, y.values, 1)
}
1.4.2 dot(x, y)
dot函數功能:x、y向量內積。
已知兩個非零向量a=(x1,y1),b=(x2,y2),則有a·b=x1x2+y1y2。
/**
* dot(x, y)
*/
privatedef dot(x: DenseVector, y: DenseVector): Double = {
val n = x.size
f2jBLAS.ddot(n, x.values, 1, y.values, 1)
}
1.4.3 copy (x, y)
copy函數功能:把向量x複製到向量y。
/**
* y = x
*/
def copy(x: Vector, y: Vector): Unit = {
1.4.4 scal (a, x)
scal函數功能:把向量x乘以常數a。
/**
* x = a * x
*/
def scal(a: Double, x: Vector): Unit = {
x match {
case sx: SparseVector =>
f2jBLAS.dscal(sx.values.size, a, sx.values, 1)
case dx: DenseVector =>
f2jBLAS.dscal(dx.values.size, a, dx.values, 1)
case _ =>
thrownew IllegalArgumentException(s"scal doesn't support vector type ${x.getClass}.")
}
}
1.4.5 syr (alpha, x, A)
執行對稱秩1操作。
/**
* A := alpha * x * x^T^ + A
* @param alpha a real scalar that will be multiplied to x * x^T^.
* @param x the vector x that contains the n elements.
* @param A the symmetric matrix A. Size of n x n.
*/
def syr(alpha: Double, x: Vector, A: DenseMatrix) {
val mA = A.numRows
val nA = A.numCols
require(mA == nA, s"A is not a square matrix (and hence is not symmetric). A: $mA x $nA")
require(mA == x.size, s"The size of x doesn't match the rank of A. A: $mA x $nA, x: ${x.size}")
x match {
case dv: DenseVector => syr(alpha, dv, A)
case sv: SparseVector => syr(alpha, sv, A)
case _ =>
thrownew IllegalArgumentException(s"syr doesn't support vector type ${x.getClass}.")
}
}
1.4.6 gemn(alpha, A, B, beta, C)
矩陣與矩陣相乘。
/**
* C := alpha * A * B + beta * C
* @param alpha a scalar to scale the multiplication A * B.
* @param A the matrix A that will be left multiplied to B. Size of m x k.
* @param B the matrix B that will be left multiplied by A. Size of k x n.
* @param beta a scalar that can be used to scale matrix C.
* @param C the resulting matrix C. Size of m x n. C.isTransposed must be false.
*/
def gemm(
alpha: Double,
A: Matrix,
B: DenseMatrix,
beta: Double,
C: DenseMatrix): Unit = {
require(!C.isTransposed,
"The matrix C cannot be the product of a transpose() call. C.isTransposed must be false.")
if (alpha == 0.0) {
logDebug("gemm: alpha is equal to 0. Returning C.")
} else {
A match {
case sparse: SparseMatrix => gemm(alpha, sparse, B, beta, C)
case dense: DenseMatrix => gemm(alpha, dense, B, beta, C)
case _ =>
thrownew IllegalArgumentException(s"gemm doesn't support matrix type ${A.getClass}.")
}
}
}
1.4.7 gemv (alpha, A, x, beta, y)
矩陣與向量相乘。
/**
* y := alpha * A * x + beta * y
* @param alpha a scalar to scale the multiplication A * x.
* @param A the matrix A that will be left multiplied to x. Size of m x n.
* @param x the vector x that will be left multiplied by A. Size of n x 1.
* @param beta a scalar that can be used to scale vector y.
* @param y the resulting vector y. Size of m x 1.
*/
def gemv(
alpha: Double,
A: Matrix,
x: DenseVector,
beta: Double,
y: DenseVector): Unit = {
require(A.numCols == x.size,
s"The columns of A don't match the number of elements of x. A: ${A.numCols}, x: ${x.size}")
require(A.numRows == y.size,
s"The rows of A don't match the number of elements of y. A: ${A.numRows}, y:${y.size}}")
if (alpha == 0.0) {
logDebug("gemv: alpha is equal to 0. Returning y.")
} else {
A match {
case sparse: SparseMatrix =>
gemv(alpha, sparse, x, beta, y)
case dense: DenseMatrix =>
gemv(alpha, dense, x, beta, y)
case _ =>
thrownew IllegalArgumentException(s"gemv doesn't support matrix type ${A.getClass}.")
}
}
}