用 C++ 中的内存有效方式用列和替换 (mxm) 矩阵中的对角线值
我有以下大小为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
创建一个大小为 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.