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

Last change on this file since 2751 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: 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
[2615]10#include "sopnamsp.h"
[228]11#include "fmath.h"
12
13#include "bruit.h"
14#include "nbrandom.h"
15// #include "rancern.h"
[313]16// #include "hbook.h"
[1783]17#ifdef OS_MACOSX
18#include <limits.h>
19#endif
[228]20
21// Le code des classes NoiseGenerator RWalkNoise
22
[568]23//++
24// Class NoiseGenerator
25//
26// include bruit.h math.h fmath.h nbrandom.h
27//
28//--
29//++
30//
31// Links Childs
32//
33// RWalkNoise OOFNoise EXPNoise MemNoise SumNoise
34//
35//--
36//++
37// Titre Constructors
38//--
[228]39
[2148]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
[228]45/* --Methode-- */
[568]46//++
[228]47NoiseGenerator::NoiseGenerator(float sigma)
[568]48//
49//--
[228]50{
51if (sigma < 0.) sigma = 1.;
52mNCoups = 0;
53mSigma = sigma;
54//printf("-- NoiseGenerator::NoiseGenerator(%g) (Constructeur) ---\n", sigma);
55}
56
[568]57//++
58// Titre Destructor
59//--
[228]60/* --Methode-- */
[568]61//++
[228]62NoiseGenerator::~NoiseGenerator()
[568]63//
64//--
[228]65{
66 //printf("-- NoiseGenerator::~NoiseGenerator() (Destructeur) --- \n");
67}
68
[568]69
70//++
71//
72// inline unsigned long int NoiseGenerator::NCoups()
73//--
74//++
75// Titre Public Methods
76//--
77
[228]78/* --Methode-- */
[568]79//++
[228]80float NoiseGenerator::Noise()
[568]81//
82//--
[228]83{
84mNCoups++;
85return(NorRand()*mSigma);
86}
[568]87//++
88// Class RWalkNoise
89//
90// include bruit.h math.h fmath.h nbrandom.h
91//
92//--
93//++
94//
95// Links Parents
96//
97// NoiseGenerator
98//
99//--
100//++
101// Titre Constructor
102//--
[228]103
104/* --Methode-- */
[568]105//++
[228]106RWalkNoise::RWalkNoise(float sigma)
107 : NoiseGenerator(sigma)
[568]108//
109//--
[228]110{
111mState = 0.;
112//printf("-- RWalkNoise::RWalkNoise(%g) (Constructeur) ---\n", sigma);
113}
114
115
[568]116//++
117// Titre Destructor
118//--
[228]119/* --Methode-- */
[568]120//++
[228]121RWalkNoise::~RWalkNoise()
[568]122//
123//--
[228]124{
125//printf("-- RWalkNoise::~RWalkNoise (Destructeur) ---\n");
126
127}
128
[568]129//++
130// Titre Public Methods
131//--
[228]132/* --Methode-- */
[568]133//++
[228]134float RWalkNoise::Noise()
[568]135//
136//--
[228]137{
138mState += NoiseGenerator::Noise();
139return(mState);
140}
141
[568]142//++
143// Class OOFNoise
144//
145// include bruit.h math.h fmath.h nbrandom.h
146//
147//--
148//++
149//
150// Links Parents
151//
152// NoiseGenerator
153//
154//--
155//++
156// Titre Constructor
157//--
[228]158
159/* --Methode-- */
[568]160//++
[228]161OOFNoise::OOFNoise(float sigma, int typacf, int mem, float tau)
162 : NoiseGenerator(sigma)
[568]163//
164//--
[228]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
[568]187//++
188// Titre Destructor
189//--
[228]190/* --Methode-- */
[568]191//++
[228]192OOFNoise::~OOFNoise()
[568]193//
194//--
[228]195{
196delete[] mState;
197delete[] mDyn;
198// printf("-- OOFNoise::~OOFNoise (Destructeur) ---\n");
199}
200
201
[568]202//++
203// Titre Public Methods
204//--
[228]205/* --Methode-- */
[568]206//++
[228]207float OOFNoise::Noise()
[568]208//
209//--
[228]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-- */
[568]222//++
[228]223void OOFNoise::Print()
[568]224//
225//--
[228]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}
[568]235//++
236// Class EXPNoise
237//
238// include bruit.h math.h fmath.h nbrandom.h
239//
240//--
241//++
242//
243// Links Parents
244//
245// NoiseGenerator
246//
247//--
248//++
249// Titre Constructor
250//--
[228]251
252/* --Methode-- */
[568]253//++
[228]254EXPNoise::EXPNoise(float sigma, int typacf, int mem, float tau)
255 : NoiseGenerator(sigma)
[568]256//
257//--
[228]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
[568]278//++
279// Titre Destructor
280//--
[228]281/* --Methode-- */
[568]282//++
[228]283EXPNoise::~EXPNoise()
[568]284//
285//--
[228]286{
287delete[] mState;
288delete[] mDyn;
289//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
290}
291
292
[568]293//++
294// Titre Public Methods
295//--
[228]296/* --Methode-- */
[568]297//++
[228]298float EXPNoise::Noise()
[568]299//
300//--
[228]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-- */
[568]313//++
[228]314void EXPNoise::Print()
[568]315//
316//--
[228]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}
[568]327
328//++
329// Class MemNoise
330//
331// include bruit.h math.h fmath.h nbrandom.h
332//
333//--
334//++
335//
336// Links Parents
337//
338// NoiseGenerator
339//
340//--
341//++
342// Titre Constructor
343//--
344
345
[680]346// ---------------- $CHECK$ Reza 1/12/99 ------------
347// ----- MAJ MemNoise et SumNoise / version F. Couchot (~couchot/CoSa/Samba/bruit.cc )
348// -----------------------------------------------------------
[568]349
[228]350/* --Methode-- */
[568]351//++
[228]352MemNoise::MemNoise(float sigma, int mem, float tau, int ava)
[2148]353 : NoiseGenerator(_mysqrtf(_myfabsf(tau))*sigma)
[568]354//
355//--
[228]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
[568]396//++
397// Titre Destructor
398//--
[228]399/* --Methode-- */
[568]400//++
[228]401MemNoise::~MemNoise()
[568]402//
403//--
[228]404{
405delete[] mStPos;
406delete[] mStNeg;
407delete[] mTePos;
408delete[] mTeNeg;
409//printf("-- EXPNoise::~EXPNoise (Destructeur) ---\n");
410}
411
[568]412//++
413// Titre Public Methods
414//--
[228]415/* --Methode-- */
[568]416//++
[228]417float MemNoise::Noise()
[568]418//
419//--
[228]420{
421return(Avance(0));
422}
423
424/* --Methode-- */
[568]425//++
[228]426float MemNoise::Avance(long Asauter)
[568]427//
428//--
[228]429{
430int i,j;
431float boum;
[680]432float rn = 0;
[228]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]);
[2148]476 Somme = mStPos[i]/_mysqrtf(mTePos[i]);
[228]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]);
[2148]482 Somme += mStPos[j]/_mysqrtf(mTePos[j]);
[228]483 Poids += mStPos[j];
484 SbaryT += mStPos[j] * mTePos[j];
485 BaryT = SbaryT / Poids;
[2148]486 Approx = Poids / _mysqrtf(BaryT);
[228]487 Erreur = (Approx - Somme) / Somme;
[2148]488 // printf("i,j = %d %d Approx = %g \n",i,j,_myfabsf(Erreur));
[228]489 // printf("Temps,Bruit = %g %g \n",BaryT,Poids);
[2148]490 if(_myfabsf(Erreur)<epsilon)
[228]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]);
[2148]529 Somme = mStNeg[i]/_mysqrtf(mTeNeg[i]);
[228]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]);
[2148]535 Somme += mStNeg[j]/_mysqrtf(mTeNeg[j]);
[228]536 Poids += mStNeg[j];
537 SbaryT += mStNeg[j] * mTeNeg[j];
538 BaryT = SbaryT / Poids;
[2148]539 Approx = Poids / _mysqrtf(BaryT);
[228]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);
[2148]543 if(_myfabsf(Erreur)<epsilon)
[228]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 */
[680]565// $CHECK$ avec Francois - rndm() remplace par Reza 10/01/99
566// passage en drand le 1/12/99
567mduree = -mTau*log(drand01());
[228]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{
[782]591if(mTePos[i] > 1.) break; // Modif F.C et D.Y. 03/2000
[228]592rn += mStPos[i];
593indlim++;
594}
595// float ajout=0.;
[2148]596for(i=indlim; i < mMemPos-1; i++) rn += mStPos[i]/_mysqrtf(mTePos[i]);
[228]597indlim=0;
598for(i=0; i < mMemNeg-1; i++)
599{
[782]600if(mTeNeg[i] > 1.) break; // Modif F.C et D.Y. 03/2000
[228]601rn += mStNeg[i];
602indlim++;
603}
[2148]604for(i=indlim; i < mMemNeg-1; i++) rn += mStNeg[i]/_mysqrtf(mTeNeg[i]);
[228]605}
606}
607return(rn);
608}
609/* --Methode-- */
[568]610//++
[228]611int MemNoise::Print()
[568]612//
613//--
[228]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
[568]626//++
627// Class SumNoise
628//
629// include bruit.h math.h fmath.h nbrandom.h
630//
[700]631// Generateur de bruit blanc + 1/f avec fknee
632
[568]633//--
634//++
635//
636// Links Parents
637//
638// NoiseGenerator
639//
640//--
641//++
642// Titre Constructor
643//--
[228]644// Generateur de bruit blanc + 1/f avec fknee
645
646
647/* --Methode-- */
[568]648//++
[680]649SumNoise::SumNoise(float fknee, float sig, int mem, float tau)
[228]650 : NoiseGenerator(sig)
[568]651//
652//--
[228]653{
654// Reza 27/01/98 :
655// Je calcule les sigma du MemNoise d'apres la formule de Francois
[680]656// mn = new MemNoise(sig*fknee);
[2148]657// mn = new MemNoise(1.4142*sig*_mysqrtf(fknee),1,10.,1000000); // modif appel FC 13 mai 98.
[680]658mn = new MemNoise(1.4142*sig*sqrt((double)fknee),mem,tau,12000); // FC 13 mai 98. -> Reza 1/12/99
[228]659}
660
661
[568]662//++
663// Titre Destructor
664//--
[228]665/* --Methode-- */
[568]666//++
[228]667SumNoise::~SumNoise()
[568]668//
669//--
[228]670{
671delete mn;
672}
673
[568]674//++
675// Titre Public Methods
676//--
[228]677/* --Methode-- */
[568]678//++
[228]679float SumNoise::Noise()
[568]680//
681//--
[228]682{
683return(NoiseGenerator::Noise() + mn->Noise());
684}
Note: See TracBrowser for help on using the repository browser.