2016-08-19 142 views
1

我嘗試用Breeze求解線性方程的均勻系統。如何用Breeze求解線性方程的均勻系統

組Ax = 0

我希望得到一個平凡的解決方案

不過,我在尋找的非零解

我該怎麼辦了一些問題?

感謝

這是我的代碼:

val A =DenseMatrix(
    (1.0,2.0,3.0,2.0), 
    (1.0,3.0,5.0,5.0), 
    (2.0,4.0,7.0,1.0), 
    (-1.0,-2.0,-6.0,-7.0) 
    ) 

    val e = DenseVector(0,0,0,0) 

    val x = A \ e 

錯誤:

breeze.linalg.MatrixSingularException: 
at breeze.linalg.operators.DenseMatrixMultiplyStuff$implOpSolveMatrixBy_DMD_DMD_eq_DMD$.LUSolve(DenseMatrixOps.scala:151) 
at breeze.linalg.operators.DenseMatrixMultiplyStuff$implOpSolveMatrixBy_DMD_DMD_eq_DMD$.apply(DenseMatrixOps.scala:127) 
at breeze.linalg.operators.DenseMatrixMultiplyStuff$implOpSolveMatrixBy_DMD_DMD_eq_DMD$.apply(DenseMatrixOps.scala:115) 
at breeze.linalg.ImmutableNumericOps$class.$bslash(NumericOps.scala:144) 
at breeze.linalg.DenseMatrix.$bslash(DenseMatrix.scala:53) 
at breeze.linalg.operators.DenseMatrixMultiplyStuff$implOpSolveMatrixBy_DMD_DVD_eq_DVD$.apply(DenseMatrixOps.scala:221) 
at breeze.linalg.operators.DenseMatrixMultiplyStuff$implOpSolveMatrixBy_DMD_DVD_eq_DVD$.apply(DenseMatrixOps.scala:218) 
at breeze.linalg.ImmutableNumericOps$class.$bslash(NumericOps.scala:144) 
at breeze.linalg.DenseMatrix.$bslash(DenseMatrix.scala:53) 
at .<init>(<console>:27) 
at .<clinit>(<console>) 
at .<init>(<console>:7) 
at .<clinit>(<console>) 
at $print(<console>) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734) 
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983) 
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573) 
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604) 
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568) 
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:760) 
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805) 
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:717) 
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:581) 
at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:588) 
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:591) 
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:882) 
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837) 
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837) 
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135) 
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:837) 
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:904) 
at org.jetbrains.plugins.scala.compiler.rt.ConsoleRunner.main(ConsoleRunner.java:64) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 
+0

您的矩陣是滿秩(*所有*特徵值都不爲零)。這意味着它的零空間(映射到0向量的輸入空間子空間)只包含0向量。不知道爲什麼Breeze拋出一個奇異的矩陣異常,但實際上沒有非零向量'x',使得'Ax = 0'。 –

+0

@AhmedFasih我試過另一個例子。它只返回平凡的解決方案(全零)。一般來說,我可以在Breeze中獲得一個不重要的解決方案嗎?或者你能舉一個例子嗎?謝謝 –

+1

我在https://gist.github.com/fasiha/84c17532528b0274557ee2150df7e98d上提供了一些關於如何找到'Ax = 0'解決方案的一般性意見。我在這裏使用了Matlab,但是相同的原理在Scipy/Python和Julia以及R等工作。:你使用SVD。我不知道Scala或Breeze是如何工作的,但如果你可以採用SVD,你可以得到'Ax = 0'的非零解(如果A是等級不足的話)。 –

回答

2

首先,你的代碼不會產生這個錯誤,而是一個類型錯誤,因爲你的載體是[Int]。在發佈之前嘗試運行您發佈的代碼。
其次,你的矩陣有非零行列式,所以沒有這樣的解決方案。
你可以看到,很容易與微風

scala> import breeze.linalg._ 
import breeze.linalg._ 

scala> val A =DenseMatrix(
    |  (1.0,2.0,3.0,2.0), 
    |  (1.0,3.0,5.0,5.0), 
    |  (2.0,4.0,7.0,1.0), 
    |  (-1.0,-2.0,-6.0,-7.0) 
    | ) 
