2011-01-29 7 views
2

私はJama Matrixで作業しています。私はLSIに使った。それはすべて正常に動作します。しかし、私が8000x8000のような大きな行列を渡すと、私のシステム全体が殺されます。私は単純にSVDを呼び出して行列のサイズを減らして加算します。他に何もない!Java Jama行列

どうすればこの問題を解決できますか?

core2du

ラム= 10ギガバイト

設定

Javaランタイム

-Xmx5000M

私はジャママトリクスコードに

+1

「私のシステム全体を殺す」とはどういう意味ですか?あなたが 'OutOfMemoryError'を取得した場合、これは8000x200の配列が約12Mbのメモリを必要とするためです。 SVDのコンストラクタは、新しい配列のスタック全体を作成します。その1回の呼び出しでも、JVMの64Mbのデフォルト最大メモリー割り当てに近づいている可能性があります(Oracle/Sun JVMを使用していると仮定します)。 – Ash

+0

ご意見ありがとうございます。私のコンピュータには10GBのRAMがあります。 JDK 1.5を使用していて、私のプログラムにすでに5GBを割り当てました。私は混乱のために申し訳ありません。私のシステム全体を殺すという意味で、Jamaと共にこの小さな行列を処理するには数日かかる。私は他のものを使用していません。私は単純な行列をJamaパッケージに渡すだけです。 – Tweet

+2

SVDがO(n^3)のように見えるので、別のライブラリや小さな行列を使って問題を解決すると思われます。それに失敗した場合は、メモリまたはCPUにバインドされているかどうかをプロファイリング(jvisualvmなど)して調べることができます。小規模なケースで測定し、必要な実行時間を見積もることができます。 –

答えて

2

また、Jama for SVDを使用し、大きな行列を解く際にも同じ問題があります。 メモリオーバーフローのケースを減らすために、私はSingularValueDecomposition.javaをコンパクトに調整しました。チューニングは、A、U、V、Workなどのように使用されるすべての行列のコンパクトが0より大きい利用可能な値のメモリしか許容しないように、行列Aにそれほど多くの0(ゼロ)値を有することである。 コンパクトSVDを使用すると、行列ファイルは r/tc/t値/ n r/tc/t値/ n ... '/ t'と '/ n'はそれぞれタブと改行を意味する。

例:(0,0,0)、(0,1,0)、(0,2,0)、(0,3,0)、(1,0,1)、(1,1) 、0)、(1,2,0)、(1,3,3)、マトリックスサイズが2 * 4(R * C)の場合は、 MATRIXSIZE/t 2/t 4/nのようなファイルを作成します。 0/T 1/T 0.5/N 0/T 3/T 0.2/N 1/T 0/T 1/N 1/T 3/T 0.3/N

あなたがそれを使用したい場合、あなたのメールアドレス([email protected])を教えてください。 私は電子メールでそれを使用するための詳細を提供します。

私は結果が正しいことを確認しました。しかし、私はコンピュータにとってどれだけ効果的かは分かりません。 とにかく、あまり好きではないにもかかわらず、うまく動作しています。

1

を実行しながら、あなたはおそらく直面している実行中の他のプログラムがありませんメモリ不足状態です。たとえば、-Xmxオプションを使用してJVMで使用可能なメモリーを増やしたい場合があります。たとえば、Xm256mはデフォルトの64 MBではなく、JVMに256 MBを与えます。

また、COO、DOK、CSRなどのスパース行列のモデルを使用して、メモリ効率のよい行列表現を扱う代替ライブラリを使用することを検討することもできます...詳細については、「スパース行列」のWikipediaエントリを参照してください。

This threadは、Jamaに代わるいくつかの方法を提供しています。

+0

もう一度私の質問を読むことができますか?コメント? – Tweet

0

ピーター・テイラーはまさに正しいです。

指数関数的な大きな問題です。あなたが64,000,000要素を話しているので、すべての後に8000×8000行列のSVDを計算することはケーキではありません!

あなたはJAMA MagicSquareExampleを実行した場合、で:

32×32のマトリクス経過時間0.062秒です。
64×64は1716.719秒で
512×512 83.625秒で46.063秒で
224x224 24.063秒で11.109秒で4.5秒で1.891秒で
128×128を経過する
160×160 0.0328秒に

enter image description here
256×256を
192x192を
に96x96を上がります

0

LSIを使用している場合は、2つの重要な最適化を行うことができます。まず、あなたの行列が疎です(文書単位の行列を使用していると仮定して)。 JAMAは密行列を扱うので、別の表現を探すことができます。 Loloが述べたように、これはオーバーヘッドを大幅に削減します。第2に、LSIは、上位k個の特異ベクトルが計算されることのみを必要とする。 JAMAはすべての特異値を計算しますが、これはあなたの場合には不要です。さらに、k個だけ必要な場合は、薄いSVDを使用してさらに最適化することができます。これは、メモリオーバーヘッドが大幅に少なくなります。大規模なドキュメントコレクションでは、LSI用の完全SVDを計算することはほとんど不可能になるので、規模を拡大するには、最終的にJAMA以外のものに切り替える必要があります。

SVDLIBJは、JavaでシンSVDを実行するための1つの可能性です。 S-Space Packageには、SVDLIBJラッパーとコマンドラインツールが含まれています。また、LSIを完全に書くことを避けたい場合は、LSI/LSAの実装もあります。