#include "sopnamsp.h" #include "FSAppIrrSmpl.h" FSApproximationIrregularSampling::FSApproximationIrregularSampling() : fftIntfPtr_(NULL) {;} FSApproximationIrregularSampling::FSApproximationIrregularSampling(TVector& sampling, double offset, double range) { initFFT(); makeSamplingVector(sampling, offset, range); M_ = 0; } FSApproximationIrregularSampling::~FSApproximationIrregularSampling() {if (fftIntfPtr_!=NULL) delete fftIntfPtr_;} void FSApproximationIrregularSampling::makeRHS(TVector >& coefSolution) { int k; if (exponFourier_.Size() == 0) calculeExponentiellesFourier(); coefSolution.ReSize(2*M_+1); coefSolution = complex(0.,0.); int nbEchantillons = samplingValues_.Size(); // initialisation d'un tableau de travail pour calcul des termes // du second membre par recurrence TVector > travail(nbEchantillons); for (k=0; k < nbEchantillons; k++) { travail(k) = poids_(k)*signal_(k); coefSolution(M_) += travail(k); } // recurrence for (k=1; k<=M_; k++) { int j; for (j=0; j < nbEchantillons; j++) { travail(j) *= exponFourier_(j); coefSolution(M_+k) += travail(j); } coefSolution(M_-k) = conj(coefSolution(M_+k)); } } void FSApproximationIrregularSampling::makeToeplitzMatrix(int M) { int j,k; M_ = M; int nbEchantillons = samplingValues_.Size(); // matrice de Toeplitz if (exponFourier_.Size() == 0) calculeExponentiellesFourier(); TVector > gamma(2*M_+1); gamma = complex(0.,0.); // initialisation d'un tableau de travail pour calcul des termes // de la matrice par recurrence TVector > travail(nbEchantillons); travail = poids_; for (j=0; j& signal) { int k; if (delta_ <= 1./(2.*M) ) { cout << " FSApproximationIrregularSampling : BON ECHANTILLONNAGE " << endl; } else { cout << " FSApproximationIrregularSampling : ATTENTION : SIGNAL SOUS-ECHANTILLONNE " << endl; cout << " deltaMax (normalise) = " << delta_ << " devrait etre inferieur a " << 1./(2.*M) << endl; cout << " ecart max intervient entre echantillon no " << nokdelta_ << " et le suivant, abscisse= " << samplingValues_(nokdelta_)*samplingRange_+samplingOffset_ << endl; } // PrtTim(" avant toeplitz " ); if ( M != M_ ) makeToeplitzMatrix(M); // PrtTim(" fin toeplitz " ); makeSignalVector(signal); // PrtTim(" fin fabrication signal " ); // second membre TVector > coefSolution; makeRHS(coefSolution); int j; // PrtTim(" fin fabrication second membre " ); int niter = tptz_.gradientToeplitz(coefSolution); // int niter = tptz_.gradientToeplitzPreconTChang(coefSolution); cout << " FSApproximationIrregularSampling::approximateSignal : converged in " << niter << " iterations " << endl; coefFourier_.ReSize(M_+1); coefFourier_ = coefSolution(Range(M_, 2*M_)); } // la periode normalisee 1 est divisee en nbInterv intervalles // les valeurs de la solution sont donnes en 0, 1/n, ..... (n-1)/n // le calcul est beaucoup plus rapide si nbInterv est pair (FFT) void FSApproximationIrregularSampling::restaureRegularlySampledSignal(int nbInterv, TVector& solution) const { cout << " c'est celui que je corrige " << endl; int k; if (nbInterv < 2*M_+1) { solution.ReSize(nbInterv); double delta = 1./nbInterv; for (k=0; k > TFf(nbInterv); TVector > bidon(nbInterv); TFf = complex(0.,0.); TFf(Range(0,M_)) = coefFourier_; for ( k=1; k<= M_; k++) { TFf(nbInterv-k) = conj(coefFourier_(k)); } fftIntfPtr_-> FFTBackward(TFf, bidon); cout << " taille de bidon "<< bidon.Size() << endl; solution.ReSize(nbInterv); for (k=0; k< nbInterv; k++) solution(k) = bidon(k).real(); } reshapeSignalInUsersFrame(solution); } void FSApproximationIrregularSampling::computeSignalOnASampling(const TVector& abscisses, TVector& solution ) const { int k; int n= abscisses.Size(); if (n<=0) { cout << " restaurationEnPoints: vecteurs de points vide " << endl; return; } TVector abscissesLocales; abscissesLocales = abscisses; matchToSamplingReference(abscissesLocales); solution.ReSize(n); for (k=0; k& sv) const { int k; int n = samplingValues_.Size(); sv.ReSize(n); for (k=0; k& coef) const { int j; coef.ReSize(2*M_+1); coef(0) = coefFourier_(0).real(); for (j=1; j& sampling) const { int k; int compteur = sampling.Size(); double fac = 1./samplingRange_; for (k=0; k1. ) { cout << " matchToSamplingReference: points hors [0.,1.] " << endl; cout << " " << sampling(0) << " " << sampling(compteur-1) << endl; } } // exprime les valeurs d'echantillonnage entre 0 et 1 void FSApproximationIrregularSampling::resizeSamplingIn_0_1(double offset, double range) { int k; int compteur = samplingValues_.Size(); samplingOffset_ = offset; samplingRange_ = range; double fac = 1./samplingRange_; for (k=0; k delta_ ) { delta_ = diff; nokdelta_ = k; } } // calcul des poids (pour tenir compte de l'irregularite de // l'echantillonnage) poids_.ReSize(nbEchantillons); poids_(0) = 0.5*(samplingValues_(1)-samplingValues_(nbEchantillons-1) + 1.); for (k=1; k< nbEchantillons-1; k++) { poids_(k) = 0.5*(samplingValues_(k+1)-samplingValues_(k-1)); } poids_(nbEchantillons-1) = 0.5*(samplingValues_(0) +1 - samplingValues_(nbEchantillons-2)); } void FSApproximationIrregularSampling::NormSignal() { int k; int nbEchantillons = samplingValues_.Size(); normeSignal_=0; for (k=0; k< nbEchantillons; k++) { double s = signal_(k); normeSignal_ += s*s*poids_(k); } normeSignal_=sqrt(normeSignal_); double fac = 1./normeSignal_; signal_ *= fac; } void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(const TVector& abscisses, TVector& resultat) const { if (resultat.Size() <= 0) { cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl; } resultat *= normeSignal_; } void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(TVector& resultat) const { if (resultat.Size() <= 0) { cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl; } resultat *= normeSignal_; } void FSApproximationIrregularSampling::makeSamplingVector(const TVector& sampling, double offset, double range) { samplingValues_.ReSize(sampling.Size()); samplingValues_ = sampling; resizeSamplingIn_0_1(offset, range); computeWeights(); } void FSApproximationIrregularSampling::makeSignalVector(const TVector& signal) { int n = samplingValues_.Size(); if (n != signal.Size() ) { cout << " echantillonnage et signal n'ont pas les memes dimensions " << endl; } signal_ = signal; NormSignal(); } void FSApproximationIrregularSampling::restaureSignal(TVector& solution) const { int k; int n= samplingValues_.Size(); if (n<=0) { cout << " restaurationEnPoints: vecteurs de points vide " << endl; return; } solution.ReSize(n); for (k=0; k