bpmwf/complexwf.c

Go to the documentation of this file.
00001 
00006 #include <bpm/bpm_wf.h>
00007 
00008 complexwf_t* complexwf( int ns, double fs ) {
00009   
00010   complexwf_t *w;
00011 
00012   if ( fs <= 0 ) {
00013     bpm_error( "Cannot have sampling frequency <= 0. in complexwf()",
00014                __FILE__, __LINE__ );
00015     return NULL;
00016   }
00017 
00018   if ( ns > MAX_ALLOWED_NS ) {
00019     bpm_error( "Maximum allowed number of samples exceeded, failed to allocate.",
00020                __FILE__, __LINE__ );
00021     return NULL;
00022   }
00023 
00024   if ( ns > 1 ) {
00025     w = (complexwf_t*) calloc( 1, sizeof(complexwf_t) );
00026     if ( ! w ) {
00027       bpm_error( "Cannot allocate memory for waveform structure in complexwf()",
00028                  __FILE__, __LINE__ );
00029       return NULL;
00030     }
00031     w->ns = ns;
00032     w->fs = fs;
00033     w->wf = (complex_t*) calloc( w->ns, sizeof( complex_t ) );
00034     if ( ! w->wf ) {
00035       bpm_error( "Cannot allocate memory for waveform data in complexwf()",
00036                  __FILE__, __LINE__ );
00037       free( w );
00038       return NULL;
00039     }
00040   } else {
00041     bpm_error( "Invalid number of samples in complexwf()", __FILE__, __LINE__ );
00042     return NULL;
00043   }
00044 
00045   return w;
00046 }
00047 
00048 // ----------------------------------------------------------------------------
00049 
00050 complexwf_t* complexwf_copy_new( complexwf_t *w ) {
00051   
00052   int i = 0;
00053   complexwf_t *s = complexwf( w->ns, w->fs );
00054   
00055   if ( ! s ) {
00056     bpm_error( "Cannot allocate memory in complexwf_copy_new()", __FILE__, __LINE__ );
00057     return NULL;
00058   };
00059 
00060   for ( i=0; i<w->ns; i++ ) s->wf[i] = w->wf[i];
00061 
00062   return s;
00063 }
00064 
00065 // ----------------------------------------------------------------------------
00066 
00067 int complexwf_copy( complexwf_t *copy, complexwf_t *src ) {
00068   
00069   int i = 0;
00070 
00071   if ( ! copy || ! src ) {
00072     bpm_error( "Invalid pointer arguments in complexwf_copy()", __FILE__, __LINE__ );
00073     return BPM_FAILURE;
00074   };
00075 
00076   if ( complexwf_compat( copy, src ) ) {
00077     for ( i=0; i<copy->ns; i++ ) copy->wf[i] = src->wf[i];
00078   } else {
00079     bpm_error( "Incompatible waveforms for in complexwf_copy()", __FILE__, __LINE__ );
00080     return BPM_FAILURE;
00081   }
00082 
00083   return BPM_SUCCESS;
00084 }
00085 
00086 // ----------------------------------------------------------------------------
00087 
00088 int complexwf_subset( complexwf_t *sub, complexwf_t *w, int i1, int i2 ) {
00089   
00090   int i = 0;
00091 
00092   if ( ! sub || ! w ) {
00093     bpm_error( "Invalid pointer arguments in complexwf_subset()", __FILE__, __LINE__ );
00094     return BPM_FAILURE;
00095   };
00096 
00097   // reset the number of samples in the subset
00098   sub->ns = 0;
00099   sub->fs = w->fs;
00100 
00101   for ( i=MAX(0,i1); i<=MIN(w->ns-1,i2); i++ ) {
00102     sub->wf[i] = w->wf[i-i1];
00103     sub->ns++;
00104   }
00105 
00106 
00107   return BPM_SUCCESS;
00108 }
00109 
00110 // ----------------------------------------------------------------------------
00111 
00112 int complexwf_setvalues( complexwf_t *w, complex_t *x ) {
00113 
00114   int i = 0;
00115   if ( ! w || ! x ) {
00116     bpm_error( "Invalid pointer arguments in complexwf_setvalues()",
00117                __FILE__, __LINE__ );
00118     return BPM_FAILURE;
00119   }
00120 
00121   for ( i=0; i<w->ns; i++ ) w->wf[i] = x[i];
00122 
00123   return BPM_SUCCESS;
00124 }
00125 // ----------------------------------------------------------------------------
00126 
00127 int complexwf_setfunction( complexwf_t *w, 
00128                            complex_t (*wffun)( double, int, double* ),
00129                            int npars, double *par ) {
00130   
00131   int i = 0;
00132   if ( ! w || ! wffun ) {
00133     bpm_error( "Invalid pointer arguments in complexwf_setfunction()",
00134                __FILE__, __LINE__ );
00135     return BPM_FAILURE;
00136   }
00137 
00138   for ( i=0; i<w->ns; i++ ) w->wf[i] = (*wffun)( (double) i / w->fs, npars, par );
00139 
00140   return BPM_SUCCESS;
00141 }
00142 
00143 // ----------------------------------------------------------------------------
00144 
00145 int complexwf_reset( complexwf_t *w ) {
00146 
00147   int i = 0;
00148 
00149   if ( ! w  ) {
00150     bpm_error( "Invalid pointer argument in complexwf_reset()", 
00151                __FILE__, __LINE__ );
00152     return BPM_FAILURE;
00153   }
00154 
00155   for ( i=0; i<w->ns; i++ ) w->wf[i] = complex( 0., 0. );
00156 
00157   return BPM_SUCCESS;
00158 }
00159 
00160 // ----------------------------------------------------------------------------
00161 
00162 void complexwf_delete( complexwf_t *w ) {
00163 
00164   if ( w ) {
00165     if ( w->wf ) free( w->wf ); else
00166       bpm_warning( "Cannot free complexwf_t::wf pointer in complexwf()_delete, already NULL !",
00167                    __FILE__, __LINE__ );
00168     free( w );
00169   } else {
00170     bpm_warning( "Cannot free complexwf_t pointer in complexwf()_delete, already NULL !", 
00171                  __FILE__, __LINE__ );
00172   }
00173   
00174   return;
00175 }
00176 
00177 // ----------------------------------------------------------------------------
00178 
00179 int complexwf_compat( complexwf_t *w1, complexwf_t *w2 ) {
00180 
00181   if ( ! w1 || ! w2 ) {
00182     bpm_error( "Invalid pointer arguments in doublewf_compat()", 
00183                __FILE__, __LINE__ );
00184     return 0;
00185   }
00186   
00187   return ((w1->ns==w2->ns)&&(fabs(w1->fs-w2->fs)<WF_EPS)?1:0);
00188 }
00189 
00190 // ----------------------------------------------------------------------------
00191 
00192 int complexwf_add( complexwf_t *w1, complexwf_t *w2 ) {
00193 
00194   int i = 0;
00195 
00196   if ( ! w1 || ! w2 ) {
00197     bpm_error( "Invalid pointer arguments in complexwf_add()", 
00198                __FILE__, __LINE__ );
00199     return BPM_FAILURE;
00200   }
00201 
00202   if ( ! complexwf_compat( w1, w2 ) ) {
00203     bpm_warning( "Incompatible waveforms in complexwf_add()", __FILE__, __LINE__ );
00204   }
00205   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] = c_sum( w1->wf[i], w2->wf[i] );
00206   
00207   return BPM_SUCCESS;
00208 }
00209 
00210 // ----------------------------------------------------------------------------
00211 
00212 int complexwf_subtract( complexwf_t *w1, complexwf_t *w2 ) {
00213   
00214   int i = 0;
00215   
00216   if ( ! w1 || ! w2 ) {
00217     bpm_error( "Invalid pointer arguments in complexwf_subtract()", 
00218                __FILE__, __LINE__ );
00219     return BPM_FAILURE;
00220   }
00221 
00222   if ( ! complexwf_compat( w1, w2 ) ) {
00223     bpm_warning( "Incompatible waveforms in complexwf_subtract()", __FILE__, __LINE__ );
00224   }
00225 
00226   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] = c_diff( w1->wf[i], w2->wf[i] );
00227   
00228   return BPM_SUCCESS;
00229 }
00230 
00231 // ----------------------------------------------------------------------------
00232 
00233 int complexwf_multiply( complexwf_t *w1, complexwf_t *w2 ) {
00234 
00235   int i = 0;
00236   
00237   if ( ! w1 || ! w2 ) {
00238     bpm_error( "Invalid pointer arguments in complexwf_multiply()", 
00239                __FILE__, __LINE__ );
00240     return BPM_FAILURE;
00241   }
00242 
00243   if ( ! complexwf_compat( w1, w2 ) ) {
00244     bpm_warning( "Incompatible waveforms in complexwf_multiply()", 
00245                  __FILE__, __LINE__ );
00246   }
00247 
00248   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] = c_mult( w1->wf[i], w2->wf[i] );
00249   
00250   return BPM_SUCCESS;
00251 }
00252 
00253 // ----------------------------------------------------------------------------
00254 
00255 int complexwf_divide( complexwf_t *w1, complexwf_t *w2 ) {
00256   
00257   int i = 0;
00258   
00259   if ( ! w1 || ! w2 ) {
00260     bpm_error( "Invalid pointer arguments in complexwf_divide()", 
00261                __FILE__, __LINE__ );
00262     return BPM_FAILURE;
00263   }
00264 
00265   if ( ! complexwf_compat( w1, w2 ) ) {
00266     bpm_warning( "Incompatible waveforms in complexwf_divide()", 
00267                  __FILE__, __LINE__ );
00268   }
00269 
00270   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) {
00271 
00272     if ( c_isequal( w2->wf[i], complex( 0., 0. ) ) ) {
00273       bpm_warning( "Trapped division by 0+0i in complexwf_divide()", 
00274                    __FILE__, __LINE__ );
00275       w1->wf[i] = complex(0.,0.);
00276     } else {
00277       w1->wf[i] = c_div( w1->wf[i], w2->wf[i] );
00278     } 
00279     
00280   } 
00281 
00282   return BPM_SUCCESS;
00283 }
00284 
00285 // ----------------------------------------------------------------------------
00286 
00287 int complexwf_scale( complex_t f, complexwf_t *w ) {
00288 
00289   int i = 0;
00290   
00291   if ( ! w ) {
00292     bpm_error( "Invalid pointer argument in complexwf_scale()", 
00293                __FILE__, __LINE__ );
00294     return BPM_FAILURE;
00295   }
00296 
00297   for ( i=0; i<w->ns; i++ ) w->wf[i] = c_mult( f, w->wf[i] );
00298 
00299   return BPM_SUCCESS;
00300 }
00301 
00302 // ----------------------------------------------------------------------------
00303 
00304 int complexwf_bias( complex_t c, complexwf_t *w ) {
00305 
00306   int i = 0;
00307   
00308   if ( ! w ) {
00309     bpm_error( "Invalid pointer argument in complexwf_bias()", 
00310                __FILE__, __LINE__ );
00311     return BPM_FAILURE;
00312   }
00313 
00314   for ( i=0; i<w->ns; i++ ) w->wf[i] = c_sum( c, w->wf[i] );
00315 
00316   return BPM_SUCCESS;
00317 }
00318 
00319 // ----------------------------------------------------------------------------
00320 
00321 int complexwf_add_cwtone( complexwf_t *w, double amp, double phase, double freq,
00322                          double phasenoise ) {
00323   
00324   int i = 0;
00325   
00326   if ( ! w ) {
00327     bpm_error( "Invalid pointer argument in complexwf_add_cwtone()", 
00328                __FILE__, __LINE__ );
00329     return BPM_FAILURE;
00330   }
00331 
00332   for (i=0; i<w->ns; i++ ) {
00333     w->wf[i].re += amp * cos( 2. * PI * freq * (double) i /  w->fs + 
00334                               nr_rangauss( phase, phasenoise ) );
00335     
00336     w->wf[i].im += amp * sin( 2. * PI * freq * (double) i /  w->fs + 
00337                               nr_rangauss( phase, phasenoise ) );
00338   }
00339 
00340   return BPM_SUCCESS;
00341 }
00342 
00343 // ----------------------------------------------------------------------------
00344 
00345 int complexwf_add_dcywave( complexwf_t *w, double amp, double phase, double freq, 
00346                            double ttrig, double tdcy, double phasenoise ) {
00347 
00348   int    i = 0;
00349   double t = 0.;
00350 
00351   if ( ! w ) {
00352     bpm_error( "Invalid pointer argument in complexwf_add_dcywave()", 
00353                __FILE__, __LINE__ );
00354     return BPM_FAILURE;
00355   }
00356   
00357   for (i=0; i<w->ns; i++ ) {
00358     t = (double) i / w->fs;
00359     if ( t >= ttrig ) {
00360       w->wf[i].re += amp * exp( -( t - ttrig ) / tdcy ) * 
00361         cos( 2. * PI * freq * ( t - ttrig ) + nr_rangauss( phase, phasenoise ) );
00362       w->wf[i].im += amp * exp( -( t - ttrig ) / tdcy ) * 
00363         sin( 2. * PI * freq * ( t - ttrig ) + nr_rangauss( phase, phasenoise ) );
00364     }
00365   }
00366 
00367   return BPM_SUCCESS;
00368 }
00369 
00370 // ----------------------------------------------------------------------------
00371 
00372 int complexwf_add_noise( complexwf_t *w, double sigma ) {
00373   
00374   int i = 0;
00375   double amp, phase;
00376 
00377   if ( ! w ) {
00378     bpm_error( "Invalid pointer argument in complexwf_add_noise()", 
00379                __FILE__, __LINE__ );
00380     return BPM_FAILURE;
00381   }
00382 
00383   for (i=0; i<w->ns; i++ ) {
00384     amp   = nr_rangauss( 0., sigma );
00385     phase = nr_ranuniform( 0., 2*PI );
00386 
00387     w->wf[i] = c_sum( w->wf[i], complex( amp*cos(phase), amp*sin(phase) ) );
00388   }
00389   
00390   return BPM_SUCCESS;
00391 
00392 }
00393 
00394 // ----------------------------------------------------------------------------
00395 
00396 int complexwf_add_ampnoise( complexwf_t *w, double sigma ) {
00397   
00398   int i = 0;
00399   double amp, phase;
00400 
00401   if ( ! w ) {
00402     bpm_error( "Invalid pointer argument in complexwf_add_ampnoise()", 
00403                __FILE__, __LINE__ );
00404     return BPM_FAILURE;
00405   }
00406 
00407   for (i=0; i<w->ns; i++ ) {
00408     amp   = nr_rangauss( c_abs( w->wf[i]), sigma );
00409     phase = c_arg( w->wf[i] );
00410 
00411     w->wf[i] = complex( amp * cos( phase ), amp * sin( phase ) );
00412   }
00413 
00414   return BPM_SUCCESS;
00415 
00416 }
00417 
00418 // ----------------------------------------------------------------------------
00419 
00420 int complexwf_add_phasenoise( complexwf_t *w, double sigma ) {
00421   
00422   int i = 0;
00423   double amp, phase;
00424 
00425   if ( ! w ) {
00426     bpm_error( "Invalid pointer argument in complexwf_add_phasenoise()", 
00427                __FILE__, __LINE__ );
00428     return BPM_FAILURE;
00429   }
00430 
00431   for (i=0; i<w->ns; i++ ) {
00432     amp      = c_abs( w->wf[i] ); 
00433     phase    = nr_rangauss( c_arg( w->wf[i]), sigma );
00434 
00435     w->wf[i] = complex( amp * cos( phase ), amp * sin( phase ) );
00436   }
00437 
00438   return BPM_SUCCESS;
00439 
00440 }
00441 
00442 
00443 // ----------------------------------------------------------------------------
00444 
00445 void complexwf_print( FILE *of, complexwf_t *w ) {
00446   
00447   int i = 0;
00448   if ( !of || !w ) {
00449     bpm_error( "Invalid pointers in comlexwf_print()", __FILE__, __LINE__ );
00450     return;
00451   }
00452   
00453   fprintf( of, "Waveform:\n" );
00454   fprintf( of, "Number of samples  : %d\n",     w->ns );
00455   fprintf( of, "Sampling frequency : %f MHz\n", w->fs / MHz );
00456   for( i = 0; i < w->ns; i++ )  fprintf( of, "  wf[%5d] = %.14e + i %.14e \n", 
00457                                          i, w->wf[i].re, w->wf[i].im );
00458   fflush( of );
00459 
00460   return;
00461 }
00462 
00463 // ----------------------------------------------------------------------------
00464 
00465 int complexwf_getreal( doublewf_t *re, complexwf_t *z ) {
00466   
00467   int i = 0;
00468 
00469   if ( ! re || ! z ) {
00470     bpm_error( "Invalid pointer argument in complexwf_getreal()", 
00471                __FILE__, __LINE__ );
00472     return BPM_FAILURE;
00473   }
00474 
00475   if ( re->ns != z->ns ) {
00476     bpm_warning( "Different number of samples in complex_getreal()",
00477                  __FILE__, __LINE__ );
00478   }
00479   
00480   for ( i=0; i < MIN(re->ns,z->ns); i++ ) re->wf[i] = z->wf[i].re;  
00481 
00482   return BPM_SUCCESS;
00483 }
00484 
00485 // ----------------------------------------------------------------------------
00486 
00487 int complexwf_getimag( doublewf_t *im, complexwf_t *z ) {
00488   
00489   int i = 0;
00490 
00491   if ( ! im || ! z ) {
00492     bpm_error( "Invalid pointer argument in complexwf_getimag()", 
00493                __FILE__, __LINE__ );
00494     return BPM_FAILURE;
00495   }
00496 
00497   if ( im->ns != z->ns ) {
00498     bpm_warning( "Different number of samples in complex_getimag()",
00499                  __FILE__, __LINE__ );
00500   }
00501   
00502   for ( i=0; i < MIN(im->ns,z->ns); i++ ) im->wf[i] = z->wf[i].im;  
00503 
00504   return BPM_SUCCESS;
00505 }
00506 
00507 // ----------------------------------------------------------------------------
00508 
00509 int complexwf_getamp( doublewf_t *r, complexwf_t *z ) {
00510   
00511   int i = 0;
00512 
00513   if ( ! r || ! z ) {
00514     bpm_error( "Invalid pointer argument in complexwf_getamp()", 
00515                __FILE__, __LINE__ );
00516     return BPM_FAILURE;
00517   }
00518 
00519   if ( r->ns != z->ns ) {
00520     bpm_warning( "Different number of samples in complex_getamp()",
00521                  __FILE__, __LINE__ );
00522   }
00523   
00524   for ( i=0; i < MIN(r->ns,z->ns); i++ ) r->wf[i] = c_abs( z->wf[i] );  
00525 
00526   return BPM_SUCCESS;
00527 }
00528 
00529 // ----------------------------------------------------------------------------
00530 
00531 int complexwf_getphase( doublewf_t *theta, complexwf_t *z ) {
00532   
00533   int i = 0;
00534 
00535   if ( ! theta || ! z ) {
00536     bpm_error( "Invalid pointer argument in complexwf_getphase()", 
00537                __FILE__, __LINE__ );
00538     return BPM_FAILURE;
00539   }
00540 
00541   if ( theta->ns != z->ns ) {
00542     bpm_warning( "Different number of samples in complexwf_getphase()",
00543                  __FILE__, __LINE__ );
00544   }
00545   
00546   for ( i=0; i < MIN(theta->ns,z->ns); i++ ) theta->wf[i] = c_arg( z->wf[i] );  
00547 
00548   return BPM_SUCCESS;
00549 }
00550 
00551 // ----------------------------------------------------------------------------
00552 
00553 int complexwf_setreal( complexwf_t *z, doublewf_t *re ){
00554 
00555   int i = 0;
00556 
00557   if ( ! re || ! z ) {
00558     bpm_error( "Invalid pointer argument in complexwf_setreal()", 
00559                __FILE__, __LINE__ );
00560     return BPM_FAILURE;
00561   }
00562 
00563   if ( re->ns != z->ns ) {
00564     bpm_warning( "Different number of samples in complexwf_setreal()",
00565                  __FILE__, __LINE__ );
00566   }
00567 
00568   for ( i=0; i < MIN(re->ns,z->ns); i++ ) z->wf[i].re = re->wf[i];
00569   
00570   return BPM_SUCCESS;
00571 }
00572 
00573 // ----------------------------------------------------------------------------
00574 
00575 int complexwf_setimag( complexwf_t *z, doublewf_t *im ){
00576 
00577   int i = 0;
00578 
00579   if ( ! im || ! z ) {
00580     bpm_error( "Invalid pointer argument in complexwf_setreal()", 
00581                __FILE__, __LINE__ );
00582     return BPM_FAILURE;
00583   }
00584   
00585   if ( im->ns != z->ns ) {
00586     bpm_warning( "Different number of samples in complexwf_setreal()",
00587                  __FILE__, __LINE__ );
00588   }
00589   
00590   for ( i=0; i < MIN(im->ns,z->ns); i++ ) z->wf[i].im = im->wf[i];
00591   
00592   return BPM_SUCCESS;
00593 }
00594 
00595 // ----------------------------------------------------------------------------
00596 
00597 doublewf_t* complexwf_getreal_new( complexwf_t *z ) {
00598 
00599   int i = 0;
00600   doublewf_t *w = NULL;
00601 
00602   if ( ! z ) {
00603     bpm_error( "Invalid pointer argument in complexwf_getreal_new()",
00604                __FILE__, __LINE__ );
00605     return NULL;
00606   }
00607 
00608   w = doublewf( z->ns, z->fs );
00609   if ( ! w ) {
00610     bpm_error( "Unable to allocate memory for waveform in complex_getreal_new()",
00611                __FILE__, __LINE__ );
00612     return NULL;
00613   }
00614 
00615   for (i=0;i<z->ns;i++) w->wf[i] = z->wf[i].re;
00616 
00617   return w;
00618 }
00619 
00620 // ----------------------------------------------------------------------------
00621 
00622 doublewf_t* complexwf_getimag_new( complexwf_t *z ) {
00623 
00624   int i = 0;
00625   doublewf_t *w = NULL;
00626 
00627   if ( ! z ) {
00628     bpm_error( "Invalid pointer argument in complexwf_getimag_new()",
00629                __FILE__, __LINE__ );
00630     return NULL;
00631   }
00632 
00633   w = doublewf( z->ns, z->fs );
00634   if ( ! w ) {
00635     bpm_error( "Unable to allocate memory for waveform in complex_getimag_new()",
00636                __FILE__, __LINE__ );
00637     return NULL;
00638   }
00639 
00640   for (i=0;i<z->ns;i++) w->wf[i] = z->wf[i].im;
00641 
00642   return w;
00643 }
00644 
00645 // ----------------------------------------------------------------------------
00646 
00647 doublewf_t* complexwf_getamp_new( complexwf_t *z ) {
00648 
00649   int i = 0;
00650   doublewf_t *w = NULL;
00651 
00652   if ( ! z ) {
00653     bpm_error( "Invalid pointer argument in complexwf_getamp_new()",
00654                __FILE__, __LINE__ );
00655     return NULL;
00656   }
00657 
00658   w = doublewf( z->ns, z->fs );
00659   if ( ! w ) {
00660     bpm_error( "Unable to allocate memory for waveform in complex_getamp_new()",
00661                __FILE__, __LINE__ );
00662     return NULL;
00663   }
00664 
00665   for (i=0;i<z->ns;i++) w->wf[i] = c_abs( z->wf[i] );
00666 
00667   return w;
00668 }
00669 
00670 // ----------------------------------------------------------------------------
00671 
00672 doublewf_t* complexwf_getphase_new( complexwf_t *z ) {
00673 
00674   int i = 0;
00675   doublewf_t *w = NULL;
00676 
00677   if ( ! z ) {
00678     bpm_error( "Invalid pointer argument in complexwf_getphase_new()",
00679                __FILE__, __LINE__ );
00680     return NULL;
00681   }
00682 
00683   w = doublewf( z->ns, z->fs );
00684   if ( ! w ) {
00685     bpm_error( "Unable to allocate memory for waveform in complex_getphase_new()",
00686                __FILE__, __LINE__ );
00687     return NULL;
00688   }
00689 
00690   for (i=0;i<z->ns;i++) w->wf[i] = c_arg( z->wf[i] );
00691 
00692   return w;
00693 }
00694 
00695 

Generated on Thu Jan 10 10:18:04 2008 for libbpm by  doxygen 1.5.1