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

Last change on this file since 4002 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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