在scalaNLP微风的复杂矩阵上使用kronecker产品

时间:2016-06-09 06:31:36

标签: scala matrix vector scala-breeze

我有一段代码:

def this(vectors: List[DenseVector[Double]]) {
    this(vectors.length)
    var resultVector = vectors.head
    for (vector <- vectors) {
        resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
    }
    _vector = resultVector
}

它的工作方式与我希望它的工作方式相同。问题是我需要复杂的价值而不是双打。导入breeze.math.Complex后,我将代码更改为:

def this(vectors: List[DenseVector[Complex]]) {
    this(vectors.length)
    var resultVector = vectors.head
    for (vector <- vectors) {
       resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
    }
    _vector = resultVector
}

然而,这会导致错误:

Error:(42, 26) could not find implicit value for parameter impl: breeze.linalg.kron.Impl2[breeze.linalg.DenseMatrix[breeze.math.Complex],breeze.linalg.DenseMatrix[breeze.math.Complex],VR]
      resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
                         ^

Error:(42, 26) not enough arguments for method apply: (implicit impl: breeze.linalg.kron.Impl2[breeze.linalg.DenseMatrix[breeze.math.Complex],breeze.linalg.DenseMatrix[breeze.math.Complex],VR])VR in trait UFunc.
Unspecified value parameter impl.
      resultVector = kron(resultVector.toDenseMatrix, vector.toDenseMatrix).toDenseVector
                         ^

这是一个错误还是我忘了做某事?

1 个答案:

答案 0 :(得分:0)

我通过以下方式找到了问题:

  1. 我首先重写了函数以使用更少的矩阵转换
  2. 由于kron的隐式impl变量存在问题,我还重写了函数调用以明确说明要使用哪个变量
  3. def this(vectors: List[DenseVector[Complex]]) {
        this(vectors.length)
        var resultMatrix = vectors.head.toDenseMatrix
        for (i <- 1 until vectors.length) {
             resultMatrix = kron(resultMatrix, vectors(i).toDenseMatrix)(kron.kronDM_M[Complex, Complex, DenseMatrix[Complex], Complex])
        }
        _vector = resultMatrix.toDenseVector
    }
    

    这向我显示ScalarMulOpV2M DenseMatrix[RV] MMatrix[V1]V1 V2 }和RV是输入类型,ScalarMulOpDenseMatrixOps

    的输出类型

    ScalarMulOp中找到微风的源代码,如果V1V2和{{1},上述类型只有隐式RV属于IntLongFloatDouble类型。通过复制函数并使其特定于复数,我能够使kronecker产品起作用。现在我也可以删除显式使用(kron.kronDM_M[Complex, Complex, DenseMatrix[Complex], Complex])。有问题的ScalarMulOp函数是:

    implicit def s_dm_op_Complex_OpMulScalar(implicit op: OpMulScalar.Impl2[Complex, Complex, Complex]):
      OpMulScalar.Impl2[Complex, DenseMatrix[Complex], DenseMatrix[Complex]] =
    
        new OpMulScalar.Impl2[Complex, DenseMatrix[Complex], DenseMatrix[Complex]] {
          def apply(b: Complex, a: DenseMatrix[Complex]): DenseMatrix[Complex] = {
            val res: DenseMatrix[Complex] = DenseMatrix.zeros[Complex](a.rows, a.cols)
            val resd: Array[Complex] = res.data
            val ad: Array[Complex] = a.data
            var c = 0
    
            var off = 0
            while (c < a.cols) {
              var r = 0
              while (r < a.rows) {
                resd(off) = op(b, ad(a.linearIndex(r, c)))
                r += 1
                off += 1
              }
              c += 1
            }
    
            res
          }
    
          implicitly[BinaryRegistry[Complex, Matrix[Complex], OpMulScalar.type, Matrix[Complex]]].register(this)
        }