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

      }

    }

  }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章