使用 scalaNLP breeze 在复杂矩阵上使用 kronecker 产品

Using the kronecker product on complex matrices with scalaNLP 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. 我首先重写了函数以使用更少的矩阵转换
  2. 由于kron的隐式impl变量有问题,我也重写了函数调用,明确说明使用哪个变量

.

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
}

这告诉我 V2MDenseMatrix[RV] 没有 ScalarMulOp,其中 MMatrix[V1]V1V2 是输入类型,RVScalarMulOp

的输出类型

挖掘 breeze 的源代码,我在 DenseMatrixOps 中发现,如果 V1、[=14=,则上述类型只有一个隐式 ScalarMulOp ] 和 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)
    }