void luaStore_writeValue(TValue * v, file& f, std::vector<void *>& functions) { uint i; bool found; byte type = ttype(v); f.write(type); switch(type) { case LUA_TNIL: // nil has no data break; case LUA_TBOOLEAN: f.write((byte)val_(v).b); break; case LUA_TLIGHTUSERDATA: // write the pointer f.write(&val_(v).p, sizeof(void*)); break; case LUA_TNUMBER: f.write(num_(v)); break; case LUA_TSTRING: // write the pointer to gc objects case LUA_TTABLE: case LUA_TUSERDATA: case LUA_TTHREAD: // all gc objects will be flushed to disk later f.write(&val_(v).gc, sizeof(void*)); break; case LUA_TLCL: f.write(&val_(v).gc, sizeof(void*)); // this variant is a gc object break; case LUA_TLCF: // c-function // look up the function in the bindings list found = false; for(i = 0;i < functions.size();i++) { if(functions[i] == val_(v).f) { // write the index as a short f.write((ushort)i); found = true; break; } } if(!found) dbgError("unknown light function"); break; default: dbgError("unknown object type %i", type); break; } }
int& operator()(int r, int c) { return num_(r, c); }
int const& operator()(int r, int c) const { return num_(r, c); }
//=========================// // PARTIAL PIVOT ACA // //=========================// // If reqrank=-1 (default value), we use the precision given by epsilon for the stopping criterion; // otherwise, we use the required rank for the stopping criterion (!: at the end the rank could be lower) LowRankMatrix(const SubMatrix& A, const vectInt& ir0, const vectInt& ic0, const Cluster& t, const Cluster& s, int reqrank=-1){ nr = nb_rows(A); nc = nb_cols(A); ir=ir0; ic=ic0; vector<bool> visited_row(nr,false); vector<bool> visited_col(nc,false); Real frob = 0.; Real aux = 0.; Cplx frob_aux=0; //// Choice of the first row (see paragraph 3.4.3 page 151 Bebendorf) Real dist=1e30; int I=0; for (int i =0;i<int(nr/ndofperelt);i++){ Real aux_dist= norm(pts_(t)[tab_(t)[num_(t)[i*ndofperelt]]]-ctr_(t)); if (dist>aux_dist){ dist=aux_dist; I=i*ndofperelt; } } int J=0; int q = 0; if(reqrank == 0){ rank = 0; // approximate with a zero matrix } else if ( (nr+nc)>=(nr*nc) ){ // even rank 1 is not advantageous rank=-5; // just a flag for BuildBlockTree (the block won't be treated as a FarField block) } else{ vectCplx r(nc),c(nr); // Compute the first cross //==================// // Recherche colonne Real rmax = 0.; for(int k=0; k<nc; k++){ r[k] = A(I,k); for(int j=0; j<u.size(); j++){ r[k] += -u[j][I]*v[j][k];} if( abs(r[k])>rmax && !visited_col[k] ){ J=k; rmax=abs(r[k]);} } visited_row[I] = true; //==================// // Recherche ligne if( abs(r[J]) > 1e-15 ){ Cplx gamma = Cplx(1.)/r[J]; Real cmax = 0.; for(int j=0; j<nr; j++){ c[j] = A(j,J); for(int k=0; k<u.size(); k++){ c[j] += -u[k][j]*v[k][J];} c[j] = gamma*c[j]; if( abs(c[j])>cmax && !visited_row[j] ){ I=j; cmax=abs(c[j]);} } visited_col[J] = true; // We accept the cross q++; //====================// // Estimateur d'erreur frob_aux = 0.; aux = abs(dprod(c,c)*dprod(r,r)); // aux: terme quadratiques du developpement du carre' de la norme de Frobenius de la matrice low rank for(int j=0; j<u.size(); j++){ frob_aux += dprod(r,v[j])*dprod(c,u[j]);} // frob_aux: termes croises du developpement du carre' de la norme de Frobenius de la matrice low rank frob += aux + 2*frob_aux.real(); // frob: Frobenius norm of the low rank matrix //==================// // Nouvelle croix u.push_back(c); v.push_back(r); } else{cout << "There is a zero row in the starting submatrix and ACA didn't work" << endl;} // Stopping criterion of slide 26 of Stephanie Chaillat and Rjasanow-Steinbach // (if epsilon>=1, it always stops to rank 1 since frob=aux) while ( ((reqrank > 0) && (q < reqrank) ) || ( (reqrank < 0) && ( sqrt(aux/frob)>epsilon ) ) ) { if (q >= min(nr,nc) ) break; if ( (q+1)*(nr +nc) > (nr*nc) ){ // one rank more is not advantageous if (reqrank <0){ // If we didn't required a rank, i.e. we required a precision with epsilon rank=-5; // a flag for BuildBlockTree to say that the block won't be treated as a FarField block } break; // If we required a rank, we keep the computed ACA approximation (of lower rank) } // Compute another cross //==================// // Recherche colonne rmax = 0.; for(int k=0; k<nc; k++){ r[k] = A(I,k); for(int j=0; j<u.size(); j++){ r[k] += -u[j][I]*v[j][k];} if( abs(r[k])>rmax && !visited_col[k] ){ J=k; rmax=abs(r[k]);} } visited_row[I] = true; //==================// // Recherche ligne if( abs(r[J]) > 1e-15 ){ Cplx gamma = Cplx(1.)/r[J]; Real cmax = 0.; for(int j=0; j<nr; j++){ c[j] = A(j,J); for(int k=0; k<u.size(); k++){ c[j] += -u[k][j]*v[k][J];} c[j] = gamma*c[j]; if( abs(c[j])>cmax && !visited_row[j] ){ I=j; cmax=abs(c[j]);} } visited_col[J] = true; aux = abs(dprod(c,c)*dprod(r,r)); // aux: terme quadratiques du developpement du carre' de la norme de Frobenius de la matrice low rank } else{ cout << "ACA's loop terminated" << endl; break; } // terminate algorithm with exact rank q (not full-rank submatrix) // We accept the cross q++; //====================// // Estimateur d'erreur frob_aux = 0.; for(int j=0; j<u.size(); j++){ frob_aux += dprod(r,v[j])*dprod(c,u[j]);} // frob_aux: termes croises du developpement du carre' de la norme de Frobenius de la matrice low rank frob += aux + 2*frob_aux.real(); // frob: Frobenius norm of the low rank matrix //==================// // Nouvelle croix u.push_back(c); v.push_back(r); } rank = u.size(); } // Use this for Bebendorf stopping criterion (3.58) pag 141 (not very flexible): // if(reqrank == 0) // rank = 0; // approximate with a zero matrix // else if ( (nr+nc)>=(nr*nc) ){ // even rank 1 is not advantageous // rank=-5; // just a flag for BuildBlockTree (the block won't be treated as a FarField block) // } else{ // vectCplx r(nc),c(nr); // // // Compute the first cross // // (don't modify the code because we want to really use the Bebendorf stopping criterion (3.58), // // i.e. we don't want to accept the new cross if it is not satisfied because otherwise the approximation would be more precise than desired) // //==================// // // Recherche colonne // Real rmax = 0.; // for(int k=0; k<nc; k++){ // r[k] = A(I,k); // for(int j=0; j<u.size(); j++){ // r[k] += -u[j][I]*v[j][k];} // if( abs(r[k])>rmax && !visited_col[k] ){ // J=k; rmax=abs(r[k]);} // } // visited_row[I] = true; // //==================// // // Recherche ligne // if( abs(r[J]) > 1e-15 ){ // Cplx gamma = Cplx(1.)/r[J]; // Real cmax = 0.; // for(int j=0; j<nr; j++){ // c[j] = A(j,J); // for(int k=0; k<u.size(); k++){ // c[j] += -u[k][j]*v[k][J];} // c[j] = gamma*c[j]; // if( abs(c[j])>cmax && !visited_row[j] ){ // I=j; cmax=abs(c[j]);} // } // visited_col[J] = true; // // aux = abs(dprod(c,c)*dprod(r,r)); // } // else{cout << "There is a zero row in the starting submatrix and ACA didn't work" << endl;} // // // (see Bebendorf stopping criterion (3.58) pag 141) // while ( (q == 0) || // ( (reqrank > 0) && (q < reqrank) ) || // ( (reqrank < 0) && ( sqrt(aux/frob)>Parametres.epsilon * (1 - Parametres.eta)/(1 + Parametres.epsilon) ) ) ) { // // // We accept the cross // q++; // //====================// // // Estimateur d'erreur // frob_aux = 0.; // //aux = abs(dprod(c,c)*dprod(r,r)); // (already computed to evaluate the test) // // aux: terme quadratiques du developpement du carre' de la norme de Frobenius de la matrice low rank // for(int j=0; j<u.size(); j++){ // frob_aux += dprod(r,v[j])*dprod(c,u[j]);} // // frob_aux: termes croises du developpement du carre' de la norme de Frobenius de la matrice low rank // frob += aux + 2*frob_aux.real(); // frob: Frobenius norm of the low rank matrix // //==================// // // Nouvelle croix // u.push_back(c); // v.push_back(r); // // if (q >= min(nr,nc) ) // break; // if ( (q+1)*(nr +nc) > (nr*nc) ){ // one rank more is not advantageous // if (reqrank <0){ // If we didn't required a rank, i.e. we required a precision with epsilon // rank=-5; // a flag for BuildBlockTree to say that the block won't be treated as a FarField block // } // break; // If we required a rank, we keep the computed ACA approximation (of lower rank) // } // // Compute another cross // //==================// // // Recherche colonne // rmax = 0.; // for(int k=0; k<nc; k++){ // r[k] = A(I,k); // for(int j=0; j<u.size(); j++){ // r[k] += -u[j][I]*v[j][k];} // if( abs(r[k])>rmax && !visited_col[k] ){ // J=k; rmax=abs(r[k]);} // } // visited_row[I] = true; // //==================// // // Recherche ligne // if( abs(r[J]) > 1e-15 ){ // Cplx gamma = Cplx(1.)/r[J]; // Real cmax = 0.; // for(int j=0; j<nr; j++){ // c[j] = A(j,J); // for(int k=0; k<u.size(); k++){ // c[j] += -u[k][j]*v[k][J];} // c[j] = gamma*c[j]; // if( abs(c[j])>cmax && !visited_row[j] ){ // I=j; cmax=abs(c[j]);} // } // visited_col[J] = true; // // aux = abs(dprod(c,c)*dprod(r,r)); // } // else{ cout << "ACA's loop terminated" << endl; break; } // terminate algorithm with exact rank q (not full-rank submatrix) // } // // rank = u.size(); // } }