Auffüllen und Speichern eines sehr großen Arrays in Mathematica

  • Ich verwende Mathematica 8, um ein sehr großes mehrdimensionales Array von Fließkommazahlen zu erzeugen und dann in einer Datei zu speichern. Typische Array-Größen sind 10000 x 50 x 15 x 40, so dass sich eine Datei mit 3 bis 4 GB ergibt. Die Einträge des Arrays werden rekursiv generiert, nachdem einige Startwerte berechnet wurden. Nach Abschluss der Berechnungen (etwa 12 Stunden) scheint Mathematica für 8 oder mehr Stunden während des Schreibens des Arrays zu hängen. Manchmal endet das Programm nicht innerhalb eines Zeitlimits von 24 Stunden (vom System I vorgegeben) verwende), und es wird keine Datei erzeugt (nicht einmal eine unvollständige). Ich frage mich: Welche Strategien gibt es, um mit diesen großen Arrays in Mathematica umzugehen und sicherzustellen, dass das Schreiben einer Datei erfolgreich ausgeführt wird?

    Hintergrund: Das Array ist im Speicher belegt und dann mit einigen Anfangswerten und einer Rekursionsrelation gefüllt

     prec = 50;
    GenerateMyArray[iMax_,jMax_,kMax_,lMax_] := Module[{myArray},
      myArray = ConstantArray[SetPrecision[0.0, prec], {iMax, jMax, kMax, lMax}];
    
      (* do something to populate initial entries *)
      ...
    
      (* populate the rest with a recursion relation *)
      Do[
        myArray[[i,j,k,l]] = Evaluate[myRecursionRelation],
        {i,1,iMax},
        {j,1,jMax},
        {k,1,kMax},
        {l,1,lMax}
      ];
      myArray
    ];
     

    (Die Berechnungen müssen jedoch mit hoher Genauigkeit ausgeführt werden das Array wird schließlich mit niedrigerer Genauigkeit gespeichert). Schließlich schreibe ich die Einträge in eine Datei.

     mp[x_] := NumberForm[SetPrecision[x, 16], 16, ExponentFunction -> (Null &)];    
    
    myArray = GenerateMyArray[10000, 50, 15, 40];
    w = OpenWrite[myFileName];
    writeHeader[w];
    Do[WriteString[w, mp[x], "\n"],
        {irow,myArray},
        {jrow,irow},
        {krow,jrow},
        {x,krow}];
    Close[w];
     

    Mein Verständnis, wann Dinge nach Wert übergeben werden und wann Sie werden in Mathematica als Referenz übergeben und sind ziemlich arm. Vielleicht werden große Datenmengen unnötig kopiert? Ich würde mich freuen, wenn Sie uns helfen würden, diesen Prozess effizienter und robuster zu gestalten.

    Zusätzlicher Hinweis: Die Ausgabe wird von einem Nicht-Mathematica-Programm gelesen. Die Verwendung von .mx-Dateien ist daher keine Option.

    14 May 2012
    Adam LassekEspen
1 answer
  • Als Alternative zu all den wahnsinnig klugen Antworten ist hier ein dummer Trick, der das Schreiben um 20% beschleunigt:

     Do[WriteString[w, StringJoin @@ ({ToString[mp[#]], "\n"} & /@ krow)],
        {irow,myArray},
        {jrow,irow},
        {krow,jrow}];
     

    Anstatt jedes Element einzeln zu schreiben, wird eine Zeichenfolge aus der tiefsten Zeile erstellt und dann auf einmal geschrieben.

    15 May 2012
    ThiefMaster