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

Last change on this file since 2384 was 2148, checked in by ansari, 23 years ago

Adaptation a fmath.h vide (pas de #define fsqrt() fabsf() , Reza 31/7/2002

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