scalanlp / breeze

Breeze is/was a numerical processing library for Scala.
https://www.scalanlp.org
Apache License 2.0
3.45k stars 693 forks source link

how to find the norm of a matrix #803

Open jimka2001 opened 3 years ago

jimka2001 commented 3 years ago

I'm trying to call the norm function, as documented in the cheat sheet. https://github.com/scalanlp/breeze/wiki/Linear-Algebra-Cheat-Sheet

Here is the code I'm trying to compile, and the compilation error is shown below. What is the correct way to find out if two matrices of the same dimensions are equal within a given epsilon? Am I doing it wrong?

test("breeze"){
  import breeze.linalg._
  import scala.util.Random
  for{dim <- 1 to 4} {
    val dm1 = DenseMatrix.tabulate(dim, dim)((_,_)=>Random.between(-10.0,10.0))
    val svd.SVD(u, s, vt) = svd(dm1)
    val dm2 = u * diag(s) * vt.t
    val dist:Double = norm(dm2 - dm1) /// <--- this fails to compile
    assert(dist < 0.001, s"dist=$dist dm1=[$dm1] dm2=[$dm2]")
  }
}

But I get a compilation error about a missing implicit. I don't see information in the cheat sheet about how to get the implicits.

/Users/jnewton/Repos/scalain_e/scalain-e-course-code/src/test/scala/TranscendentalsTestSuite.scala:493:29
could not find implicit value for parameter impl: breeze.linalg.norm.Impl[breeze.linalg.DenseMatrix[Double],VR]
      val dist:Double = norm(dm2 - dm1)
dlwh commented 3 years ago

we don't define norm on Matrices, which is an oversight but in part because it wasn't clear what the default norm should be for matrices (elementwise, frobenius etc). If you flatten to a vector, norm will work.

On Wed, Apr 7, 2021 at 1:05 AM Jim Newton @.***> wrote:

I'm trying to call the norm function, as documented in the cheat sheet. https://github.com/scalanlp/breeze/wiki/Linear-Algebra-Cheat-Sheet

Here is the code I'm trying to compile, and the compilation error is shown below. What is the correct way to find out if two matrices of the same dimensions are equal within a given epsilon? Am I doing it wrong?

test("breeze"){ import breeze.linalg. import scala.util.Random for{dim <- 1 to 4} { val dm1 = DenseMatrix.tabulate(dim, dim)((,_)=>Random.between(-10.0,10.0)) val svd.SVD(u, s, vt) = svd(dm1) val dm2 = u diag(s) vt.t val dist:Double = norm(dm2 - dm1) /// <--- this fails to compile assert(dist < 0.001, s"dist=$dist dm1=[$dm1] dm2=[$dm2]") } }

But I get a compilation error about a missing implicit. I don't see information in the cheat sheet about how to get the implicits.

/Users/jnewton/Repos/scalain_e/scalain-e-course-code/src/test/scala/TranscendentalsTestSuite.scala:493:29 could not find implicit value for parameter impl: breeze.linalg.norm.Impl[breeze.linalg.DenseMatrix[Double],VR] val dist:Double = norm(dm2 - dm1)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/scalanlp/breeze/issues/803, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAACLIIBIFUB3MZR3QXATRDTHQG3NANCNFSM42QIWLBA .

jimka2001 commented 3 years ago

For testing whether two matrices are equal within epsilon, I think any norm works. How do people normally check whether two matrices are almost equal? Is flatting to a vector, and using the vector norm, the usual way? Or is there some sort of fold/reduce function I should be using, which should be faster and more memory efficient anyway?

darrenjw commented 3 years ago

For testing purposes (eg. in unit and property based tests), I tend to just use sum(abs(A)). But I think it would make sense to have the Frobenious norm in Breeze. Flattening and applying the vector norm should be quite efficient, I think.

jimka2001 commented 3 years ago

I'm using max(abs(...))