在使用矩阵进行计算时擦除 C++ 2d 向量行

Posted

技术标签:

【中文标题】在使用矩阵进行计算时擦除 C++ 2d 向量行【英文标题】:Erase C++ 2d vector row while doing calculations with the matrix 【发布时间】:2017-04-28 01:39:01 【问题描述】:

我正在尝试模拟一组神经元的平均行为。这意味着我需要对包含数十亿个元素的矩阵进行计算(steps~106neurons~10 4)。

为了避免吃掉我的整个 RAM(并死去尝试),我决定在完成计算后立即从矩阵中删除行。我对 C++ 没有太多经验,但我的理解是 v.erase( v.begin()-i+1); 应该允许我这样做。

// Membrane potential matrix using st::vector
vector<vector<double>> v;
v.resize(steps + 1, vector<double>(neurons));
// Initialise v
for (size_t n = 0; n < neurons; n++) 
    v[0][n] = v0;


double v_avg[steps + 1] = v0;

// Loop
for (size_t i = 1; i < steps + 1; i++) 
    for (size_t n = 0; n < neurons; n++) 
        if(v[i-1][n] >= vp) 
            v[i][n] = -vp;
        
        else 
            v[i][n] = v[i-1][n] + h * ( pow(v[i-1][n], 2) + I[i] + eta[n] );
        
        v_avg[i] += v[i][n]; // Sum of membrane potentials
    
    cout << "step " << i << "/" << steps << " done\n";
    v.erase( v.begin()-i+1); // Erase row v[i-1]
    v_avg[i] = v_avg[i]/neurons; // Mean membrane potential

v.erase( v.begin()+steps+1 ); // Erase last row

我不确定为什么在 steps/2 步骤之后会出现分段错误(我正在使用较小的 steps 值进行测试):

...    
step 10/20 done
[1]    1791 segmentation fault (core dumped)  ./qif_solve_vect

更新:

感谢@1201ProgramAlarm 我明白了我的问题所在。我的问题是:

    如何以从一开始就没有分配的方式使用矩阵。 如何在保留索引的同时释放/释放行(与 v.erase( v.begin()) 不同)。这是必不可少的,因为稍后我将在每个神经元产生尖峰时为它们实现不同的不应时间 (v[i][n] = -vp;)。

【问题讨论】:

【参考方案1】:

在您的erase 语句中,您从v.begin() 中减去,这将导致无效的迭代器,因为它将指向向量开始之前。你的意思可能是v.erase( v.begin() + i - 1);

但是,由于您已经分配了完整的矩阵,因此像这样擦除并不能节省任何空间。擦除会将所有剩余元素向下移动一个元素,并且您对下一个循环的索引将是错误的(因为您想一直使用v[0])。

【讨论】:

哦,我明白了。那么,正确的做法是什么? (见我的更新)。 @AlfredoHernández 您可以使用v[i].clear() 而不是erase。这将在保持索引不变的同时摆脱该行。您最初的 v.resize 应该使用空向量,并且您的循环需要在开始使用它之前填充每一行。 我不太清楚如何使用空向量调整v 的大小以及如何填充每一行(我猜是使用push_back)。你能帮我写代码吗?很抱歉打扰您。

以上是关于在使用矩阵进行计算时擦除 C++ 2d 向量行的主要内容,如果未能解决你的问题,请参考以下文章

在 2D 向量上执行单行算术以找到简化的行形式 C++

将矩阵加载到 2D 向量 C++

迭代 std::list 时擦除

Eigen:按行计算矩阵的范数,比在向量上迭代计算它们要慢

标准向量性能/替代

Vue3:如何避免 Vitejs 在挂载应用程序时擦除/替换所有 DOM 内容?