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

Last change on this file since 3113 was 3077, checked in by cmv, 19 years ago

remplacement nbrandom.h (obsolete) -> srandgen.h cmv 14/09/2006

File size: 12.5 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <math.h>
4
5#ifdef __MWERKS__
6#include "unixmac.h"
7#endif
8
9
10#include "sopnamsp.h"
11#include "fmath.h"
12
13#include "bruit.h"
14#include "srandgen.h"
15// #include "rancern.h"
16// #include "hbook.h"
17#ifdef OS_MACOSX
18#include <limits.h>
19#endif
20
21// Le code des classes NoiseGenerator RWalkNoise
22
23//++
24// Class NoiseGenerator
25//
26// include bruit.h math.h fmath.h srandgen.h
27//
28//--
29//++
30//
31// Links Childs
32//
33// RWalkNoise OOFNoise EXPNoise MemNoise SumNoise
34//
35//--
36//++
37// Titre Constructors
38//--
39
40// Definition de fonctions pour float - a changer en utilisant cmath
41// Reza Juillet 2002
42inline float _myfabsf(float x) { return ((float)(fabs((double)x)) ); }
43inline float _mysqrtf(float x) { return ((float)(sqrt((double)x)) ); }
44
45/* --Methode-- */
46//++
47NoiseGenerator::NoiseGenerator(float sigma)
48//
49//--
50{
51if (sigma < 0.) sigma = 1.;
52mNCoups = 0;
53mSigma = sigma;
54//printf("-- NoiseGenerator::NoiseGenerator(%g) (Constructeur) ---\n", sigma);
55}
56
57//++
58// Titre Destructor
59//--
60/* --Methode-- */
61//++
62NoiseGenerator::~NoiseGenerator()
63//
64//--
65{
66 //printf("-- NoiseGenerator::~NoiseGenerator() (Destructeur) --- \n");
67}
68
69
70//++
71//
72// inline unsigned long int NoiseGenerator::NCoups()
73//--
74//++
75// Titre Public Methods
76//--
77
78/* --Methode-- */
79//++
80float NoiseGenerator::Noise()
81//
82//--
83{
84mNCoups++;
85return(NorRand()*mSigma);
86}
87//++
88// Class RWalkNoise
89//
90// include bruit.h math.h fmath.h srandgen.h
91//
92//--
93//++
94//
95// Links Parents
96//
97// NoiseGenerator
98//
99//--
100//++
101// Titre Constructor
102//--
103
104/* --Methode-- */
105//++
106RWalkNoise::RWalkNoise(float sigma)
107 : NoiseGenerator(sigma)
108//
109//--
110{
111mState = 0.;
112//printf("-- RWalkNoise::RWalkNoise(%g) (Constructeur) ---\n", sigma);
113}
114
115
116//++
117// Titre Destructor
118//--
119/* --Methode-- */
120//++
121RWalkNoise::~RWalkNoise()
122//
123//--
124{
125//printf("-- RWalkNoise::~RWalkNoise (Destructeur) ---\n");
126
127}
128
129//++
130// Titre Public Methods
131//--
132/* --Methode-- */
133//++
134float RWalkNoise::Noise()
135//
136//--
137{
138mState += NoiseGenerator::Noise();
139return(mState);
140}
141
142//++
143// Class OOFNoise
144//
145// include bruit.h math.h fmath.h srandgen.h
146//
147//--
148//++
149//
150// Links Parents
151//
152// NoiseGenerator
153//
154//--
155//++
156// Titre Constructor
157//--
158
159/* --Methode-- */
160//++
161OOFNoise::OOFNoise(float sigma, int typacf, int mem, float tau)
162 : NoiseGenerator(sigma)
163//
164//--
165{
166if (typacf != ACF_Exp) typacf = ACF_Exp;
167// Fonction d'autocorrelation donnant un bruit en 1/f
168//
169mTypACF = typacf;
170if (mem < 1) mem = 1;
171mMemL = mem;
172if (tau < 1.e-6) tau = 1.e-6;
173mTau = tau;
174mState = new double[mem];
175mDyn = new double[mem];
176int i;
177mDyn[0]=1.;
178mState[0]=0.;
179for(i=1; i<mem; i++) {
180 mState[i] = 0.; mDyn[i] = 1./sqrt((double)i);
181}
182//printf("-- OOFNoise::OOFNoise(%g,%d,%d,%g) (Constructeur) ---\n",
183// sigma, typacf, mem, tau);
184}
185
186
187//++
188// Titre Destructor
189//--
190/* --Methode-- */
191//++
192OOFNoise::~OOFNoise()
193//
194//--
195{
196delete[] mState;
197delete[] mDyn;
198// printf("-- OOFNoise::~OOFNoise (Destructeur) ---\n");
199}
200
201
202//++
203// Titre Public Methods
204//--
205/* --Methode-- */
206//++
207float OOFNoise::Noise()
208//
209//--
210{
211int i;
212double rn;
213
214for(i=(mMemL-1); i>0; i--) mState[i] = mState[i-1];
215mState[0] = NoiseGenerator::Noise();
216rn = 0.;
217for(i=0; i< mMemL; i++) rn += mDyn[i]*mState[i];
218return(rn);
219}
220
221/* --Methode-- */
222//++
223void OOFNoise::Print()
224//
225//--
226{
227int i,j;
228printf("OOFNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
229printf("OOFNoise::Print() Vecteur de Dynamique / Etat : \n");
230for(i=0; i<mMemL-1; i+=2)
231 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
232 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
233return;
234}
235//++
236// Class EXPNoise
237//
238// include bruit.h math.h fmath.h srandgen.h
239//
240//--
241//++
242//
243// Links Parents
244//
245// NoiseGenerator
246//
247//--
248//++
249// Titre Constructor
250//--
251
252/* --Methode-- */
253//++
254EXPNoise::EXPNoise(float sigma, int typacf, int mem, float tau)
255 : NoiseGenerator(sigma)
256//
257//--
258{
259if (typacf != ACF_Exp) typacf = ACF_Exp;
260// Fonction d'autocorrelation exponentiel disponible uniquement
261// Reza , Juillet 97
262mTypACF = typacf;
263if (mem < 1) mem = 1;
264mMemL = mem;
265if (tau < 1.e-6) tau = 1.e-6;
266mTau = tau;
267mState = new double[mem];
268mDyn = new double[mem];
269int i;
270for(i=0; i<mem; i++) {
271 mState[i] = 0.; mDyn[i] = exp(-(double)i/tau);
272}
273//printf("-- EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n",
274// sigma, typacf, mem, tau);
275}
276
277
278//++
279// Titre Destructor
280//--
281/* --Methode-- */
282//++
283EXPNoise::~EXPNoise()
284//
285//--
286{
287delete[] mState;
288delete[] mDyn;
289//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
290}
291
292
293//++
294// Titre Public Methods
295//--
296/* --Methode-- */
297//++
298float EXPNoise::Noise()
299//
300//--
301{
302int i;
303double rn;
304
305for(i=(mMemL-1); i>0; i--) mState[i] = mState[i-1];
306mState[0] = NoiseGenerator::Noise();
307rn = 0.;
308for(i=0; i< mMemL; i++) rn += mDyn[i]*mState[i];
309return(rn);
310}
311
312/* --Methode-- */
313//++
314void EXPNoise::Print()
315//
316//--
317{
318int i,j;
319printf("EXPNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
320printf("EXPNoise::Print() Vecteur de Dynamique / Etat : \n");
321for(i=0; i<mMemL-1; i+=2)
322 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
323 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
324
325return;
326}
327
328//++
329// Class MemNoise
330//
331// include bruit.h math.h fmath.h srandgen.h
332//
333//--
334//++
335//
336// Links Parents
337//
338// NoiseGenerator
339//
340//--
341//++
342// Titre Constructor
343//--
344
345
346// ---------------- $CHECK$ Reza 1/12/99 ------------
347// ----- MAJ MemNoise et SumNoise / version F. Couchot (~couchot/CoSa/Samba/bruit.cc )
348// -----------------------------------------------------------
349
350/* --Methode-- */
351//++
352MemNoise::MemNoise(float sigma, int mem, float tau, int ava)
353 : NoiseGenerator(_mysqrtf(_myfabsf(tau))*sigma)
354//
355//--
356{
357/* on tire les instants des impulsions successives selon une
358loi de distance exponentielle de duree tau
359*/
360const int place = 1000;
361mTypACF = ACF_Exp;
362if (mem < 1) mem = 1;
363mMemL = place;
364mCoupHaut=mem;
365if (tau < 1.) tau = 1.;
366mTau = tau;
367mStPos = new float[place];
368mStNeg = new float[place];
369mTePos = new float[place];
370mTeNeg = new float[place];
371// printf("apres reservation\n");
372int i;
373for(i=0; i<place; i++)
374{
375mStNeg[i] = 0.; mStPos[i] = 0.;
376}
377// printf("apres initialisation tableaux \n");
378
379mNappel=0;
380mNtirage=1;
381mNappLast=0;
382mMemPos=1;
383mMemNeg=1;
384mduree=0.;
385mTePos[0]=0.;
386mTeNeg[0]=0.;
387mTdernier=0.;
388
389Avance(ava);
390// printf("fin du createur MemNoise \n");
391//printf("-- EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n",
392// sigma, typacf, mem, tau);
393}
394
395
396//++
397// Titre Destructor
398//--
399/* --Methode-- */
400//++
401MemNoise::~MemNoise()
402//
403//--
404{
405delete[] mStPos;
406delete[] mStNeg;
407delete[] mTePos;
408delete[] mTeNeg;
409//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
410}
411
412//++
413// Titre Public Methods
414//--
415/* --Methode-- */
416//++
417float MemNoise::Noise()
418//
419//--
420{
421return(Avance(0));
422}
423
424/* --Methode-- */
425//++
426float MemNoise::Avance(long Asauter)
427//
428//--
429{
430int i,j;
431float boum;
432float rn = 0;
433float Somme,SbaryT,Poids,BaryT,Approx,Erreur;
434int nReduit;
435const float epsilon=.05;
436// printf("entree dans methode Noise de MemNoise \n");
437long mNsaut;
438for (mNsaut = Asauter ; mNsaut >= 0 ; mNsaut--)
439 { // debut mNsaut
440 // printf("mNsaut = %ld\n",mNsaut);
441mNappel++;
442mTdernier += 1.;
443for(i=0; i<mMemPos; i++) mTePos[i] += 1.;
444for(i=0; i<mMemNeg; i++) mTeNeg[i] += 1.;
445
446if (mduree < mTdernier)
447 {
448 /* la duree depuis le dernier tirage est maintenant ecoulee
449 on commence par remettre a jour le temps ecoule entre la derniere
450 impulsion (celle qu'on va tirer maintenant) et l'instant present */
451
452 mTdernier = mTdernier - mduree;
453
454 /* puis on tire une nouvelle impulsion de bruit */
455
456 boum = NoiseGenerator::Noise();
457
458 /* on decale la memoire d'une case vers le passe
459 puis on met a jour la case [0] */
460
461if(boum>0)
462 {
463 for(i=mMemPos; i>0; i--)
464 {
465 mStPos[i] = mStPos[i-1];
466 mTePos[i] = mTePos[i-1];
467 }
468 mTePos[0] = mTdernier;
469 mStPos[0] = boum;
470 if (mMemPos<mMemL) mMemPos++;
471/* a chaque tirage, on regroupe les impulsions precedentes */
472for(i=mMemPos-2 ; i>0 ; i--)
473 {
474 if(mStPos[i]==0.)continue;
475 // printf("i,temps,bruit %d,%g,%g \n",i,mTePos[i],mStPos[i]);
476 Somme = mStPos[i]/_mysqrtf(mTePos[i]);
477 SbaryT = mStPos[i] * mTePos[i];
478 Poids = mStPos[i];
479 for(j=i-1 ; j>=0 ; j--)
480 {
481 // printf(" j,temps,bruit %d,%g,%g \n",j,mTePos[j],mStPos[j]);
482 Somme += mStPos[j]/_mysqrtf(mTePos[j]);
483 Poids += mStPos[j];
484 SbaryT += mStPos[j] * mTePos[j];
485 BaryT = SbaryT / Poids;
486 Approx = Poids / _mysqrtf(BaryT);
487 Erreur = (Approx - Somme) / Somme;
488 // printf("i,j = %d %d Approx = %g \n",i,j,_myfabsf(Erreur));
489 // printf("Temps,Bruit = %g %g \n",BaryT,Poids);
490 if(_myfabsf(Erreur)<epsilon)
491 {
492 mStPos[i]=Poids;
493 mTePos[i]=BaryT;
494 mStPos[j]=0.;
495 }
496 else break;
497 }
498 }
499nReduit=0;
500for(i=0; i<mMemPos-1 ; i++)
501 {
502 if(mStPos[i]!=0)
503 {
504 mStPos[nReduit]=mStPos[i];
505 mTePos[nReduit]=mTePos[i];
506 nReduit++;
507 }
508 }
509mMemPos=nReduit+1;
510
511 }
512else
513 {
514 for(i=mMemNeg; i>0; i--)
515 {
516 mStNeg[i] = mStNeg[i-1];
517 mTeNeg[i] = mTeNeg[i-1];
518 }
519 mTeNeg[0] = mTdernier;
520 mStNeg[0] = boum;
521 if (mMemNeg<mMemL) mMemNeg++;
522
523
524/* idem pour negatifs */
525for(i=mMemNeg-2 ; i>0 ; i--)
526 {
527 if(mStNeg[i]==0.)continue;
528 // printf("i,temps,bruit %d,%g,%g \n",i,mTeNeg[i],mStNeg[i]);
529 Somme = mStNeg[i]/_mysqrtf(mTeNeg[i]);
530 SbaryT = mStNeg[i] * mTeNeg[i];
531 Poids = mStNeg[i];
532 for(j=i-1 ; j>=0 ; j--)
533 {
534 // printf(" j,temps,bruit %d,%g,%g \n",j,mTeNeg[j],mStNeg[j]);
535 Somme += mStNeg[j]/_mysqrtf(mTeNeg[j]);
536 Poids += mStNeg[j];
537 SbaryT += mStNeg[j] * mTeNeg[j];
538 BaryT = SbaryT / Poids;
539 Approx = Poids / _mysqrtf(BaryT);
540 Erreur = (Approx - Somme) / Somme;
541 // printf("i,j = %d %d Approx = %g \n",i,j,Erreur);
542 // printf("Temps,Bruit = %g %g \n",BaryT,Poids);
543 if(_myfabsf(Erreur)<epsilon)
544 {
545 mStNeg[i]=Poids;
546 mTeNeg[i]=BaryT;
547 mStNeg[j]=0.;
548 }
549 else break;
550 }
551 }
552nReduit=0;
553for(i=0; i<mMemNeg-1 ; i++)
554 {
555 if(mStNeg[i]!=0)
556 {
557 mStNeg[nReduit]=mStNeg[i];
558 mTeNeg[nReduit]=mTeNeg[i];
559 nReduit++;
560 }
561 }
562mMemNeg=nReduit+1;
563 }
564/* on tire la duree a attendre avant la prochaine impulsion de bruit */
565// $CHECK$ avec Francois - rndm() remplace par Reza 10/01/99
566// passage en drand le 1/12/99
567mduree = -mTau*log(drand01());
568
569// if(mNtirage<mMemL) mNtirage++;
570mNtirage++;
571/*
572int idn=1;
573float pds=1.;
574float nul=0.;
575hfill_(&idn,&mduree,&nul,&pds);
576*/
577// printf("Ntirage %d,mMemPos,Neg %d,%d, Suppress = %d \n",mNtirage,mMemPos,mMemNeg, Suppress);
578 }
579/* On calcule le bruit total */
580
581//printf("mMemPos,Neg,%d %d\n",mMemPos,mMemNeg);
582//for(i=0;i<mMemPos;i++) printf("mTePos %g \n",mTePos);
583//for(i=0;i<mMemNeg;i++) printf("mTeNeg %g \n",mTeNeg);
584if(mNsaut == 0)
585 {
586 // printf("coucou\n");
587rn = 0.;
588int indlim=0;
589for(i=0; i < mMemPos-1; i++)
590{
591if(mTePos[i] > 1.) break; // Modif F.C et D.Y. 03/2000
592rn += mStPos[i];
593indlim++;
594}
595// float ajout=0.;
596for(i=indlim; i < mMemPos-1; i++) rn += mStPos[i]/_mysqrtf(mTePos[i]);
597indlim=0;
598for(i=0; i < mMemNeg-1; i++)
599{
600if(mTeNeg[i] > 1.) break; // Modif F.C et D.Y. 03/2000
601rn += mStNeg[i];
602indlim++;
603}
604for(i=indlim; i < mMemNeg-1; i++) rn += mStNeg[i]/_mysqrtf(mTeNeg[i]);
605}
606}
607return(rn);
608}
609/* --Methode-- */
610//++
611int MemNoise::Print()
612//
613//--
614{
615int i,j,rc=0;
616printf("MemNoise::Print() MemL=%d Tau= %g \n", mMemL, mTau);
617printf("mNtirage= %d , mMemPos= %d , mMemNeg= %d \n",mNtirage,mMemPos,mMemNeg);
618// printf("MemNoise::Print() Vecteur de Dynamique / Etat : \n");
619/* for(i=0; i<mMemL-1; i+=2)
620 printf("%d: D=%g S=%g | %d: D=%g S=%g \n", i,
621 mDyn[i], mState[i], i+1, mDyn[i], mState[i]);
622 */
623return(rc);
624}
625
626//++
627// Class SumNoise
628//
629// include bruit.h math.h fmath.h srandgen.h
630//
631// Generateur de bruit blanc + 1/f avec fknee
632
633//--
634//++
635//
636// Links Parents
637//
638// NoiseGenerator
639//
640//--
641//++
642// Titre Constructor
643//--
644// Generateur de bruit blanc + 1/f avec fknee
645
646
647/* --Methode-- */
648//++
649SumNoise::SumNoise(float fknee, float sig, int mem, float tau)
650 : NoiseGenerator(sig)
651//
652//--
653{
654// Reza 27/01/98 :
655// Je calcule les sigma du MemNoise d'apres la formule de Francois
656// mn = new MemNoise(sig*fknee);
657// mn = new MemNoise(1.4142*sig*_mysqrtf(fknee),1,10.,1000000); // modif appel FC 13 mai 98.
658mn = new MemNoise(1.4142*sig*sqrt((double)fknee),mem,tau,12000); // FC 13 mai 98. -> Reza 1/12/99
659}
660
661
662//++
663// Titre Destructor
664//--
665/* --Methode-- */
666//++
667SumNoise::~SumNoise()
668//
669//--
670{
671delete mn;
672}
673
674//++
675// Titre Public Methods
676//--
677/* --Methode-- */
678//++
679float SumNoise::Noise()
680//
681//--
682{
683return(NoiseGenerator::Noise() + mn->Noise());
684}
Note: See TracBrowser for help on using the repository browser.