简体   繁体   English

C ++中的内存错误(armadillo)

[英]Memory error in c++ (armadillo)

I wanted to solve a kind of ordinary differential equation (master equation) and I wrote the following program in c++ by help of armadillo: 我想求解一种常微分方程(主方程),并在犰狳的帮助下用C ++编写了以下程序:

#include <iostream>
#include <armadillo>
#include <iomanip>

using namespace std;
using namespace arma;


cx_mat tens( cx_mat a1,cx_mat a2,cx_mat a3,cx_mat a4,cx_mat a5,cx_mat 
a6,cx_mat a7,cx_mat a8,cx_mat a9,cx_mat a10,cx_mat a11,cx_mata12,cx_mat a13,cx_mat a14,cx_mat a15,cx_mat a16,cx_mat a17,cx_mat a18,cx_mat a19,cx_mat a20,cx_mat a21)
{return kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(kron(a1,a2),a3),a4),a5),a6),a7),a8),a9),a10),a11),a12),a13),a14),a15),a16),a17),a18),a19),a20),a21);}


cx_mat ii(2,2,fill::eye);// make a 2*2 identify cx_matrix


cx_mat ee = ii.col(0); // extract a column vector

cx_mat gg = ii.col(1);

cx_mat a1 =tens(ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a2 =tens(gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a3 =tens(gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a4 =tens(gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a5 =tens(gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a6 =tens(gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a7 =tens(gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a8 =tens(gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a9 =tens(gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a10=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a11=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a12=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a13=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg,gg);
cx_mat a14=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg,gg);
cx_mat a15=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg,gg);
cx_mat a16=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg,gg);
cx_mat a17=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg,gg);
cx_mat a18=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg,gg);
cx_mat a19=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg,gg);
cx_mat a20=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee,gg);
cx_mat a21=tens(gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,gg,ee);



cx_mat sink=a21*a20.t();


cx_mat H0(cx_mat a){
return a*a.t();}


cx_mat H1(cx_mat a,cx_mat b){
return a*b.t()+b*a.t();}


cx_mat H00=H0(a1)+H0(a2)+H0(a3)+H0(a4)+H0(a5)+H0(a6)+H0(a7);

cx_mat H11=H1(a1,a2)+H1(a1,a3)+H1(a1,a4)+H1(a1,a5)+H1(a1,a6)+H1(a1,a7)+H1(a1,a8)+H1(a1,a9)+H1(a1,a10)+H1(a1,a11)+H1(a1,a12)+H1(a1,a13)+H1(a1,a14)+H1(a1,a15)+H1(a1,a16)+H1(a1,a17)+H1(a1,a18)+H1(a1,a19)+H1(a1,a20);

cx_mat H=H00+H11;//system Hamiltonian


cx_mat rhot(float t,cx_mat y){ 
return complex<double>(0, 1)*(-H*y+y*H)+0.5*(2*sink*y*sink.t()-sink.t()*sink*y-y*sink.t()*sink);}//Master equation



int rk4(cx_mat y,float dt,float tmax)//Runge kutta 4th order
{float t = 0.;cx_mat ydot1, ydot2, ydot3, ydot4;

  while (t < tmax)
  {
  ydot1 = rhot(t, y);
  ydot2 = rhot(t+0.5*dt, y+0.5*dt*ydot1);
  ydot3 = rhot(t+0.5*dt, y+0.5*dt*ydot2);
  ydot4 = rhot(t+dt, y+dt*ydot3);
  cout<<t<< real(a21.t()*y*a21) ;

  y=y+ (dt/6.0)*(ydot1 + 2.0*ydot2 + 2.0*ydot3 + ydot4);
  t=t+ dt;
  }

return 0;
}


int main()
  {
  rk4(a1*a1.t(),0.01,40.);
 return 0;
  }

I run this program by typying the following comment on the Ubuntu terminal: 我通过在Ubuntu终端上键入以下注释来运行该程序:

 g++ -std=c++0x psinkt.cpp -o ./psinkt.out -O3 -march=native -larmadillo

but I encountered to the following memory error: 但是我遇到了以下内存错误:

error: arma::memory::acquire(): out of memory

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

Generally, is there a way to solve such a problem? 通常,有没有办法解决这个问题? if yes, please tell me even the key word ! 如果是,请甚至告诉我关键词! I really need to solve the problem. 我真的需要解决这个问题。

Step 1: Identify where it happens. 步骤1:找出发生的地方。

Compile with 编译

$ g++ -std=c++0x -Wall -O0 -g3 psinkt.cpp -o ./psinkt.out

and debug with 和调试

$ gdb ./psinkt.out
gdb> run

Or use valgrind 或使用valgrind

$ yum install valgrind
# or
$ apt-get install valgrind
$ valgrind --tool=memcheck ./psinkt.out

Step 2: Improve your C++ 步骤2:改善您的C ++

I'd strongly encourage you to visit a book store and skim some C++ books and find a more readable style. 我强烈建议您访问书店并浏览一些C ++书籍,并找到更具可读性的样式。 Your current code is very hard to penetrate and coming from Python to C++ is going to introduce a level of hurt like this - C++ is a language full of stupidly sharp edges and loaded hand cannons; 您当前的代码很难被渗透,从Python到C ++都会给您带来一定程度的伤害-C ++是一种充满愚蠢的锋利边缘和手炮的语言。 it's C++, not you :) 它是C ++,不是你:)

