2016-08-19 19 views
1

私はBreezeを使って一次方程式の均質系を解こうとします。私は非自明な解決策Breezeで一次方程式の均質系を解く方法

を取得したい

アックス= 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が特異行列例外を投げているのか分かりませんが、文字通り 'Ax = 0'のような非ゼロベクトル' x'はありません。 –

+0

@AhmedFasih私は別の例を試しました。それは単純な解(すべてゼロ)を返すだけです。一般的に、私はBreezeで自明ではない解決策を得ることができますか?またはサンプルの例を教えてもらえますか?ありがとう –

+1

私はhttps://gist.github.com/fasiha/84c17532528b0274557ee2150df7e98dで 'Ax = 0'の解決策を見つける方法に関するいくつかの一般的なコメントを書いた。私はここでMatlabを使ったが、同じ原則はScipy/PythonとJulia and R 。:あなたはSVDを使用しています。私はScalaやBreezeがどのように動作するのか分かりませんが、SVDを使うことができれば、Ax = 0に非ゼロ解を得ることができます(Aがランク不足の場合)。 –

答えて

2

まず、あなたのコードは、このエラーを生成しますが、型エラーはありません、あなたのベクトル理由[Int]である。投稿する前に投稿したコードを実行してみてください。
第2に、行列にゼロ以外の行列式があるため、そのような解は存在しません。
あなたは、彼らが

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 

だから私たちは今、私たちはそのために使用できる行列を持つ線形依存になるように、私たちは、1行を変更することができそよ風

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 

で簡単にそれを見ることができます。 我々は特異値でそれを分解し、ゼロを探して私たちは、最後の値が(6.020650824737852E-16〜0) は、いくつかのゼロ値があるかもしれませんnullであることがわかります

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) 

値が、必要があります行列の場合行列式が0の場合、常に少なくとも1つ存在します。 現在、当社のヌル特異値の位置を除いてゼロの完全なベクトルを作成し、これはあなたが望んでいた非自明な解であること

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です。