source: Sophya/trunk/SophyaLib/Samba/bruit.cc@ 228

Last change on this file since 228 was 228, checked in by ansari, 26 years ago

Creation du module DPC/Samba Reza 13/04/99

File size: 9.7 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <math.h>
4
5#include "fmath.h"
6#include "cimage.h"
7
8#include "bruit.h"
9#include "nbrandom.h"
10// #include "rancern.h"
11#include "hbook.h"
12
13// Le code des classes NoiseGenerator RWalkNoise
14
15
16/* --Methode-- */
17NoiseGenerator::NoiseGenerator(float sigma)
18{
19if (sigma < 0.) sigma = 1.;
20mNCoups = 0;
21mSigma = sigma;
22//printf("-- NoiseGenerator::NoiseGenerator(%g) (Constructeur) ---\n", sigma);
23}
24
25/* --Methode-- */
26NoiseGenerator::~NoiseGenerator()
27{
28 //printf("-- NoiseGenerator::~NoiseGenerator() (Destructeur) --- \n");
29}
30
31/* --Methode-- */
32float NoiseGenerator::Noise()
33{
34mNCoups++;
35return(NorRand()*mSigma);
36}
37
38/* --Methode-- */
39RWalkNoise::RWalkNoise(float sigma)
40 : NoiseGenerator(sigma)
41{
42mState = 0.;
43//printf("-- RWalkNoise::RWalkNoise(%g) (Constructeur) ---\n", sigma);
44}
45
46
47/* --Methode-- */
48RWalkNoise::~RWalkNoise()
49{
50//printf("-- RWalkNoise::~RWalkNoise (Destructeur) ---\n");
51
52}
53
54/* --Methode-- */
55float RWalkNoise::Noise()
56{
57mState += NoiseGenerator::Noise();
58return(mState);
59}
60
61
62/* --Methode-- */
63OOFNoise::OOFNoise(float sigma, int typacf, int mem, float tau)
64 : NoiseGenerator(sigma)
65{
66if (typacf != ACF_Exp) typacf = ACF_Exp;
67// Fonction d'autocorrelation donnant un bruit en 1/f
68//
69mTypACF = typacf;
70if (mem < 1) mem = 1;
71mMemL = mem;
72if (tau < 1.e-6) tau = 1.e-6;
73mTau = tau;
74mState = new double[mem];
75mDyn = new double[mem];
76int i;
77mDyn[0]=1.;
78mState[0]=0.;
79for(i=1; i<mem; i++) {
80 mState[i] = 0.; mDyn[i] = 1./sqrt((double)i);
81}
82//printf("-- OOFNoise::OOFNoise(%g,%d,%d,%g) (Constructeur) ---\n",
83// sigma, typacf, mem, tau);
84}
85
86
87/* --Methode-- */
88OOFNoise::~OOFNoise()
89{
90delete[] mState;
91delete[] mDyn;
92// printf("-- OOFNoise::~OOFNoise (Destructeur) ---\n");
93}
94
95
96/* --Methode-- */
97float OOFNoise::Noise()
98{
99int i;
100double rn;
101
102for(i=(mMemL-1); i>0; i--) mState[i] = mState[i-1];
103mState[0] = NoiseGenerator::Noise();
104rn = 0.;
105for(i=0; i< mMemL; i++) rn += mDyn[i]*mState[i];
106return(rn);
107}
108
109/* --Methode-- */
110void OOFNoise::Print()
111{
112int i,j;
113printf("OOFNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
114printf("OOFNoise::Print() Vecteur de Dynamique / Etat : \n");
115for(i=0; i<mMemL-1; i+=2)
116 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
117 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
118return;
119}
120
121/* --Methode-- */
122EXPNoise::EXPNoise(float sigma, int typacf, int mem, float tau)
123 : NoiseGenerator(sigma)
124{
125if (typacf != ACF_Exp) typacf = ACF_Exp;
126// Fonction d'autocorrelation exponentiel disponible uniquement
127// Reza , Juillet 97
128mTypACF = typacf;
129if (mem < 1) mem = 1;
130mMemL = mem;
131if (tau < 1.e-6) tau = 1.e-6;
132mTau = tau;
133mState = new double[mem];
134mDyn = new double[mem];
135int i;
136for(i=0; i<mem; i++) {
137 mState[i] = 0.; mDyn[i] = exp(-(double)i/tau);
138}
139//printf("-- EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n",
140// sigma, typacf, mem, tau);
141}
142
143
144/* --Methode-- */
145EXPNoise::~EXPNoise()
146{
147delete[] mState;
148delete[] mDyn;
149//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
150}
151
152
153/* --Methode-- */
154float EXPNoise::Noise()
155{
156int i;
157double rn;
158
159for(i=(mMemL-1); i>0; i--) mState[i] = mState[i-1];
160mState[0] = NoiseGenerator::Noise();
161rn = 0.;
162for(i=0; i< mMemL; i++) rn += mDyn[i]*mState[i];
163return(rn);
164}
165
166/* --Methode-- */
167void EXPNoise::Print()
168{
169int i,j;
170printf("EXPNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
171printf("EXPNoise::Print() Vecteur de Dynamique / Etat : \n");
172for(i=0; i<mMemL-1; i+=2)
173 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
174 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
175
176return;
177}
178/* --Methode-- */
179MemNoise::MemNoise(float sigma, int mem, float tau, int ava)
180 : NoiseGenerator(sqrtf(fabsf(tau))*sigma)
181{
182/* on tire les instants des impulsions successives selon une
183loi de distance exponentielle de duree tau
184*/
185const int place = 1000;
186mTypACF = ACF_Exp;
187if (mem < 1) mem = 1;
188mMemL = place;
189mCoupHaut=mem;
190if (tau < 1.) tau = 1.;
191mTau = tau;
192mStPos = new float[place];
193mStNeg = new float[place];
194mTePos = new float[place];
195mTeNeg = new float[place];
196// printf("apres reservation\n");
197int i;
198for(i=0; i<place; i++)
199{
200mStNeg[i] = 0.; mStPos[i] = 0.;
201}
202// printf("apres initialisation tableaux \n");
203
204mNappel=0;
205mNtirage=1;
206mNappLast=0;
207mMemPos=1;
208mMemNeg=1;
209mduree=0.;
210mTePos[0]=0.;
211mTeNeg[0]=0.;
212mTdernier=0.;
213
214Avance(ava);
215// printf("fin du createur MemNoise \n");
216//printf("-- EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n",
217// sigma, typacf, mem, tau);
218}
219
220
221/* --Methode-- */
222MemNoise::~MemNoise()
223{
224delete[] mStPos;
225delete[] mStNeg;
226delete[] mTePos;
227delete[] mTeNeg;
228//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
229}
230
231/* --Methode-- */
232float MemNoise::Noise()
233{
234return(Avance(0));
235}
236
237/* --Methode-- */
238float MemNoise::Avance(long Asauter)
239{
240int i,j;
241float boum;
242float rn;
243float Somme,SbaryT,Poids,BaryT,Approx,Erreur;
244int nReduit;
245const float epsilon=.05;
246// printf("entree dans methode Noise de MemNoise \n");
247long mNsaut;
248for (mNsaut = Asauter ; mNsaut >= 0 ; mNsaut--)
249 { // debut mNsaut
250 // printf("mNsaut = %ld\n",mNsaut);
251mNappel++;
252mTdernier += 1.;
253for(i=0; i<mMemPos; i++) mTePos[i] += 1.;
254for(i=0; i<mMemNeg; i++) mTeNeg[i] += 1.;
255
256if (mduree < mTdernier)
257 {
258 /* la duree depuis le dernier tirage est maintenant ecoulee
259 on commence par remettre a jour le temps ecoule entre la derniere
260 impulsion (celle qu'on va tirer maintenant) et l'instant present */
261
262 mTdernier = mTdernier - mduree;
263
264 /* puis on tire une nouvelle impulsion de bruit */
265
266 boum = NoiseGenerator::Noise();
267
268 /* on decale la memoire d'une case vers le passe
269 puis on met a jour la case [0] */
270
271if(boum>0)
272 {
273 for(i=mMemPos; i>0; i--)
274 {
275 mStPos[i] = mStPos[i-1];
276 mTePos[i] = mTePos[i-1];
277 }
278 mTePos[0] = mTdernier;
279 mStPos[0] = boum;
280 if (mMemPos<mMemL) mMemPos++;
281/* a chaque tirage, on regroupe les impulsions precedentes */
282for(i=mMemPos-2 ; i>0 ; i--)
283 {
284 if(mStPos[i]==0.)continue;
285 // printf("i,temps,bruit %d,%g,%g \n",i,mTePos[i],mStPos[i]);
286 Somme = mStPos[i]/sqrtf(mTePos[i]);
287 SbaryT = mStPos[i] * mTePos[i];
288 Poids = mStPos[i];
289 for(j=i-1 ; j>=0 ; j--)
290 {
291 // printf(" j,temps,bruit %d,%g,%g \n",j,mTePos[j],mStPos[j]);
292 Somme += mStPos[j]/sqrtf(mTePos[j]);
293 Poids += mStPos[j];
294 SbaryT += mStPos[j] * mTePos[j];
295 BaryT = SbaryT / Poids;
296 Approx = Poids / sqrtf(BaryT);
297 Erreur = (Approx - Somme) / Somme;
298 // printf("i,j = %d %d Approx = %g \n",i,j,fabsf(Erreur));
299 // printf("Temps,Bruit = %g %g \n",BaryT,Poids);
300 if(fabsf(Erreur)<epsilon)
301 {
302 mStPos[i]=Poids;
303 mTePos[i]=BaryT;
304 mStPos[j]=0.;
305 }
306 else break;
307 }
308 }
309nReduit=0;
310for(i=0; i<mMemPos-1 ; i++)
311 {
312 if(mStPos[i]!=0)
313 {
314 mStPos[nReduit]=mStPos[i];
315 mTePos[nReduit]=mTePos[i];
316 nReduit++;
317 }
318 }
319mMemPos=nReduit+1;
320
321 }
322else
323 {
324 for(i=mMemNeg; i>0; i--)
325 {
326 mStNeg[i] = mStNeg[i-1];
327 mTeNeg[i] = mTeNeg[i-1];
328 }
329 mTeNeg[0] = mTdernier;
330 mStNeg[0] = boum;
331 if (mMemNeg<mMemL) mMemNeg++;
332
333
334/* idem pour negatifs */
335for(i=mMemNeg-2 ; i>0 ; i--)
336 {
337 if(mStNeg[i]==0.)continue;
338 // printf("i,temps,bruit %d,%g,%g \n",i,mTeNeg[i],mStNeg[i]);
339 Somme = mStNeg[i]/sqrtf(mTeNeg[i]);
340 SbaryT = mStNeg[i] * mTeNeg[i];
341 Poids = mStNeg[i];
342 for(j=i-1 ; j>=0 ; j--)
343 {
344 // printf(" j,temps,bruit %d,%g,%g \n",j,mTeNeg[j],mStNeg[j]);
345 Somme += mStNeg[j]/sqrtf(mTeNeg[j]);
346 Poids += mStNeg[j];
347 SbaryT += mStNeg[j] * mTeNeg[j];
348 BaryT = SbaryT / Poids;
349 Approx = Poids / sqrtf(BaryT);
350 Erreur = (Approx - Somme) / Somme;
351 // printf("i,j = %d %d Approx = %g \n",i,j,Erreur);
352 // printf("Temps,Bruit = %g %g \n",BaryT,Poids);
353 if(fabsf(Erreur)<epsilon)
354 {
355 mStNeg[i]=Poids;
356 mTeNeg[i]=BaryT;
357 mStNeg[j]=0.;
358 }
359 else break;
360 }
361 }
362nReduit=0;
363for(i=0; i<mMemNeg-1 ; i++)
364 {
365 if(mStNeg[i]!=0)
366 {
367 mStNeg[nReduit]=mStNeg[i];
368 mTeNeg[nReduit]=mTeNeg[i];
369 nReduit++;
370 }
371 }
372mMemNeg=nReduit+1;
373 }
374/* on tire la duree a attendre avant la prochaine impulsion de bruit */
375// $CHECK$ avec Francois - rndm() remplace par Reza 10/01/99
376mduree = -mTau*log(frand01());
377
378// if(mNtirage<mMemL) mNtirage++;
379mNtirage++;
380/*
381int idn=1;
382float pds=1.;
383float nul=0.;
384hfill_(&idn,&mduree,&nul,&pds);
385*/
386// printf("Ntirage %d,mMemPos,Neg %d,%d, Suppress = %d \n",mNtirage,mMemPos,mMemNeg, Suppress);
387 }
388/* On calcule le bruit total */
389
390//printf("mMemPos,Neg,%d %d\n",mMemPos,mMemNeg);
391//for(i=0;i<mMemPos;i++) printf("mTePos %g \n",mTePos);
392//for(i=0;i<mMemNeg;i++) printf("mTeNeg %g \n",mTeNeg);
393if(mNsaut == 0)
394 {
395 // printf("coucou\n");
396rn = 0.;
397int indlim=0;
398for(i=0; i < mMemPos-1; i++)
399{
400if(mTePos[i] > .1)break;
401rn += mStPos[i];
402indlim++;
403}
404// float ajout=0.;
405for(i=indlim; i < mMemPos-1; i++) rn += mStPos[i]/sqrtf(mTePos[i]);
406indlim=0;
407for(i=0; i < mMemNeg-1; i++)
408{
409if(mTeNeg[i] > .1) break;
410rn += mStNeg[i];
411indlim++;
412}
413for(i=indlim; i < mMemNeg-1; i++) rn += mStNeg[i]/sqrtf(mTeNeg[i]);
414}
415}
416return(rn);
417}
418/* --Methode-- */
419
420int MemNoise::Print()
421{
422int i,j,rc=0;
423printf("MemNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
424printf("mNtirage= %d , mMemPos= %d , mMemNeg= %d \n",mNtirage,mMemPos,mMemNeg);
425// printf("MemNoise::Print() Vecteur de Dynamique / Etat : \n");
426/* for(i=0; i<mMemL-1; i+=2)
427 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
428 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
429 */
430return(rc);
431}
432
433
434// Generateur de bruit blanc + 1/f avec fknee
435
436
437/* --Methode-- */
438SumNoise::SumNoise(float fknee, float sig)
439 : NoiseGenerator(sig)
440{
441// Reza 27/01/98 :
442// Je calcule les sigma du MemNoise d'apres la formule de Francois
443mn = new MemNoise(sig*fknee);
444}
445
446
447/* --Methode-- */
448SumNoise::~SumNoise()
449{
450delete mn;
451}
452
453/* --Methode-- */
454float SumNoise::Noise()
455{
456return(NoiseGenerator::Noise() + mn->Noise());
457}
Note: See TracBrowser for help on using the repository browser.