2013-07-21 13 views
5

3次元でルックアップテーブルを使用する必要があります。テーブル自体に73x73x73(389017)の二重値があります。GHCは大きなルックアップテーブルを扱うことができません

module Hammer.Texture.Table3D where 

import qualified Data.Vector   as V 
import qualified Data.Vector.Unboxed as U 

import   Data.Vector.Unboxed (Vector) 

table3D :: V.Vector (V.Vector (Vector Double)) 
table3D = V.fromList [table0, table1, ... table72] 

table0 = V.fromList $ map U.fromList [ 
    [1.973921e+01, 0.000000e+00, ... 0.000000e+00], 
    ..... 
    [1.973921e+01, 0.000000e+00, ... 0.000000e+00]] 
..... 
table72 = V.fromList $ map U.fromList [ 
    [1.973921e+01, 0.000000e+00, ... 0.000000e+00], 
    ..... 
    [1.973921e+01, 0.000000e+00, ... 0.000000e+00]] 

問題はGHCベクタダブルまたは[ダブル]のこのサイズを扱うことができないということです、GHCのコンパイルに時間がかかる(〜2分)まで、最終的には、メモリが吹くまで。非常に大きなString([Char])でうまく動作するので、GHCやいくつかのバグでメモリリークが発生しているようです。

GHCを使用して "大きな"ルックアップテーブル(ダブルタイプ)を作成するためのソリューションはありますか?

+1

は、あなたの代わりに '' Data.Array'またはData.Array.Repa'のような配列を使用してみましたか?それは、あなたがベクトルではなく固定サイズのコンテナを必要としているようです。 –

+1

これは、10 MBのソースファイルのように、テキスト形式のテーブル全体にありますか?なぜあなたはこのようにしますか?このような大きな 'Vector'を実行時に生成するのは問題ではなく、バイナリファイルからもっと効率的に読み込むことができます。ソースに入れるだけで、IOから簡単に遠ざけることができます。 – leftaroundabout

+1

文字列で正常に実行されていれば...(ダブルではなく)ハードコード文字列を使用しないのはなぜですか? (その後、 'read'はもちろんですが)、醜いかもしれませんが、うまくいくかもしれません... – josejuan

答えて

8

私は2つの可能性を考えることができます:あなたは、ルックアップテーブルが最初ではなく、使用されたときにこれが起こるしたい場合は、おそらくunsafeInterleaveIOを使用して(ファイルへのベクトルをシリアル化し、プログラムの起動時にそれらをデシリアライズ

  1. プログラムが起動すると)。
  2. 擬似コードが示唆するようにルックアップテーブルが実際にはまばらである場合は、疎なデータ構造を使用することを検討してください。 Data.Map、あるいは単純な関数でさえあります。必要に応じて、この疎なデータ構造を使用してベクトルを生成することができます(実行時にも)。
関連する問題