Пример #1
0
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;
	}
}
Пример #2
0
 int&
 operator()(int r, int c)       { return num_(r, c); }
Пример #3
0
 int
 const& operator()(int r, int c) const { return num_(r, c); }
Пример #4
0
	//=========================//
	//    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();
//		}
		
		
		
	}