用 C++ 中的内存有效方式用列和替换 (mxm) 矩阵中的对角线值

发布于 2024-07-30 05:24:02 字数 2776 浏览 1 评论 0原文

我有以下大小为 m=4 的矩阵

   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

我想替换该矩阵的对角线 与(1 - 其列的总和)。 结果矩阵:

   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

例如,对于 (1,1) 我们有

   1 - (0.04565 + 0.04565 + 0.00000) = 0.90870

现在实际实践中 m 的大小非常大 范围为 10^6 到 10^7。 所以我无法存储初始矩阵 放入容器中。

有没有内存有效的替代方法来做到这一点?

当前是我用于吸收它的实现 转化为向量的向量。 它无法处理大 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;
        }  

I have the following matrix of size m=4

   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

And I want to replace the diagonal of that matrix
with (1 - sum of its column). Resulting matrix:

   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 for example for (1,1) we have

   1 - (0.04565 + 0.04565 + 0.00000) = 0.90870

Now the actual practice the size of m is very large
of scale 10^6 to 10^7. So I can't afford to store the initial matrix
into a container.

Is there any memory efficient alternative way to do it?

The current is the implementation I have for slurping it
into vector of vectors. It cannot handle large 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;
        }  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

像极了他 2024-08-06 05:24:02

创建一个大小为 m 的向量来存储对角线。 然后遍历该文件并将每行的第 i 列添加到 diag[i]。 现在再次遍历该文件并输出每一行,但将第 i 行第 i 个元素的值替换为 diag[i]。 这样你只需要在内存中存储一​​个大小为 m 的向量。

Create a vector of size m to store the diagonal. Then go through the file and add the ith column of each line to diag[i]. Now go through the file again and output each line, but replace the value of the ith element on the ith line with diag[i]. This way you only need to store a vector of size m in memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文