2009-08-07 10 views
0

je la matrice suivante de taille m = 4Remplacement Valeur des Diagonales dans (MXM) Matrice avec sa colonne Somme avec mémoire Way efficace en 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 

Et je veux remplacer la diagonale de cette matrice avec (1 - somme de sa colonne). matrice résultante:

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 

Ainsi, par exemple pour (1,1), nous avons

1 - (0.04565 + 0.04565 + 0.00000) = 0.90870 

Maintenant, la pratique de la taille de m est très grande d'échelle 10^6 à 10^7. Donc, je ne peux pas me permettre de stocker la matrice initiale dans un conteneur.

Existe-t-il une autre manière efficace de mémoire pour le faire?

Le courant est la mise en œuvre que j'ai pour le tailler en vecteur de vecteurs. Il ne peut pas gérer grand m (10^6).

#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; 
     } 

Répondre

4

Créez un vecteur de taille m pour stocker la diagonale. Parcourez ensuite le fichier et ajoutez la ième colonne de chaque ligne à diag [i]. Maintenant, parcourez à nouveau le fichier et affichez chaque ligne, mais remplacez la valeur de l'élément ith sur la ligne it avec diag [i]. De cette façon, il vous suffit de stocker un vecteur de taille m en mémoire.

+0

En outre, en supposant que l'E/S disque sera le goulot d'étranglement, et que le 1PB des données d'entrée est stocké physiquement sur plus d'un volume de disque, une sorte de parallélisation serait dans l'ordre. Le vecteur représentant la diagonale peut facilement être fragmenté, donc cet algorithme est un bon début. –