Пример #1
0
/*! \brief Initialization.
 *
 * Number of bins must be adjusted depending on filter stabilization :
 * \f[ NbDataStab= 2 \cdot  NbData + NbDataStab_{NFilter} + Max(size(\alpha_{NFilter}),size(\beta_{NFilter})) \f]
 * #WhiteData size and #NoiseData size are set to NbDataStab.
 *
 * WhiteData is  generated as a standard gaussian :
 * \f[  \textrm{ for i=0,\dots,Startbin } WhiteData[i] = \sqrt{-\frac{log(r1)}{tStep} \cdot cos(2 \cdot \pi \cdot r1)} \f]
 *  where r1 and r2 are random values between 0 and 1 (using #genunf).
 * 
 * Noise data are generated using Filter::App method with  StartBin, WhiteData, and NoiseData arguments.\n
 * Then last data are deleted : #WhiteData size and #NoiseData size are set to #NbData.
 *
 */
void NoiseOof::loadNoise()
{
	int NbDataStab(2*NbData + NFilter.getNbDataStab() + NFilter.getDepth()); //More bin that necessary for stabilization of the filter
    int StartBin(NbDataStab-NFilter.getDepth());
	//cout << "  - NbDataStab = " << NbDataStab << endl;
	WhiteData.resize(NbDataStab, 0.0);
	NoiseData.resize(NbDataStab, 0.0);
	
    // Generation of all data for white noise
    double r1(0.0), r2(0.0);
    for(int i=0; i<StartBin; i++){
        //r1 = (double)rand()/RAND_MAX;
        //r2 = (double)rand()/RAND_MAX;

        r1 = (double)genunf(0.0, 1.0);
        r2 = (double)genunf(0.0, 1.0);
		//WhiteData[i] = tStep*sqrt(-2.0*log(r2))*cos(2*M_PI*r1);
		WhiteData[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
		//WhiteData[i] = 1.0;
    }
    
	// Generation of all noise data by filtering
	NFilter.App(StartBin, WhiteData, NoiseData);
    
	// Delete of last data in excess
    WhiteData.resize(NbData);
    NoiseData.resize(NbData);
	//cout << "  NbData = " << NbData << endl;
	//cout << "  NbBinAdd = " << NbBinAdd << endl;
	/*for(int i=0; i<NbData; i++){
		cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << endl;
	}*/
}
Пример #2
0
void sim_pois(double *intensity,
	      long *npts,
	      double *l1,
	      double *l2,
	      long *N,
	      long *M,
	      double *spp)
{
  int i,j,k,l;
  double maxint,u,pitch[2];
  
  /*
  printf("Simulating inhomogeneous Poisson process with %d points.\n",*npts);
  */
  pitch[0]=*l1/(*M);
  pitch[1]=*l2/(*N);
  maxint=intensity[0];
  /* maxx=pitch[0]/2.0; maxy=pitch[1]/2.0;*/
  for (i=0; i<*N; i++)
    for (j=0; j<*M; j++)
      if (intensity[i*(*M)+j]>maxint) {
	maxint=intensity[i*(*M)+j];
      }

  for (i=0; i<*npts; i++) {
    do {
      spp[2*i]=genunf(0,*l1);
      spp[2*i+1]=genunf(0,*l2);
      u=genunf(0,1);
      k=(int)(floor(spp[2*i]/pitch[0]));
      l=(int)(floor(spp[2*i+1]/pitch[1]));
    } while ((u>=intensity[l*(*M)+k]/maxint) || (k>=128) || (l>=128));

  }
}
/*! \brief Initialization.
 *
 * Number of bins must be adjusted depending on filter stabilization :
 * \f[ NbDataStab= 2 \cdot  NbData + NbDataStab_{NFilter} + Max(size(\alpha_{NFilter}),size(\beta_{NFilter})) \f]
 * #WhiteData size and #NoiseData size are set to NbDataStab.
 *
 * WhiteData is  generated as a standard gaussian :
 * \f[  \textrm{ for i=0,\dots,Startbin } WhiteData[i] = \sqrt{-\frac{log(r1)}{tStep} \cdot cos(2 \cdot \pi \cdot r1)} \f]
 *  where r1 and r2 are random values between 0 and 1 (using #genunf).
 * 
 * Noise data are generated using Filter::App method with  StartBin, WhiteData, and NoiseData arguments.\n
 * Then last data are deleted : #WhiteData size and #NoiseData size are set to #NbData.
 *
 */
void NoiseTwoFilter::loadNoise()
{
	int NbDataStab(2*NbData + NFilter.getNbDataStab() + NFilter.getDepth()); //More bin that necessary for stabilization of the filter
    int StartBin(NbDataStab-MAX(NFilter.getDepth(),NFilter_2.getDepth()));
    int order_ep=3;//=0,1,2,ou 3 (3=1+2) 
	//cout << "  - NbDataStab = " << NbDataStab << endl;
	WhiteData.resize(NbDataStab, 0.0);
	WhiteData2.resize(NbDataStab, 0.0);
	NoiseData.resize(NbDataStab, 0.0);
	NoiseData_tmp1.resize(NbDataStab, 0.0);
	NoiseData_tmp2.resize(NbDataStab, 0.0);
	
    // Generation of all data for white noise
    double r1(0.0), r2(0.0);
    for(int i=0; i<StartBin; i++){
      
      r1 = (double)genunf(0.0, 1.0);
      r2 = (double)genunf(0.0, 1.0);
      WhiteData[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
      r1 = (double)genunf(0.0, 1.0);
      r2 = (double)genunf(0.0, 1.0);
      WhiteData2[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
      //WhiteData[i] = 1.0;
    }
    
    // Generation of all noise data by filtering
    //cout << endl << "loadNoise : The noise is filtered with Filter_MLDC (in LISACode_NoiseTwoFilter.cpp)" << endl ;
    NFilter.App(StartBin, WhiteData, NoiseData_tmp1);
    NFilter_2.App(StartBin, WhiteData2, NoiseData_tmp2);
    /*    for(int i=0; i<10; i++){
      cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData_tmp[i] << "     " << NoiseData[i] << endl;
      }*/
    
    if(order_ep == 1){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp1[i] ; 
      }
    }      
    if(order_ep == 2){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp2[i] ; 
      }
    }      
    if(order_ep == 3){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp1[i] + NoiseData_tmp2[i] ;
      }
    }
    // Delete of last data in excess
    WhiteData.resize(NbData);
    WhiteData2.resize(NbData);
    NoiseData_tmp1.resize(NbData);
    NoiseData_tmp2.resize(NbData);
    //cout << "  NbData = " << NbData << endl;
    //cout << "  NbBinAdd = " << NbBinAdd << endl; 
    /*for(int i=0; i<NbData; i++){
      cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << endl;
      }*/
}
Пример #4
0
static int runif_rng (lua_State *L) {
  nl_RNG *r = getrng(L);
  lua_Number low = luaL_optnumber(L, 1, 0);
  lua_Number high = luaL_optnumber(L, 2, 1);
  if (low > high)
    luaL_error(L, "inconsistent parameters: %f > %f", low, high);
  if (low == 0 && high == 1)
    setdeviate(number, ranf(r), 3);
  else
    setdeviate(number, genunf(r, low, high), 3);
  return 1;
}
Пример #5
0
/*L:lqp_sample_val*
________________________________________________________________

		lqp_sample_val
________________________________________________________________

Name:		lqp_sample_val
Syntax:		
Description:
Side effects:   
Return value:   None
Global or static variables used: None
Example:
Linking:
Bugs:
Author:		Geir Storvik, UiO
Date:
Source file: Cvs: $
________________________________________________________________
*/
static int lqp_sample_val(int i_m,double *i_knots,double i_fopt,double *i_par,
			  double (*i_log_f)(double,double *),
			  double **i_coef,double *i_prob,double i_max_r,
			  double *o_x,double *o_lacc)
{
  int     i;
  double  u,p,a,b,c,beta,x,x_opt,max_r,e,r,f;
 
  /* Convert probabilities to cummulative ones */
  for(i=1;i<=i_m;i++)
    i_prob[i] = i_prob[i-1] + i_prob[i];
  /* Sample intervall */
  u = genunf(G_ZERO,i_prob[i_m]);
  i=0;
  while(u > i_prob[i])
    i++;
  /* Sample inside intervall */
  if(i==0)
    p = i_prob[i]/i_prob[i_m];
  else
      p = (i_prob[i]-i_prob[i-1])/i_prob[i_m];
  a = i_coef[i][0];
  b = i_coef[i][1];
  c = i_coef[i][2]-log(p);
  if(i==0)
    {
      /* Exact sampling */
      u = genunf(G_ZERO,G_ONE);
      x = i_knots[0]+log(u)/b;
    }
  else if(i<i_m)
    {
      /* Rejection sampling using exponential approximation */
      beta = a*(i_knots[i-1]+i_knots[i])+b;
      x_opt = G_HALF*(beta-b)/a;
      max_r = (a*x_opt+b-beta)*x_opt;
      e = exp(beta*(i_knots[i]-i_knots[i-1]))-G_ONE;
      u = genunf(G_ZERO,G_ONE);
      x = i_knots[i-1]+log(G_ONE+u*e)/beta;
      r = (a*x+b-beta)*x;
      while(genunf(G_ZERO,G_ONE)>exp(r-max_r))
	{
	  u = genunf(G_ZERO,G_ONE);
	  x = i_knots[i-1]+log(G_ONE+u*e)/beta;
	  r = (a*x+b-beta)*x;
	}
    }
  else
    {
      /* Exact sampling */
      u = genunf(G_ZERO,G_ONE);
      x = i_knots[i-1]+log(G_ONE+u)/b;
    }

  *o_x = x;
  c = i_coef[i][2];
  f = log_f_ratio(x,i_fopt,i_log_f,i_par,a,b,c);
  *o_lacc = f+log(i_prob[i_m]);
  return(0);
}		/* end of lqp_sample_val */
Пример #6
0
void NoiseOof::generNoise(int StartBin)
{
    double r1(0.0), r2(0.0);
	WhiteData.insert(WhiteData.begin(), NbBinAdd, 0.0);
	/*cout << " Avant bruit :" << endl;
	for(int i=0; i<10; i++){
		cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << endl;
	}*/
	// Generation of white noise
	for(int i=StartBin; i>=0; i--){
        //r1 = (double)rand()/RAND_MAX;
        //r2 = (double)rand()/RAND_MAX;
		r1 = (double)genunf(0.0, 1.0);
        r2 = (double)genunf(0.0, 1.0);
        //WhiteData[i] = tStep*sqrt(-2.0*log(r2))*cos(2*M_PI*r1);
		WhiteData[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
	}
	/*cout << " Avant filtrage :" << endl;
	for(int i=0; i<10; i++){
		cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << endl;
	}*/
    // Generation of noise data by filtering
	NFilter.App(StartBin, WhiteData, NoiseData);
	
	/*cout << " Apres filtrage :" << endl;
	for(int i=0; i<10; i++){
		cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << endl;
	}*/
	
    // Delete of last data
    WhiteData.resize(NbData);
    /*for(int i=0; i<NbData; i++){
		cout << "   i,noisedata = " << i << "  " << NoiseData[i] << endl;
	}
	throw;*/
}
Пример #7
0
int sample_lambda_prior_COST(Data_COST *i_D_COST)
{
  int i,h,T,num;
  double sumLambda,sumLogLambda;
  double c_new,c_old,log_new,log_old,accProb,u;
  double e = 0.001;
  double f = 0.001;
  double fac = 0.01;

  sumLambda = G_ZERO;
  sumLogLambda = G_ZERO;
  for(h=0;h<i_D_COST->mland->n_trip;h++)
    {
      sumLambda += i_D_COST->mland->lambda[h];
      sumLogLambda += log(i_D_COST->mland->lambda[h]);
    }
  T = i_D_COST->mland->n_trip;

  num=1000;
  c_old = i_D_COST->mland->c;
  for(i=0;i<num;i++)
    {
      c_new = scale_proposal(c_old,fac,NULL);
      
      log_new = -T*log(exp(gammln(c_new))) + (c_new-1)*sumLogLambda
	         +log(exp(gammln(e+c_new*T))) - (e+c_new*T)*log(f+sumLambda);
      log_old = -T*log(exp(gammln(c_old))) + (c_old-1)*sumLogLambda
	         +log(exp(gammln(e+c_old*T))) - (e+c_old*T)*log(f+sumLambda);
      accProb = log_new - log_old;
      u = genunf(G_ZERO,G_ONE);
      if(accProb > -1.0e32 && accProb < 1.0e32 && log(u) < accProb)
	c_old = c_new;
    }
  i_D_COST->mland->c = c_old;

  i_D_COST->mland->d = gengam(f+sumLambda,e+i_D_COST->mland->c*T);

  return(0);
}		/* end of sample_lambda_prior_COST */
void NoiseTwoFilter::generNoise(int StartBin)
{
    double r1(0.0), r2(0.0); 
    int print_ep=0 ;
    int order_ep=3;//=0,1,2,ou 3 (3=1+2) 

    WhiteData.insert(WhiteData.begin(), NbBinAdd, 0.0);
    WhiteData2.insert(WhiteData2.begin(), NbBinAdd, 0.0);
    //    cout << "GenerNoise : startbin,nbBinAdd"   << "   " << StartBin << "   " << NbBinAdd << endl;
    // Generation of white noise
    for(int i=StartBin; i>=0; i--){
      r1 = (double)genunf(0.0, 1.0);
      r2 = (double)genunf(0.0, 1.0);
      WhiteData[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
      r1 = (double)genunf(0.0, 1.0);
      r2 = (double)genunf(0.0, 1.0);
      WhiteData2[i] = sqrt(-1.0*log(r2)/tStep)*cos(2*M_PI*r1);
    }
    if(print_ep != 0){
      cout << " Avant filtrage EP, order_ep :" << order_ep  << endl;
      cout << " i, whitenoise, NoiseData, tmp1, tmp2 " << endl ;
      for(int i=0; i<10; i++){
	cout << "   i = " << i << " :   " << WhiteData[i] << "     " << NoiseData[i] << "     " << NoiseData_tmp1[i] << "     " << NoiseData_tmp2[i] << endl;
      }
    }
    // Generation of noise data by filtering

    if(order_ep == 1 || order_ep == 3){  // 1/f
      NFilter.App(StartBin, WhiteData, NoiseData_tmp1);  // generates 1/f noise
      if(print_ep != 0){
	cout << " Apres  filtrage 1/f : order_ep :" << order_ep << endl;
	for(int i=0; i<10; i++){
	  cout << "   i = " << i << " :   " <<WhiteData[i] << " :   " << NoiseData_tmp1[i] << endl;
	}
      }
    }
    if(order_ep >= 2){ // 1/f≤
      NFilter_2.App(StartBin, WhiteData2, NoiseData_tmp2);  // should generate 1/f≤ noise
      if(print_ep != 0){
	cout << " Apres 1er filtrage 1/f≤, order_ep :" << order_ep  << endl;
	for(int i=0; i<10; i++){
	  cout << "   i = " << i << " :   " << WhiteData2[i] << "     " << NoiseData_tmp2[i]  << endl;
	}
      }
    }
    if(order_ep == 1){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp1[i] ; 
      }
    }      
    if(order_ep == 2){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp2[i] ; 
      }
    }      
    if(order_ep == 3){
      for(int i=StartBin; i>=0; i--){
	NoiseData[i] = NoiseData_tmp1[i] + NoiseData_tmp2[i] ;
      }
      if(print_ep != 0){
	cout << " On ajoute 1/f + 1/f≤, order_ep :" << order_ep  << endl;
	for(int i=0; i<10; i++){
	  cout << "   i = " << i << " :   " << NoiseData[i] << endl;
	}
      }
    }    
    // Delete of last data
    WhiteData.resize(NbData);
    WhiteData2.resize(NbData);
    //    NoiseData_tmp.resize(NbData);
    //	throw invalid_argument("NoiseTwoFilter : Eric a arrete le programe en 1 !");
}
Пример #9
0
/*int CHOOSE_NEW_VENT(SpatialDensity *grid,
	unsigned num_grids,
	unsigned num_vents, 
	double grid_spacing,
	unsigned *new_east,
	unsigned *new_north) {

	 Parameters
	In->spdfilespatial_density = $_[0];
	num_vents = $_[1];
 	spd_spacing = $_[2];
  my @lambda;
  my $sum;
  my $random;
  my $sum_lambda = 0;
*/
int CHOOSE_NEW_VENT(Inputs *In, DataCell ***SpDens ,VentArr *Vent) {
	double sum_lambda = 0, sum = 0, random;
	unsigned i,j;
	
	//If the Spatial Density Grid is NULL, declare it by loading in the SPD FILE
	if (*SpDens==NULL) {
		fprintf(stdout, "\nLoading Vent Spatial Density file...\n");
		In->spd_grid_data = DEM_LOADER(In->spd_file,
		                        SpDens,
		                        "DENSITY"
		                       );
		if ((In->spd_grid_data == NULL) || (*SpDens == NULL)) {
			fprintf(stderr, "\nError [CHOOSE_NEW_VENT]: ");
			fprintf(stderr, "Error flag returned from DEM_LOADER[DENSITY].\n");
			return 1;
		}
	}
	
	/*Metadata:
	  In->spd_grid_data[0] lower left x
	  In->spd_grid_data[1] w-e pixel resolution
	  In->spd_grid_data[2] number of cols
	  In->spd_grid_data[3] lower left y
	  In->spd_grid_data[4] number of lines
	  In->spd_grid_data[5] n-s pixel resolution */
	
	//Integrate the spatial density within the grid
	for(i=0; i < In->spd_grid_data[4]; i++) {
		for(j=0; j < In->spd_grid_data[2]; j++) {
			sum_lambda += (*(*SpDens+i)+j)->prob;
		}
	}
	if (sum_lambda <=0 ) {
		fprintf(stderr, "\nError [CHOOSE_NEW_VENT]: Spatial Density sums to <= 0!!\n");
		return 1;
	}
	
	
	//fprintf(stderr,"New Vent Location:");
	
	//Choose a random number (0 to integrated density) to match to a grid cell
	random = (double) genunf ( (float) 0, (float) sum_lambda );
	
	j=i=0;
	while (sum < random) {
		sum += (*(*SpDens+i)+(j++))->prob;
		if (j == (In->spd_grid_data[2])){
			i++;
			j=0;
		}
	}
	//j will be one step too far after this loop, so let's take 1 step back.
	if(j==0) {
		j=In->spd_grid_data[2];
		i--;
	}
	j--;
	
	Vent->northing = In->spd_grid_data[3] + (i * In->spd_grid_data[5]);
	Vent->easting = In->spd_grid_data[0] + (j * In->spd_grid_data[1]);
	
	//Choose a random location within the cell
	Vent->northing += ((double) genunf ( (float) 0, (float) 1)) * 
	                   In->spd_grid_data[5];
	Vent->easting  += ((double) genunf ( (float) 0, (float) 1)) * 
	                   In->spd_grid_data[1];
	
	
	//fprintf(stderr,"  %0.3f e, %0.3f n\n",Vent->easting,Vent->northing);
	
	
  	return 0;
	
}
Пример #10
0
void    mcwfalg(integer itraj, integer ntraj)
{
    integer i, N, exflag, flag;
    real    eps = 1.0e-6, t, temp;
    real    nl, nr, na, tl, tr, taim, thresh;
    double  sum = 0.0;

    N = RHS.N;
    for (i = 1; i <= 2 * N; i++)
        Ith(y, i) = Ith(ystart, i);

    /* Initialize ODE solver */
    cvode_mem = CVodeMalloc(2 * N, derivs, Ith(tlist, 1), y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                     	     &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);

    q = N_VNew(2 * N, NULL);
    thresh = genunf(0.0, 1.0);  /* Generate target value of norm^2 */
    if (nopers == 0)
        fwrite(&itraj, sizeof(integer), 1, op);
    if (clrecflag) {
        temp = itraj;
        fwrite(&temp, sizeof(real), 1, cp);
        temp = 0.0;
        fwrite(&temp, sizeof(real), 1, cp);
    }
    tr = Ith(tlist, 1);
    nr = norm2(N_VDATA(y) - 1, N);
    if (nopers == 0)
        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
    else
        operAccum(N_VDATA(y) - 1, N_VDATA(q) - 1, N, tr, 1);

    for (i = 2; i <= ntimes;) {
        taim = Ith(tlist, i);
        tl = tr;
        nl = nr;
        flag = CVode1(cvode_mem, taim, y, &tr, ONE_STEP);
        if (flag != SUCCESS) {
            sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
            fatal_error(errmsg);
        }
        nr = norm2(N_VDATA(y) - 1, N);
        for (; i <= ntimes;) {
            if (tr < taim) {
                if (nr < thresh) {
                    tr = docollapse(tl, nl, tr, nr, thresh);  /* A collapse has
                                                               * occured */
                    nr = 1.0;
                    thresh = genunf(0.0, 1.0);  /* Generate target value of
                                                 * norm^2 */
                }
                break;
            } else {
                flag = CVode1(cvode_mem, taim, y, &t, NORMAL); /* Interpolate */
                if (flag != SUCCESS) {
                    sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
                    fatal_error(errmsg);
                }
                na = norm2(N_VDATA(y) - 1, N);
                if (na < thresh) {
                    tr = docollapse(tl, nl, taim, na, thresh);  /* A collapse has
                                                                 * occured */
                    nr = 1.0;
                    thresh = genunf(0.0, 1.0);  /* Generate target value of
                                                 * norm^2 */
                    break;
                } else {        /* Write out results */
                    tl = taim;
                    nl = na;
                    if (nopers == 0)
                        fwrite(N_VDATA(y), sizeof(real), 2 * N, op);
                    else
                        operAccum(N_VDATA(y) - 1, N_VDATA(q) - 1, N, taim, i);
                    i += 1;
                    progress += NHASH;
                    while (progress >= (ntimes - 1) * ntraj) {
                        fprintf(stderr, "#");
                        progress -= (ntimes - 1) * ntraj;
                    }
                    taim = Ith(tlist, i);
                }
            }
        }
    }
    CVodeFree(cvode_mem);
}
Пример #11
0
real    docollapse(real tl, real nl, real tr, real nr, real thresh)
/* Find the time of collapse, update the wave function and restart the integrator */
{
    integer j, flag, k;
    real    tc, nc, temp, sum, t;

	for (k=1;k<=5;k++) {
        tc = tl + log(nl / thresh) / log(nl / nr) * (tr - tl);
        flag = CVode1(cvode_mem, tc, y, &t, NORMAL);
        if (flag != SUCCESS) {
            sprintf(errmsg, "CVode failed, flag=%d.\n", flag);
            fatal_error(errmsg);
        }
        nc = norm2(N_VDATA(y) - 1, N);
        if (fabs(thresh - nc) < THRESHTOL * fabs(thresh))
            break;
        else if (nc < thresh) {
            nr = nc;
            tr = tc;
        } else {
            nl = nc;
            tl = tc;
        }
    }
	/*    if (k>5) printf("\nWarning: Norm^2 of wavefunction does not attain threshold %f / %f\n"
					"Increase accuracy of integrator.\n",nc,thresh);*/
    /* Collapse occurs at tc, apply appropriate operator and restart
     * integrator */
    sum = 0.0;
    for (j = 1; j <= ncollapses; j++) {
        FSmul(&collapses[j], tc, N_VDATA(y) - 1, N_VDATA(q) - 1);
        sum += (Cprobs[j] = norm2(N_VDATA(q) - 1, N));
    }
    thresh = genunf(0.0, 1.0);  /* To determine which collapse occured */
    for (j = 1; j <= ncollapses; j++) {
        thresh -= Cprobs[j] / sum;
        if (thresh <= 0)
            break;
    }
    if (clrecflag) {            /* Write out classical record */
        fwrite(&tc, sizeof(real), 1, cp);
        temp = j;
        fwrite(&temp, sizeof(real), 1, cp);
    }
    /* Apply the collapse and normalize */
    FSmul(&collapses[j], tc, N_VDATA(y) - 1, N_VDATA(q) - 1);
    sum = sqrt(norm2(N_VDATA(q) - 1, N));
    for (j = 1; j <= 2 * N; j++)
        Ith(y, j) = Ith(q, j) / sum;
    /* Replace the integrator, since we have a new initial condition */
    CVodeFree(cvode_mem);
    cvode_mem = CVodeMalloc(2 * N, derivs, tc, y,
                            (method == 0) ? ADAMS : BDF,
                            (itertype == 0) ? FUNCTIONAL : NEWTON,
                            (nabstol == 1) ? SS : SV,
                     &reltol, abstolp, NULL, NULL, TRUE, iopt, ropt, NULL);
    if (cvode_mem == NULL) {
        fatal_error("CVodeMalloc failed.\n");
    }
    /* Call CVDiag */
    CVDiag(cvode_mem);
    return tc;
}