source: Sophya/trunk/SophyaLib/NTools/FSAppIrrSmpl.cc@ 1962

Last change on this file since 1962 was 1962, checked in by lemeur, 23 years ago

changement fft reelle en complexe, pour nombre pair d'achantillons

File size: 9.2 KB
Line 
1#include "FSAppIrrSmpl.h"
2
3
4FSApproximationIrregularSampling::FSApproximationIrregularSampling() : fftIntfPtr_(NULL) {;}
5
6FSApproximationIrregularSampling::FSApproximationIrregularSampling(TVector<double>& sampling, double offset, double range)
7 {
8 initFFT();
9 makeSamplingVector(sampling, offset, range);
10 M_ = 0;
11 }
12
13
14FSApproximationIrregularSampling::~FSApproximationIrregularSampling()
15{if (fftIntfPtr_!=NULL) delete fftIntfPtr_;}
16
17void FSApproximationIrregularSampling::makeRHS(TVector<complex<double> >& coefSolution)
18{
19 int k;
20 if (exponFourier_.Size() == 0) calculeExponentiellesFourier();
21 coefSolution.ReSize(2*M_+1);
22 coefSolution = complex<double>(0.,0.);
23 int nbEchantillons = samplingValues_.Size();
24
25 // initialisation d'un tableau de travail pour calcul des termes
26 // du second membre par recurrence
27 TVector<complex<double> > travail(nbEchantillons);
28 for (k=0; k < nbEchantillons; k++)
29 {
30 travail(k) = poids_(k)*signal_(k);
31 coefSolution(M_) += travail(k);
32 }
33
34 // recurrence
35 for (k=1; k<=M_; k++)
36 {
37 int j;
38 for (j=0; j < nbEchantillons; j++)
39 {
40 travail(j) *= exponFourier_(j);
41 coefSolution(M_+k) += travail(j);
42 }
43 coefSolution(M_-k) = conj(coefSolution(M_+k));
44 }
45}
46
47void FSApproximationIrregularSampling::makeToeplitzMatrix(int M)
48{
49 int j,k;
50 M_ = M;
51 int nbEchantillons = samplingValues_.Size();
52 // matrice de Toeplitz
53 if (exponFourier_.Size() == 0) calculeExponentiellesFourier();
54
55 TVector<complex<double> > gamma(2*M_+1);
56 gamma = complex<double>(0.,0.);
57 // initialisation d'un tableau de travail pour calcul des termes
58 // de la matrice par recurrence
59 TVector<complex<double> > travail(nbEchantillons);
60 travail = poids_;
61
62 for (j=0; j<nbEchantillons; j++) gamma(0) += travail(j);
63
64 // recurrence
65 for (k=1; k<=2*M_; k++)
66 {
67
68 for (j=0; j<nbEchantillons; j++)
69 {
70 travail(j) *= exponFourier_(j);
71 gamma(k) += travail(j);
72 }
73
74 }
75
76 tptz_.setMatrix(gamma);
77}
78void FSApproximationIrregularSampling::approximateSignal(int M, const TVector<double>& signal)
79{
80 int k;
81 if (delta_ <= 1./(2.*M) )
82 {
83 cout << " FSApproximationIrregularSampling : BON ECHANTILLONNAGE " << endl;
84 }
85 else
86 {
87 cout << " FSApproximationIrregularSampling : ATTENTION : SIGNAL SOUS-ECHANTILLONNE " << endl;
88 cout << " deltaMax (normalise) = " << delta_ << " devrait etre inferieur a " << 1./(2.*M) << endl;
89 cout << " ecart max intervient entre echantillon no " << nokdelta_ << " et le suivant, abscisse= " << samplingValues_(nokdelta_)*samplingRange_+samplingOffset_ << endl;
90
91 }
92 // PrtTim(" avant toeplitz " );
93
94 if ( M != M_ ) makeToeplitzMatrix(M);
95
96 // PrtTim(" fin toeplitz " );
97
98
99 makeSignalVector(signal);
100 // PrtTim(" fin fabrication signal " );
101
102 // second membre
103
104 TVector<complex<double> > coefSolution;
105 makeRHS(coefSolution);
106 int j;
107 // PrtTim(" fin fabrication second membre " );
108
109 int niter = tptz_.gradientToeplitz(coefSolution);
110 // int niter = tptz_.gradientToeplitzPreconTChang(coefSolution);
111 cout << " FSApproximationIrregularSampling::approximateSignal : converged in " << niter << " iterations " << endl;
112 coefFourier_.ReSize(M_+1);
113 coefFourier_ = coefSolution(Range(M_, 2*M_));
114}
115
116// la periode normalisee 1 est divisee en nbInterv intervalles
117// les valeurs de la solution sont donnes en 0, 1/n, ..... (n-1)/n
118// le calcul est beaucoup plus rapide si nbInterv est pair (FFT)
119void FSApproximationIrregularSampling::restaureRegularlySampledSignal(int nbInterv, TVector<double>& solution) const
120{
121 cout << " c'est celui que je corrige " << endl;
122 int k;
123 if (nbInterv < 2*M_+1)
124 {
125 solution.ReSize(nbInterv);
126 double delta = 1./nbInterv;
127 for (k=0; k<nbInterv; k++)
128 {
129 double u = k*delta;
130 solution(k) = valeursSerie(u);
131 }
132 }
133 else
134 {
135 TVector<complex<double> > TFf(nbInterv);
136 TVector<complex<double> > bidon(nbInterv);
137 TFf = complex<double>(0.,0.);
138 TFf(Range(0,M_)) = coefFourier_;
139 for ( k=1; k<= M_; k++)
140 {
141 TFf(nbInterv-k) = conj(coefFourier_(k));
142 }
143 fftIntfPtr_-> FFTBackward(TFf, bidon);
144 cout << " taille de bidon "<< bidon.Size() << endl;
145 solution.ReSize(nbInterv);
146 for (k=0; k< nbInterv; k++) solution(k) = bidon(k).real();
147 }
148 reshapeSignalInUsersFrame(solution);
149}
150
151void FSApproximationIrregularSampling::computeSignalOnASampling(const TVector<double>& abscisses, TVector<double>& solution ) const
152{
153 int k;
154 int n= abscisses.Size();
155 if (n<=0)
156 {
157 cout << " restaurationEnPoints: vecteurs de points vide " << endl;
158 return;
159 }
160 TVector<double> abscissesLocales;
161 abscissesLocales = abscisses;
162 matchToSamplingReference(abscissesLocales);
163 solution.ReSize(n);
164 for (k=0; k<n; k++)
165 {
166 double u = abscissesLocales(k);
167 solution(k) = valeursSerie(u);
168 }
169 reshapeSignalInUsersFrame(abscisses, solution);
170
171}
172
173double FSApproximationIrregularSampling::estimationConditionnement() const
174{
175 double deuxDeltaM = 2.*delta_*M_;
176 double cond = (1.+deuxDeltaM)/(1.-deuxDeltaM);
177 cond *= cond;
178 return cond;
179}
180
181void FSApproximationIrregularSampling::samplingValues(TVector<double>& sv) const
182{
183 int k;
184 int n = samplingValues_.Size();
185 sv.ReSize(n);
186 for (k=0; k<n;k++)
187 {
188 sv(k) = samplingOffset_+samplingRange_*samplingValues_(k);
189 }
190
191}
192
193// terme constant, puis cos, sin, cos, sin......
194void FSApproximationIrregularSampling::coeffCosSin(TVector<double>& coef) const
195{
196 int j;
197 coef.ReSize(2*M_+1);
198 coef(0) = coefFourier_(0).real();
199 for (j=1; j<M_; j++)
200 {
201 double aj = 2.*coefFourier_(j).real();
202 double bj = -2.*coefFourier_(j).imag();
203 coef(2*(j-1)+1) = aj;
204 coef(2*(j-1)+2) = bj;
205 }
206 coef *= normeSignal_;
207}
208
209// exprime les valeurs d'abscisses, selon la reference locale
210void FSApproximationIrregularSampling::matchToSamplingReference(TVector<double>& sampling) const
211
212{
213 int k;
214 int compteur = sampling.Size();
215 double fac = 1./samplingRange_;
216 for (k=0; k<compteur; k++)
217 {
218 sampling(k) = (sampling(k)-samplingOffset_)*fac;
219
220 }
221 if ( sampling(0) <0. || sampling(compteur-1) >1. )
222 {
223 cout << " matchToSamplingReference: points hors [0.,1.] " << endl;
224 cout << " " << sampling(0) << " " << sampling(compteur-1) << endl;
225 }
226}
227
228// exprime les valeurs d'echantillonnage entre 0 et 1
229void FSApproximationIrregularSampling::resizeSamplingIn_0_1(double offset, double range)
230{
231 int k;
232 int compteur = samplingValues_.Size();
233 samplingOffset_ = offset;
234 samplingRange_ = range;
235 double fac = 1./samplingRange_;
236 for (k=0; k<compteur ;k++)
237 {
238 samplingValues_(k) = (samplingValues_(k)-samplingOffset_)*fac;
239 }
240}
241
242void FSApproximationIrregularSampling::computeWeights()
243{
244 int k;
245 int nbEchantillons = samplingValues_.Size();
246 nokdelta_ = 0;
247
248 // calcul de l'ecart maximum entre deux temps d'echantillonnage consecutifs
249 delta_ = samplingValues_(0)-samplingValues_(nbEchantillons-1)+1;
250 for (k=0; k< nbEchantillons-1; k++)
251 {
252 double diff = samplingValues_(k+1)-samplingValues_(k);
253 if ( diff > delta_ )
254 {
255 delta_ = diff;
256 nokdelta_ = k;
257 }
258 }
259 // calcul des poids (pour tenir compte de l'irregularite de
260 // l'echantillonnage)
261 poids_.ReSize(nbEchantillons);
262 poids_(0) = 0.5*(samplingValues_(1)-samplingValues_(nbEchantillons-1) + 1.);
263 for (k=1; k< nbEchantillons-1; k++)
264 {
265 poids_(k) = 0.5*(samplingValues_(k+1)-samplingValues_(k-1));
266 }
267 poids_(nbEchantillons-1) = 0.5*(samplingValues_(0) +1 - samplingValues_(nbEchantillons-2));
268
269}
270void FSApproximationIrregularSampling::NormSignal()
271{
272 int k;
273 int nbEchantillons = samplingValues_.Size();
274 normeSignal_=0;
275 for (k=0; k< nbEchantillons; k++)
276 {
277 double s = signal_(k);
278 normeSignal_ += s*s*poids_(k);
279 }
280 normeSignal_=sqrt(normeSignal_);
281 double fac = 1./normeSignal_;
282 signal_ *= fac;
283}
284
285
286
287void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(const TVector<double>& abscisses, TVector<double>& resultat) const
288{
289 if (resultat.Size() <= 0)
290 {
291 cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
292 }
293 resultat *= normeSignal_;
294}
295
296void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(TVector<double>& resultat) const
297{
298 if (resultat.Size() <= 0)
299 {
300 cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
301 }
302 resultat *= normeSignal_;
303}
304
305
306void FSApproximationIrregularSampling::makeSamplingVector(const TVector<double>& sampling, double offset, double range)
307{
308 samplingValues_.ReSize(sampling.Size());
309 samplingValues_ = sampling;
310 resizeSamplingIn_0_1(offset, range);
311 computeWeights();
312}
313
314void FSApproximationIrregularSampling::makeSignalVector(const TVector<double>& signal)
315{
316 int n = samplingValues_.Size();
317 if (n != signal.Size() )
318 {
319 cout << " echantillonnage et signal n'ont pas les memes dimensions " << endl;
320 }
321 signal_ = signal;
322 NormSignal();
323}
324
325
326
327
328
329void FSApproximationIrregularSampling::restaureSignal(TVector<double>& solution) const
330{
331 int k;
332 int n= samplingValues_.Size();
333 if (n<=0)
334 {
335 cout << " restaurationEnPoints: vecteurs de points vide " << endl;
336 return;
337 }
338 solution.ReSize(n);
339 for (k=0; k<n; k++)
340 {
341 double u = samplingValues_(k);
342 solution(k) = valeursSerie(u);
343 }
344 reshapeSignalInUsersFrame(solution);
345}
346
347
Note: See TracBrowser for help on using the repository browser.