A: breeze.linalg.DenseMatrix[Double] = 
1.0 2.0 3.0 2.0 
1.0 3.0 5.0 5.0 
2.0 4.0 7.0 1.0 
-1.0 -2.0 -6.0 -7.0 
scala> det(A) 
res6: Double = -14.0 

我們可以改變一個行,使他們成爲線性相關

scala> val nl = DenseVector(1,2,-1,0.0).t * A 
ago 19, 2016 6:47:22 PM com.github.fommil.netlib.BLAS <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS 
ago 19, 2016 6:47:22 PM com.github.fommil.netlib.BLAS <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeRefBLAS 
nl: breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]] = Transpose(DenseVector(1.0, 4.0, 6.0, 11.0)) 


scala> val C = A.copy 
C: breeze.linalg.DenseMatrix[Double] = 
1.0 2.0 3.0 2.0 
1.0 3.0 5.0 5.0 
2.0 4.0 7.0 1.0 
-1.0 -2.0 -6.0 -7.0 

scala> C(3,::) := nl 
res1: breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]] = Transpose(DenseVector(1.0, 4.0, 6.0, 11.0)) 

scala> C 
res2: breeze.linalg.DenseMatrix[Double] = 
1.0 2.0 3.0 2.0 
1.0 3.0 5.0 5.0 
2.0 4.0 7.0 1.0 
1.0 4.0 6.0 11.0 

scala> det(C) 
ago 19, 2016 6:48:17 PM com.github.fommil.netlib.LAPACK <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeSystemLAPACK 
ago 19, 2016 6:48:17 PM com.github.fommil.netlib.LAPACK <clinit> 
WARNING: Failed to load implementation from: com.github.fommil.netlib.NativeRefLAPACK 
res3: Double = -0.0 

所以我們現在擁有了一個可以使用一個矩陣。 我們必須分解它的奇異值,並尋找零值

scala> val svd.SVD(u,s,v) = svd(C) 
u: breeze.linalg.DenseMatrix[Double] = 
-0.2418695880246191 0.18180320883181855 0.8749797442170381 -0.3779644730092261 
-0.4572321583765708 0.05780050748664106 -0.46494008565837486 -0.755928946018455 
-0.39944397391966924 0.8267072956674623 -0.11892189088772076 0.3779644730092271 
-0.7568899308580912 -0.5293030718623615 0.0640214637880056 0.3779644730092274 
s: breeze.linalg.DenseVector[Double] = DenseVector(16.921266409229123, 5.964439026615583, 0.31017770016412793, 6.020650824737852E-16) 
v: breeze.linalg.DenseMatrix[Double] = 
-0.13325714344103542 -0.3829956407255237 -0.6116100715073144 -0.6793305479205232 
0.22864098865050173 0.28948654309971367 0.5776812852057681 -0.7281518882733954 
0.7615548778852732 0.43696733513844804 -0.4774219714970357 0.03408... 
scala> s 
res4: breeze.linalg.DenseVector[Double] = DenseVector(16.921266409229123, 5.964439026615583, 0.31017770016412793, 6.020650824737852E-16) 

我們可以看到,最後一個值是零(6.020650824737852E-16〜0) 可能有幾個零個值,但如果矩陣具有行列式0,總會有至少一個。 現在,我們創建一個完整的零向量,除了在我們的空奇異值的位置,並通過它

scala> val nts = v.t * DenseVector(0,0,0,1.0) 
nts: breeze.linalg.DenseVector[Double] = DenseVector(0.5916079783099643, -0.7606388292556632, 0.25354627641855365, 0.08451542547285162) 

這是你想要的非平凡解乘以矩陣V的轉置。我們可以檢查它:

scala> C * nts 
res5: breeze.linalg.DenseVector[Double] = DenseVector(2.1094237467877974E-15, 1.4432899320127035E-15, 2.9976021664879227E-15, 1.4432899320127035E-15) 

而且我們可以看到它是0除了舍入錯誤。