haifengl / smile

Statistical Machine Intelligence & Learning Engine
https://haifengl.github.io
Other
5.99k stars 1.12k forks source link

[Bug?] Matrix multiplication gives different result between `.tm()` and `.transpose().mm()` #715

Closed CXwudi closed 2 years ago

CXwudi commented 2 years ago

Describe the bug Let's say I have two matrix:

a = [
  -4.0000
   1.0000
  -3.0000
] // 3*1 matrix

b = [
          4.0000       1.2000       0.8000
          1.2000       9.0000       1.2000
          0.8000       1.2000      16.0000
] // 3*3 matrix

Then, a.tm(b.inverse()) returns the correct result, which is a 1*3 matrix [-1.0505 0.2719 -0.1554]
But a.transpose().mm(b.inverse()) would return [0.0000 0.0000 0.0000]

Expected behavior

Both a.tm(b.inverse()) and a.transpose().mm(b.inverse()) should return the correct result, which is a 1*3 matrix [-1.0505 0.2719 -0.1554]

Actual behavior

a.transpose().mm(b.inverse()) returns an empty 1*3 matrix which is [0.0000 0.0000 0.0000]

Code snippet See above

Input data See above

Additional context

haifengl commented 2 years ago

I cannot reproduce this bug with latest code. Can you please try master branch?

CXwudi commented 2 years ago

I cannot reproduce this bug with latest code. Can you please try master branch?

Would you mind provide a guide to build this awesome library locally

haifengl commented 2 years ago

See http://haifengl.github.io/quickstart.html

CXwudi commented 2 years ago

Hi, sorry for the late reply, I tried to compile and added these jars into my build file

  testImplementation(files("libs/smile-base-3.0.0.jar"))
  testImplementation(files("libs/smile-core-3.0.0.jar"))
  testImplementation(files("libs/smile-plot-3.0.0.jar"))
  testImplementation(files("libs/smile-npl-3.0.0.jar"))

Good that I am not getting [0.0000 0.0000 0.0000] anymore,
but now tm() and .transpose().mm() returns different results:

03:27:12.316 [pool-1-thread-1 @coroutine#3] INFO scs.comp5107.a4.poc.MatrixMulPocTest - result from tm() = 1 x 3
      -1.0505       0.2719      -0.1554

03:27:12.324 [pool-1-thread-1 @coroutine#3] INFO scs.comp5107.a4.poc.MatrixMulPocTest - result from transpose().mm() = 1 x 3
      -1.0487       0.1342       0.0424

Btw, this is the kotlin code I used to reproduce the bug

  val m2 = Matrix.column(doubleArrayOf(-4.0, 1.0, -3.0))
  val cov2 = Matrix(3, 3, 3, doubleArrayOf(4.0000, 1.2000, 0.8000, 1.2000, 9.0000, 1.2000, 0.8000, 1.2000, 16.0000))

  context("about multiplication of matrix") {
    should("correctly compute with tm()") {
      val result = m2.tm(cov2.inverse())
      log.info { "result from tm() = $result" }
    }
    should("correctly compute with transpose().mm()") {
      val result = m2.transpose().mm(cov2.inverse())
      log.info { "result from transpose().mm() = $result" }
    }
  }
haifengl commented 2 years ago

Thanks. .transpose().mm() is wrong. The fix is in master now. Please have a try.

CXwudi commented 2 years ago

It works now 😄. Thanks for the effort and closing the issue now