2009-08-07 7 views
0

ich die folgende Matrix der Größe m haben = 4Wert Diagonalenzug Ersetzen in (MXM) Matrix Mit seiner Spalte Summe mit Speicher effizienteste Weg in C++

0.00000 0.09130 0.09130 0.00000 
    0.04565 0.00000 0.00000 0.00000 
    0.04565 0.00000 0.00000 0.00000 
    0.00000 0.00000 0.00000 0.00000 

Und ich die Diagonale dieser Matrix ersetzt werden soll mit (1 - Summe seiner Spalte). Ergebnismatrix:

0.90870 0.09130 0.09130 0.00000 
    0.04565 0.90870 0.00000 0.00000 
    0.04565 0.00000 0.90870 0.00000 
    0.00000 0.00000 0.00000 1.00000 

So zum Beispiel für (1,1) haben wir

1 - (0.04565 + 0.04565 + 0.00000) = 0.90870 

Nun ist die tatsächliche Praxis der Größe m ist sehr groß der Skala 10^6 bis 10^7. Daher kann ich es mir nicht leisten, die Ausgangsmatrix in einem Container zu speichern.

Gibt es eine speichereffiziente alternative Möglichkeit, dies zu tun?

Die aktuelle ist die Implementierung, die ich für schlürfen es in Vektor von Vektoren habe. Es kann nicht mit großen m (10^6) umgehen.

#include <iostream> 
    #include <vector> 
    #include <fstream> 
    #include <sstream> 
    #include <map> 
    using namespace std; 

     // Initialize Matrix Before Slurping 
     vector <vector<double> > Matrix; 
     Matrix.resize(nofRow); 
     for(size_t i = 0; i < nofRow; ++i) 
     { 
      Matrix[i].resize(nofCol); 
     } 



     if (arg_count !=2) { 
     cerr << "expected one argument" << endl; 
     return EXIT_FAILURE; 
    } 

    string line; 
    ifstream myfile (arg_vec[1]); 

    // Slurpint it 
    int count1=0; 
    if (myfile.is_open()) 
    { 

     while (getline(myfile,line)) 
     { 
      stringstream ss(line); 
      double Value; 
      count1++;    

      int count2=0; 
      while (ss >> Value) { 
       count2++; 
       Matrix[count1][count2] = Value; 
      } 


     } 
     myfile.close(); 
    } 
    else { cout << "Unable to open file"; } 


    // Summing up Column; 
     vector <double> ColSum; 
     ColSum.resize(nofCol); 
     for(size_t i = 0; i < nofRow; ++i) 
     { 
      for(size_t j = 0; j < nofCol; ++j) 
      { 
       //std::cout <<"["<<i<<"]"<<"["<<j<<"] = " <<Matrix[i][j]<<std::endl; 
       ColSum[j] += Matrix[i][j]; 
      } 
     } 



     // Printing it 
     for(size_t k = 0; k < nofRow; ++k) 
     { 
      for(size_t l = 0; l < nofCol; ++l) 
      { 
        if (k == l) { 
         double OneMinusSum = 1 - ColSum[k]; 
         //if (OneMinusSum < 0) { OneMinusSum = 1; }; 
        std::cout << OneMinusSum << "\t"; 
        } 
        else { 
         std::cout<< Matrix[k][l] << "\t"; 
        } 
      } 

      std::cout << std::endl; 
     } 

Antwort

4

Erstellen Sie einen Vektor der Größe m, um die Diagonale zu speichern. Dann gehe durch die Datei und füge die i-te Spalte jeder Zeile zu diag [i] hinzu. Durchlaufen Sie die Datei erneut und geben Sie jede Zeile aus, ersetzen Sie jedoch den Wert des i-ten Elements auf der i-ten Zeile durch diag [i]. Auf diese Weise müssen Sie nur einen Vektor der Größe m im Speicher ablegen.

+0

Wenn man annimmt, dass Platten-I/O der Flaschenhals ist und dass die 1PB der Eingangsdaten physikalisch auf mehr als einem Plattenvolumen gespeichert sind, wäre eine Art von Parallelisierung in Ordnung. Der Vektor, der die Diagonale darstellt, kann einfach scharf gemacht werden, so dass dieser Algorithmus hoffentlich ein guter Anfang ist. –

Verwandte Themen