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; } }
//=========================// // 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(); // } }