void SpectrogramComponent::processWindow()
{
  //Calculate spectrogram, fftshift and accumulate
  spgram_push(sp_, &window_[0], windowLength_x);
  spgram_execute(sp_, &spec_[0]);
  for(int i=0;i<nFft_x;i++)
  {
    Cplx c = spec_[(i+nFft_x/2)%nFft_x];
    psd_[i] += real(c*conj(c));
  }

  //Clear containers
  CplxVec temp = window_;
  window_.assign(temp.begin()+delay_x,temp.end());
  spec_.assign(nFft_x, Cplx(0,0));

  //We've accumulated enough windows, normalize, convert to dB and output
  if(++n_ >= nWindows_x)
  {
    FloatVecIt it = psd_.begin();
    for(;it!=psd_.end();++it)
      *it = (10*log10(*it/nWindows_x));

    outputPsd();
    psd_.assign(nFft_x, 0.0);
    n_ = 0;
  }
}
Example #2
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();
//		}
		
		
		
	}