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

Last change on this file since 1943 was 1943, checked in by lemeur, 24 years ago

suppression d'une variable inutilisee

File size: 9.0 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 if (nbInterv < 2*M_+1 || nbInterv%2 != 0)
122 {
123 int k;
124 solution.ReSize(nbInterv);
125 double delta = 1./nbInterv;
126 for (k=0; k<nbInterv; k++)
127 {
128 double u = k*delta;
129 solution(k) = valeursSerie(u);
130 }
131 }
132 else
133 {
134 int tailleTF = nbInterv/2+1;
135 TVector<complex<double> > TFf(tailleTF);
136 TFf = complex<double>(0.,0.);
137 TFf(Range(0,M_)) = coefFourier_;
138 fftIntfPtr_-> FFTBackward(TFf, solution);
139 }
140 reshapeSignalInUsersFrame(solution);
141}
142
143void FSApproximationIrregularSampling::computeSignalOnASampling(const TVector<double>& abscisses, TVector<double>& solution ) const
144{
145 int k;
146 int n= abscisses.Size();
147 if (n<=0)
148 {
149 cout << " restaurationEnPoints: vecteurs de points vide " << endl;
150 return;
151 }
152 TVector<double> abscissesLocales;
153 abscissesLocales = abscisses;
154 matchToSamplingReference(abscissesLocales);
155 solution.ReSize(n);
156 for (k=0; k<n; k++)
157 {
158 double u = abscissesLocales(k);
159 solution(k) = valeursSerie(u);
160 }
161 reshapeSignalInUsersFrame(abscisses, solution);
162
163}
164
165double FSApproximationIrregularSampling::estimationConditionnement() const
166{
167 double deuxDeltaM = 2.*delta_*M_;
168 double cond = (1.+deuxDeltaM)/(1.-deuxDeltaM);
169 cond *= cond;
170 return cond;
171}
172
173void FSApproximationIrregularSampling::samplingValues(TVector<double>& sv) const
174{
175 int k;
176 int n = samplingValues_.Size();
177 sv.ReSize(n);
178 for (k=0; k<n;k++)
179 {
180 sv(k) = samplingOffset_+samplingRange_*samplingValues_(k);
181 }
182
183}
184
185// terme constant, puis cos, sin, cos, sin......
186void FSApproximationIrregularSampling::coeffCosSin(TVector<double>& coef) const
187{
188 int j;
189 coef.ReSize(2*M_+1);
190 coef(0) = coefFourier_(0).real();
191 for (j=1; j<M_; j++)
192 {
193 double aj = 2.*coefFourier_(j).real();
194 double bj = -2.*coefFourier_(j).imag();
195 coef(2*(j-1)+1) = aj;
196 coef(2*(j-1)+2) = bj;
197 }
198 coef *= normeSignal_;
199}
200
201// exprime les valeurs d'abscisses, selon la reference locale
202void FSApproximationIrregularSampling::matchToSamplingReference(TVector<double>& sampling) const
203
204{
205 int k;
206 int compteur = sampling.Size();
207 double fac = 1./samplingRange_;
208 for (k=0; k<compteur; k++)
209 {
210 sampling(k) = (sampling(k)-samplingOffset_)*fac;
211
212 }
213 if ( sampling(0) <0. || sampling(compteur-1) >1. )
214 {
215 cout << " matchToSamplingReference: points hors [0.,1.] " << endl;
216 cout << " " << sampling(0) << " " << sampling(compteur-1) << endl;
217 }
218}
219
220// exprime les valeurs d'echantillonnage entre 0 et 1
221void FSApproximationIrregularSampling::resizeSamplingIn_0_1(double offset, double range)
222{
223 int k;
224 int compteur = samplingValues_.Size();
225 samplingOffset_ = offset;
226 samplingRange_ = range;
227 double fac = 1./samplingRange_;
228 for (k=0; k<compteur ;k++)
229 {
230 samplingValues_(k) = (samplingValues_(k)-samplingOffset_)*fac;
231 }
232}
233
234void FSApproximationIrregularSampling::computeWeights()
235{
236 int k;
237 int nbEchantillons = samplingValues_.Size();
238 nokdelta_ = 0;
239
240 // calcul de l'ecart maximum entre deux temps d'echantillonnage consecutifs
241 delta_ = samplingValues_(0)-samplingValues_(nbEchantillons-1)+1;
242 for (k=0; k< nbEchantillons-1; k++)
243 {
244 double diff = samplingValues_(k+1)-samplingValues_(k);
245 if ( diff > delta_ )
246 {
247 delta_ = diff;
248 nokdelta_ = k;
249 }
250 }
251 // calcul des poids (pour tenir compte de l'irregularite de
252 // l'echantillonnage)
253 poids_.ReSize(nbEchantillons);
254 poids_(0) = 0.5*(samplingValues_(1)-samplingValues_(nbEchantillons-1) + 1.);
255 for (k=1; k< nbEchantillons-1; k++)
256 {
257 poids_(k) = 0.5*(samplingValues_(k+1)-samplingValues_(k-1));
258 }
259 poids_(nbEchantillons-1) = 0.5*(samplingValues_(0) +1 - samplingValues_(nbEchantillons-2));
260
261}
262void FSApproximationIrregularSampling::NormSignal()
263{
264 int k;
265 int nbEchantillons = samplingValues_.Size();
266 normeSignal_=0;
267 for (k=0; k< nbEchantillons; k++)
268 {
269 double s = signal_(k);
270 normeSignal_ += s*s*poids_(k);
271 }
272 normeSignal_=sqrt(normeSignal_);
273 double fac = 1./normeSignal_;
274 signal_ *= fac;
275}
276
277
278
279void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(const TVector<double>& abscisses, TVector<double>& resultat) const
280{
281 if (resultat.Size() <= 0)
282 {
283 cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
284 }
285 resultat *= normeSignal_;
286}
287
288void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(TVector<double>& resultat) const
289{
290 if (resultat.Size() <= 0)
291 {
292 cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
293 }
294 resultat *= normeSignal_;
295}
296
297
298void FSApproximationIrregularSampling::makeSamplingVector(const TVector<double>& sampling, double offset, double range)
299{
300 samplingValues_.ReSize(sampling.Size());
301 samplingValues_ = sampling;
302 resizeSamplingIn_0_1(offset, range);
303 computeWeights();
304}
305
306void FSApproximationIrregularSampling::makeSignalVector(const TVector<double>& signal)
307{
308 int n = samplingValues_.Size();
309 if (n != signal.Size() )
310 {
311 cout << " echantillonnage et signal n'ont pas les memes dimensions " << endl;
312 }
313 signal_ = signal;
314 NormSignal();
315}
316
317
318
319
320
321void FSApproximationIrregularSampling::restaureSignal(TVector<double>& solution) const
322{
323 int k;
324 int n= samplingValues_.Size();
325 if (n<=0)
326 {
327 cout << " restaurationEnPoints: vecteurs de points vide " << endl;
328 return;
329 }
330 solution.ReSize(n);
331 for (k=0; k<n; k++)
332 {
333 double u = samplingValues_(k);
334 solution(k) = valeursSerie(u);
335 }
336 reshapeSignalInUsersFrame(solution);
337}
338
339
Note: See TracBrowser for help on using the repository browser.