For example, that horrible kron thing you're doing... Rethink what it is you're trying to do, and things like this: 例如,您正在做的可怕的Kron事情...重新考虑您想做的事情,像这样的事情:

cx_mat H11=H1(a1,a2)+H1(a1,a3)+H1(a1,a4)+H1(a1,a5)+H1(a1,a6)+H1(a1,a7)+H1(a1,a8)+H1(a1,a9)+H1(a1,a10)+H1(a1,a11)+H1(a1,a12)+H1(a1,a13)+H1(a1,a14)+H1(a1,a15)+H1(a1,a16)+H1(a1,a17)+H1(a1,a18)+H1(a1,a19)+H1(a1,a20);

Here's the bad news: You're going to have to write more code in C++ and use less direct paths compared to how you write in Python. 这是一个坏消息:与用Python编写的方式相比,您将不得不用C ++编写更多的代码并且使用更少的直接路径。 When you are more familiar with the language, its idioms, etc, the paths seem more obvious and natural, but coming from Python, stuff is often going to seem backwards. 当您对语言,它的惯用语言等更加熟悉时,这些路径似乎更加显而易见和自然,但是来自Python的东西通常会倒退。

You basically have to provide a lot more detail to the system, specificity is the cost of performance. 您基本上必须为系统提供更多细节,特异性就是性能成本。

For example, you might want to consider putting your "a"s into a std::vector so that you can say things like: 例如,您可能需要考虑将“ a”放入std::vector以便您可以说出以下内容:

cx_mat H11;
for (auto it = as.begin() + 1; it != as.end() - 1; ++it) {
    H11 += H1(a1, *it); // (a1,a2) ... (a1, a20)
}

You could refactor your kron nesting like this: 您可以像这样重构您的kron嵌套:

cx_mat tens(const cx_mat& background, size_t posn, const cx_mat& foreground, size_t width)
{
    std::vector<cx_mat*> mats;
    mats.resize(width);
    std::fill(mats.begin(), mats.end(), &background);
    mats[posn] = &foreground;
    cx_mat accum = *mats[0];
    for (size_t i = 1; i < width; ++i) {
        accum = kron(accum, *mats[i]);
    }
    return accum;
}

cx_mat a1 = tens(gg, 0, ee, 21);
cx_mat a2 = tens(gg, 1, ee, 21);
cx_mat a3 = tens(gg, 2, ee, 21);
...

const cx_mat& says to pass the value by reference, I don't know whether cx_mat is a trivial object or whether passing it by value as you are is expensive (pass by value requires a deep copy). const cx_mat&表示要通过引用传递值,我不知道cx_mat是一个琐碎的对象还是因为按值传递它很昂贵(按值传递需要深层复制)。

Or you could write it like this: 或者您可以这样写:

void tens(cx_mat& into, cx_mat& background, size_t posn, cx_mat& foreground, size_t width)
{
    std::vector<cx_mat*> mats;
    mats.resize(width);
    std::fill(mats.begin(), mats.end(), &background);
    mats[posn] = &foreground;
    into = *mats[0];
    for (size_t i = 1; i < width; ++i) {
        accum = kron(accum, *mats[i]);
    }
}

enum { Width = 21 };
std::vector<mat> amats;
amats.reserve(Width);
for (size_t i = 0; i < Width; ++i) {
    tens(amats[i], gg, i, ee, Width);
}

Or you could use C++11 templates: 或者,您可以使用C ++ 11模板:

cx_mat tens(const cx_mat& lhs, const cx_mat& rhs)
{
    return kron(lhs, rhs);
}

template<typename Args...>
cx_mat tens(const cx_mat& lhs, const cx_mat& rhs, Args&&... rest)
{
    return tens(kron(lhs, rhs), std::forward<Args>(rest)...);
}

cx_mat a1 = tens(ee, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg, gg);

But that's my least favorite of the options. 但这是我最不喜欢的选择。 Note: the elipsis (...) are not me leaving stuff out, that's actual C++11 variadic template syntax: see http://ideone.com/VgfmVB 注意:省略号(...)不是我遗漏的东西,这是C ++ 11可变参数模板的实际语法:请参阅http://ideone.com/VgfmVB

I don't know that the above code examples solve your problem or which is preferable in your case, but I'm hoping that between the two I've equipped you to make progress. 我不知道上面的代码示例可以解决您的问题,或者哪种情况更适合您,但我希望在这两者之间,我已经为您提供了帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM