Spark Mlib BLAS线性代数运算库,


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://www.netlib.org/blas/

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}.")

      }

    }

  }

相关内容