question about SVD

21 views
Skip to first unread message

Jim Newton

unread,
Apr 4, 2021, 11:58:54 AM4/4/21
to Scala Breeze
I notice that the `svd` function gives me a decomposition, (u,s,v), where `s` seems to be the vector consisting of eigenvalues, but u*v is not always the inverse.  Sometimes it seems to be the negative of the inverse.   Is that intended.   As I recall in the singular value decomposition u and v are inverses of each other.

Am I confused?

Alec Zorab

unread,
Apr 6, 2021, 4:52:27 AM4/6/21
to Scala Breeze
from memory, I think the breeze SVD gives you (u, s, vt)

On Sun, 4 Apr 2021 at 16:58, Jim Newton <jimka...@gmail.com> wrote:
I notice that the `svd` function gives me a decomposition, (u,s,v), where `s` seems to be the vector consisting of eigenvalues, but u*v is not always the inverse.  Sometimes it seems to be the negative of the inverse.   Is that intended.   As I recall in the singular value decomposition u and v are inverses of each other.

Am I confused?

--
You received this message because you are subscribed to the Google Groups "Scala Breeze" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-breeze...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/scala-breeze/25ae5000-8a2a-4856-a77b-4415f6a6e877n%40googlegroups.com.

Jim Newton

unread,
Apr 7, 2021, 3:52:13 AM4/7/21
to Scala Breeze
Some experimentation seems to show that it is v, not vt.
The following test passes.  So I think svt returns (u,s,v) such that u*diag(s)*v equal the original matrix.

test("breeze"){
  import breeze.linalg._
  import scala.util.Random
  def maxabsnorm(dim:Int, m:DenseMatrix[Double]):Double = {
    (0 until dim).foldLeft(m(0,0)){(acc:Double,row:Int) =>
      val x = (0 until dim).foldLeft(m(0,0)){
        (acc:Double,col:Int) => math.max(acc,math.abs(m(row,col)))}
      math.max(acc,x)
    }
  }
  for{dim <- 1 to 4} {
    val dm1: DenseMatrix[Double] = DenseMatrix.tabulate(dim, dim)((_, _)=>Random.between(-10.0, 10.0))
    val svd.SVD(u, s, v) = svd(dm1)
    val dm2 = u * diag(s) * v
    val dist:Double = maxabsnorm(dim,dm2 - dm1)
    assert(dist < 0.001, s"dist=$dist dm1=[$dm1] dm2=[$dm2] diff=[${dm2-dm1}]")
  }
}

Alec Zorab

unread,
Apr 7, 2021, 7:35:28 AM4/7/21
to Scala Breeze

--
You received this message because you are subscribed to the Google Groups "Scala Breeze" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-breeze...@googlegroups.com.

Jim Newton

unread,
Apr 7, 2021, 8:17:08 AM4/7/21
to Scala Breeze
is my `maxabsnorm` function buggy?  I could not figure out how to use the built-in norm function to measure the norm of dm2-dm1.

Darren Wilkinson

unread,
Apr 8, 2021, 11:19:36 AM4/8/21
to Scala Breeze
It is vt - the function returns (u, s, vt). But it is correct that u * diag(s) * vt is the original matrix. I think that this is all fine.
Reply all
Reply to author
Forward
0 new messages