Scala中的特征分解

Alt*_*Alt 2 scala linear-algebra breeze

我想计算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)
Run Code Online (Sandbox Code Playgroud)

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

val EigSym(lambda,evs)=EigSym(cov)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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)
                                 ^
Run Code Online (Sandbox Code Playgroud)

另一个论点应该是什么?

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

谢谢!

Tra*_*own 6

第一个问题是,eigSym并且EigSym是不同的.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)
Run Code Online (Sandbox Code Playgroud)

val EigSym(lambda, evs) = ...部分使用的EigSym一个案例类,并eigSym返回一个EigSym.在EigSym该定义的左手侧解构的情况下类,并定义新的lambdaevs已分配给变量EigSym的两个成员.您还可以编写以下内容:

val es = eigSym(A)
val lambda = es.eigenvalues
val evs = es.eigenvectors
Run Code Online (Sandbox Code Playgroud)

这是等价的,除了它还定义了一个es变量,它更嘈杂和冗长.

更一般地说,val X(a, b, c) = ...如果X对象具有unapply接受正确类型的参数的方法(并且X有时在Scala中称为"提取器"),则语法有效.Scala案例类具有unapply由编译器自动为它们生成的方法.

然而,这是很多语法糖,并且使用更详细的赋值形式是完全合理的 - 只要记住,如果你在其他人的代码中看到这种语法,你应该寻找一个案例类定义或一个unapply方法,如果你想知道发生了什么.