Scala中自己分解

Eigen decomposition in Scala

我想在 Scala 中(使用 Breeze)计算半正定矩阵的特征值和特征向量,但我被卡住了。

来自 Breeze 线性代数库参考示例:

val A = DenseMatrix((9.0,0.0,0.0),(0.0,82.0,0.0),(0.0,0.0,25.0))
val EigSym(lambda, evs) = eigSym(A)

首先在我的程序A中是一个协方差矩阵:

val EigSym(lambda,evs)=EigSym(cov)

我收到以下错误:

Error:(120, 34) not enough arguments for method apply: (eigenvalues: V, eigenvectors: M)breeze.linalg.eigSym.EigSym[V,M] in object EigSym.
Unspecified value parameter eigenvectors.
    val EigSym(lambda,evs)=EigSym(cov)
                                 ^

另一个参数应该是什么?

其次,任何人都可以为我解释为什么我们需要 "EigSym(lambda,evs)" 在左侧(我是 Scala 的新手,并且期望只是 (lambda,evs))。

谢谢!

第一个问题是eigSymEigSym不一样。 eigSym 是一个对象,它有一个 apply 方法接受一个 DenseMatrix,所以我们可以写 eigSym(A),这是语法糖(由 Scala 提供——它不是 Breeze 特定的) 对于 eigSym.apply(A).

因此以下内容将起作用:

import breeze.linalg._, eigSym.EigSym

val A = DenseMatrix((9.0,0.0,0.0),(0.0,82.0,0.0),(0.0,0.0,25.0))
val EigSym(lambda, evs) = eigSym(A)

val EigSym(lambda, evs) = ... 部分使用了 EigSyma case class 以及 eigSym returns 和 EigSym 的事实。定义左侧的 EigSym 解构了大小写 class 并定义了新的 lambdaevs 变量分配给 EigSym 的两个变量成员。你也可以这样写:

val es = eigSym(A)
val lambda = es.eigenvalues
val evs = es.eigenvectors

这是等价的,除了它还定义了一个 es 变量,而且它有点嘈杂和冗长。

更一般地说,如果 X 对象有一个接受正确类型参数的 unapply 方法(并且 X 有时在 Scala 中称为 "extractor")。 Scala case classes 有一个 unapply 方法由编译器自动为它们生成。

不过,这是很多语法糖,使用更冗长的赋值形式是完全合理的——请记住,如果您在其他人的代码中看到这种语法,您应该寻找一个案例 class 定义或 unapply 方法,如果你想弄清楚发生了什么。