Memory error in c++ (armadillo) -


i wanted solve kind of ordinary differential equation (master equation) , wrote following program in c++ of armadillo:

#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 2*2 identify cx_matrix   cx_mat ee = ii.col(0); // extract 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 program typying following comment on ubuntu terminal:

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

but encountered following memory error:

error: arma::memory::acquire(): out of memory  terminate called after throwing instance of 'std::bad_alloc'   what():  std::bad_alloc aborted (core dumped) 

generally, there way solve such problem? if yes, please tell me key word ! need solve problem.

step 1: identify happens.

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

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

step 2: improve c++

i'd encourage visit book store , skim c++ books , find more readable style. current code hard penetrate , coming python c++ going introduce level of hurt - c++ language full of stupidly sharp edges , loaded hand cannons; it's c++, not :)

for example, horrible kron thing you're doing... rethink you're trying do, , things this:

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 bad news: you're going have write more code in c++ , use less direct paths compared how write in python. when more familiar language, idioms, etc, paths seem more obvious , natural, coming python, stuff going seem backwards.

you have provide lot more detail system, specificity cost of performance.

for example, might want consider putting "a"s std::vector can things like:

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

you refactor kron nesting this:

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];     (size_t = 1; < 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 pass value reference, don't know whether cx_mat trivial object or whether passing value expensive (pass value requires deep copy).

or write 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;     = *mats[0];     (size_t = 1; < width; ++i) {         accum = kron(accum, *mats[i]);     } }  enum { width = 21 }; std::vector<mat> amats; amats.reserve(width); (size_t = 0; < width; ++i) {     tens(amats[i], gg, i, ee, width); } 

or use c++11 templates:

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 least favorite of options. note: elipsis (...) not me leaving stuff out, that's actual c++11 variadic template syntax: see http://ideone.com/vgfmvb

i don't know above code examples solve problem or preferable in case, i'm hoping between 2 i've equipped make progress.


Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -