2

I want to calculate the eigenvalues and eigenvectors of a positive semi-definite matrix in Scala (using Breeze), and I'm stuck.

From the Breeze linear algebra library reference example:

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)

First of all in my program A is a covariance matrix:

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

and I'm getting the following error:

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)
                                 ^

What should the other argument be?

Secondly, can anyone explain for me why we need "EigSym(lambda,evs)" on the left hand side (I'm new to Scala, and expect just (lambda,evs)).

Thanks!

Alt
  • 2,597
  • 5
  • 26
  • 36

1 Answers1

6

The first issue is that eigSym and EigSym are different. eigSym is an object that has an apply method that accepts a DenseMatrix, so we can write eigSym(A), which is syntactic sugar (provided by Scala—it's not Breeze-specific) for eigSym.apply(A).

So the following will work:

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)

The val EigSym(lambda, evs) = ... part uses the fact that EigSym is a case class, and that eigSym returns an EigSym. The EigSym on the left-hand side of the definition deconstructs the case class and defines new lambda and evs variables that are assigned to EigSym's two members. You could also write the following:

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

This is equivalent, except that it also defines an es variable, and it's a little more noisy and verbose.

More generally, the val X(a, b, c) = ... syntax works if the X object has an unapply method that takes arguments of the right types (and the X is then sometimes called an "extractor" in Scala). Scala case classes have an unapply method automatically generated for them by the compiler.

That's a lot of syntactic sugar, though, and it's perfectly reasonable to use the more verbose form of assignment—just remember that if you see this kind of syntax in other people's code, you should either look for a case class definition or an unapply method if you want to figure out what's going on.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680