/* file: rrgen.c Entry number : 161 Authors : Miguel A. García-González, Juan Ramos-Castro Organization : Instrumentation and Bioengineering Division, Electronic Engineering Department, Universitat Politècnica de Catalunya Barcelona, Spain email address : magarcia at eel.upc.es This program should compile without errors or warnings using: gcc -Wall rrgen.c -lm See http://www.physionet.org/challenge/2002/ for further information on the CinC Challenge 2002. This program was used to generate series rr32 and rr34 of the challenge dataset. */ #include #include #include #define SPS 128 /* sampling frequency (determines quantization of RR intervals; see main()) */ #define PI 3.14159263 #define DIM 1024 void simcirc(int *, long, float *); void sese(int, float , float *); void moving(float *,int,int, float *); void escalado(float *,float, float ); void fillmat(float [][5],float *,int , int); float mean(float *,int); float stdv(float *,int); void prepro(float *,int); float generate(void); float bbv(float,float,float,float,float,float); float sqsig(float, float); void square(float *, float , int , float *); float randn(void); float randu(void); /**********************************/ /* GLOBAL VARIABLES ***/ float lf1; float f1; float sd1; float xrr[1024]; long tgmax; /**********************************/ /* This function is called once, before generate() is called. See main() for a description of its arguments. */ /***********************************************************************/ void initialize(long seed, long tmax) { float mrr,ddn; int mat5[5]={33,10,5,2,1}; /* Initialize global variables */ srand((unsigned int) seed); mrr=0.75+0.3*randu(); /* Mean rr */ sd1=0.07*mrr+0.04*(randu()); /* generated signal standard deviation if mean rr equals 1 second */ lf1=0.5+randu()/2.0; /* ratio related to lf/hf index */ f1=2.0+18.0*randu(); /* ratio related to determistic no deterministic data */ ddn=0.5*mrr+0.05*randu(); tgmax=tmax; simcirc(mat5 , tmax, xrr); escalado(xrr,mrr,ddn); return; } /* This function is called once per RR interval. It should return the length of the next (simulated) RR interval in seconds. */ float generate(void) { static float rr,temp,dfr,fmod,bfp,bfd,bfm,dut,ph,ts,sdf; static float t,fr=0.15,kf,ss[512],ss2[512],bar[512]; int index,k; static int lresp,kresp; index = (int) floor(t/( (long) tgmax)* ((int) DIM)); if(index>(DIM-1)) index=DIM-1; if(t>=kf){ kresp=0; if (fr > 0.35) fr=fr-0.01*randu(); if (fr < 0.18) {fr=fr+0.03*randu();} else {fr=fr+0.02*(randu()-0.5);}; lresp= (int) floor(250.0+100.0*randu()); dfr=0.01*(1.0+fabs(xrr[index]-1))*randu(); kf=t+xrr[index]*lresp; /*Fractal signal used for simulate complex behaviour */ sese(512, 1.3+0.1*randu(),ss); moving(ss,512,100,ss2); fmod=0.000*randu(); bfp=0.12*(1+0.3*(randu()-0.5)); bfd=0.003*randu(); bfm=0.07*randu(); dut=80.0+10.0*randu(); ph=PI/2.0*(1+0.1*randu()); for (k=0;k<512;k++) { ts=(t+xrr[index]*k); bar[k]=sqsig(2.0*PI*bfp*(1.0+bfd/2.0*(sin(2.0*PI*bfm*ts)+1.0))*ts+ph,dut); } moving(bar,512,1,bar); prepro(bar,512); temp=mean(bar,512); for (k=0;k<512;k++) bar[k]=bar[k]-temp; sdf=0.05*randu()+0.1; } /* Simulate non chaotic data */ temp=bbv(sd1,t,xrr[index],fr,dfr,fmod)*(3*ss2[kresp]+1); temp=temp+(pow(xrr[index],-1.5)+0.03*randu())*bar[kresp]*sd1/lf1; rr=temp*pow(xrr[index],1.5)+ss[kresp]*f1*sd1*sd1*pow(xrr[index],-1)/3+0.01*randn(); rr=rr*pow(xrr[index],2)+xrr[index]; if ((rr > 2) || (rr < 0.5)) rr=xrr[index]; t += rr; kresp++; return (rr); } /********************* Aqui pongo mi codigo ***************************/ float randn(void) /* Generador de numeros aleatorios con dist. gaussiana */ { float x1,x2,z; x1=((float) rand())/RAND_MAX; x2=((float) rand())/RAND_MAX; x1=x1+1e-10; z=sqrt(-2*log(x1))*cos(2*PI*x2); return(z); } float randu(void) /* Generador de numeros aleatorios con dist. uniforme (0-1) */ { return((float) rand()/RAND_MAX); } float mean( float *vector, int dim) /* Calcula la media del vector */ { int k; float med=0; for(k=0;kma) ma=v[k]; } for(k=0;k0.05) v[k]=(v[k-1]+v[k+1])/2.0; } v[1023]=v[1021]; v[1022]=v[1020]; return; } void simcirc(int dcd[5], long tmax, float *x) /* Genera el ritmo circadiano */ { float ct[1024][5]; float ti[1024],xf[1024],ph,pes[5]; int k,zc[5],zcp[5],pos[5],nzc=0; int i,n1,n2,j; ph=1.5*PI+PI*randu()*0.1; for(k=0;k<1024;k++) ti[k]=(PI*2.0*k*tmax/(3600.0*24.0))/1023+ph; square(ti,dcd[0]+randu(),1024,x); fillmat(ct,x,0,1024); nzc=0; for(k=0;k<1023;k++){ if(x[k]!=x[k+1]) { zcp[nzc]=1023-k; nzc++; } } for(k=0;k 2) tmax = atol(argv[2]); initialize(seed, tmax); while ((t += generate()) < tmax) { /* add RR interval to running time */ /* calculate and output a quantized RR interval */ ts = (long)(SPS*t + 0.5); printf("%5.3f\n", (ts - tsp)/((float)SPS)); tsp = ts; } exit(0); }