示例#1
0
double ModelAssemble::GslRandLogNormal(int curStatus){
	double result;
	if(curStatus == PLAY || curStatus == BACKWARD)
		result = gsl_ran_lognormal(m_r,mBackZeta,mBackSigma);
	else if(curStatus == FORWARD)
		result = gsl_ran_lognormal(m_r,mForZeta,mForSigma);
	return result;
}
示例#2
0
文件: ghmock.c 项目: philbull/ghost
float draw_optical_mag_intrinsic(float sfr, float mstar, char band, float z, 
                                  struct Params p, gsl_rng *rng)
{
    /*
    Intrinsic optical magnitude pdf, conditioned on Mstar and SFR: 
        p(mag_X | M_*, SFR, z). 
    Assumed to be lognormal, with scatter measured from Guo et al. simulations.
    */
    int i;
    float mu, mean, sigma, u;
    
    // Figure out which band to use
    i = band_index(band);
    
    // Central value (mu), and mean and standard deviation of residual
    mu = optical_mag(sfr, mstar, band, z, p);
    mean = p.opt_pdf_mean[i];
    sigma = p.opt_pdf_sigma[i];
    
    // Draw realisation of u, the shifted log-normal variate
    u = gsl_ran_lognormal(rng, mean, sigma);
    
    // Return magnitude (transformed back from shifted variate, u)
    return mu + exp( mean + 0.5 * sigma*sigma ) - u;
}
示例#3
0
文件: ghmock.c 项目: philbull/ghost
float draw_mass_stellar_cen(float mhalo, float z, struct Params p, gsl_rng *rng){
    /*
    Prob. density function for stellar mass, given halo mass and redshift. Uses 
    the form from Moster et al. (2010). Central galaxies.
    */
    float M2, mean_ms, sigma;
    
    // Mean stellar mass as fn. of halo mass
    mean_ms = mass_stellar_cen(mhalo, z, p);
    
    // Scatter as a fn. of halo mass [Eq. 12 of Moster et al. (2010)]
    M2 = pow(10., p.ms_cen_logM2);
    sigma = p.ms_cen_sigmainf 
          + p.ms_cen_sigma1 * (1. - 2./M_PI*atan(p.ms_cen_xi * log10(mhalo/M2)));
    sigma *= log(10.); // sigma in dex
    
    // Ensure that sigma is +ve, and larger than the value needed for 
    // integration to converge
    if(sigma < 2e-2){ sigma = 2e-2; }
    
    // Return pdf
    return gsl_ran_lognormal(rng, 
                             log(mean_ms),
                             sigma);
    /*return exp(-log(mstar/mean_ms)**2./(2.*sigma**2.)) \
         / (np.sqrt(2.*np.pi)*sigma*Ms); */
}
示例#4
0
void AlexSim::simTestLognormal()
{
    int n=10000; // number of samples
    int nbins=100; // number of bins for the histogram

    QFile file("./AlexSimTestLognormal.txt");

    if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) QMessageBox::information(0, "error", file.errorString());
    QTextStream out(&file);
    out <<"# Test lognormal distribution. Parameters are: burstDuration="<<burstDuration<<"\tvariance="<<burstDurationVar<<"\n";
    out <<"# burst duration in ms\tfrequency\n";
    out.setRealNumberPrecision(11);

    gsl_histogram * hist = gsl_histogram_alloc (nbins);
    gsl_histogram_set_ranges_uniform (hist, 0, 10*burstDuration);
    for (int ii=0;ii<n;ii++) {
        gsl_histogram_increment (hist,gsl_ran_lognormal(r,mu,sigma));
    }

    for(unsigned int ii=0;ii<hist->n;ii++) {
        out << hist->range[ii]*1e3 << "\t" << gsl_histogram_get(hist,ii) << "\n";
    }
    file.close();
    gsl_histogram_free (hist);
}
示例#5
0
void AlexSim::burstFRET(const double FRET)
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    Photons photonsTemp;
    photonsTemp<<burst(tstart, tend,FRET);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#6
0
void librdist_lognormal(gsl_rng *rng, int argc, void *argv, int bufc, float *buf){
	t_atom *av = (t_atom *)argv;
	if(argc != librdist_getnargs(ps_lognormal)){
		return;
	}
	const double zeta = librdist_atom_getfloat(av);
	const double sigma = librdist_atom_getfloat(av + 1);
	int i;
	for(i = 0; i < bufc; i++)
	       	buf[i] = (float)gsl_ran_lognormal(rng, zeta, sigma);
}
示例#7
0
文件: ghmock.c 项目: philbull/ghost
float draw_sfr_sfms(float mstar, float z, struct Params p, gsl_rng *rng){
    /*
    Prob. density function for SFR on the SF main sequence, given stellar mass 
    and redshift, p(SFR | M_*, z).
    */
    return gsl_ran_lognormal(rng,
                             log( sfr_sfms(mstar, z, p) ), 
                             p.sfr_sfms_sigma * log(10.));
    /*return np.exp(-np.log(sfr/mean_sfr)**2./(2.*sigma**2.)) \
         / (np.sqrt(2.*np.pi)*sigma*sfr)*/
}
示例#8
0
void pplfunc_frandomln (ppl_context *c, pplObj *in, int nArgs, int *status, int *errType, char *errText)
 {
  char *FunctionDescription = "lognormal(zeta,sigma)";
  if (rndgen==NULL) { rndgen = gsl_rng_alloc(gsl_rng_default); gsl_rng_set(rndgen, 0); }
  in++;
  CHECK_1INPUT_DIMLESS; // THIS IS CORRECT. Only check in[1]
  in--;
  OUTPUT.real = gsl_ran_lognormal(rndgen, in[0].real, in[1].real);
  CHECK_OUTPUT_OKAY;
  ppl_unitsDimCpy(&OUTPUT, &in[0]);
 }
示例#9
0
void AlexSim::burstAcceptorOnly()
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Acceptor only";

    Photons photonsTemp;
    photonsTemp<<acceptorOnly(tstart, tend);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#10
0
// a burst from tstart with length of burstDuration
// interphoton times are assumed to be exponentially distributed
void AlexSim::burst(bool debug)
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    if(debug) qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms";

    Photons photonsTemp;
    photonsTemp<<burst(tstart, tend);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#11
0
void AlexSim::burstBleachingAcceptor()
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    double tBleach=gsl_ran_flat(r, tstart, tend);
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Acceptor bleaching after "<<(tBleach-tstart)*1e3<<"ms";

    Photons photonsTemp;
    photonsTemp<<burst(tstart, tBleach);
    photonsTemp<<donorOnly(tBleach, tend);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#12
0
void AlexSim::burstDelayedAcceptor()
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    double tDelayed=gsl_ran_flat(r, tstart, tend);
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Acceptor delayed for"<<(tDelayed-tstart)*1e3<<"ms";

    Photons photonsTemp;
    photonsTemp<<acceptorOnly(tstart, tDelayed);
    photonsTemp<<burst(tDelayed, tend);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#13
0
extern double dist_lognormal(struct _flow *flow, const double zeta,
			     const double sigma)
{
#ifdef HAVE_LIBGSL
	gsl_rng * r = flow->r;
	return gsl_ran_lognormal (r, zeta, sigma);
#else
	/* not implemented */
	UNUSED_ARGUMENT(flow);
	UNUSED_ARGUMENT(zeta);
	UNUSED_ARGUMENT(sigma);
	return 0;
#endif /* HAVE_LIBGSL */
}
示例#14
0
void AlexSim::burstCoincidenceDonor(double scale)
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    double tCoincidenceStart=gsl_ran_flat(r, tstart, tend);
    double tCoincidenceEnd=gsl_ran_flat(r, tCoincidenceStart, tend);
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Donor coincidence after"<<(tCoincidenceStart-tstart)*1e3<<"ms for"<<(tCoincidenceEnd-tCoincidenceStart)*1e3<<"ms with scale parameter"<<scale;

    Photons photonsTemp;
    photonsTemp<<burst(tstart, tend);
    photonsTemp<<donorOnly(tCoincidenceStart,tCoincidenceEnd);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#15
0
文件: ghmock.c 项目: philbull/ghost
float draw_sfr_passive_lognormal(float mstar, float z, struct Params p, gsl_rng *rng){
    /*
    Prob. density function for SFR on the SF main sequence, given stellar mass 
    and redshift, p(SFR | M_*, z). [log-normal version]
    */
    // Take the SFMS powerlaw, shift it by some factor, and change scatter
    
    // Sanity check on shift parameter
    assert(p.sfr_pass_mshift >= 0.);
    
    // Draw log-normal realisation
    return gsl_ran_lognormal(rng,
                             log( sfr_sfms(mstar, z, p) * p.sfr_pass_mshift ),
                             p.sfr_pass_sigma * log(10.)); // sigma in dex
    /*return np.exp(-0.5 * (np.log(sfr/mean_sfr) / sigma)**2.) \
         / (np.sqrt(2.*np.pi)*sigma*sfr)*/
}
示例#16
0
void AlexSim::burstBlinkingAcceptor()
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    double tBlinkStart=gsl_ran_flat(r, tstart, tend);
    double tBlinkEnd=tBlinkStart + gsl_ran_exponential(r, lifetimeBlinking);
    if (tBlinkEnd>tend) tBlinkEnd=tend;
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Acceptor blinks after"<<(tBlinkStart-tstart)*1e3<<"ms for"<<(tBlinkEnd-tBlinkStart)*1e3<<"ms";

    Photons photonsTemp;
    photonsTemp<<burst(tstart, tBlinkStart);
    photonsTemp<<donorOnly(tBlinkStart, tBlinkEnd);
    photonsTemp<<burst(tBlinkEnd, tend);
    photonsTemp.sort();
    photons<<photonsTemp;
}
示例#17
0
void AlexSim::burstBlinkingDonor() // The time a flourophore blinks during a burst is chosen at random (from a uniform distribtion) and its length is drawn from an exponential distribution with mean value of the triplet lifetime.
{
    double tstart=t;
    double burstDurationSample=gsl_ran_lognormal(r, mu, sigma);
    double tend = tstart + burstDurationSample;
    double tBlinkStart=gsl_ran_flat(r, tstart, tend);
    double tBlinkEnd=tBlinkStart + gsl_ran_exponential(r, lifetimeBlinking);
    qDebug()<<"burst at"<<t*1e3<<"ms for"<<burstDurationSample*1e3<<"ms. Donor blinks after"<<(tBlinkStart-tstart)*1e3<<"ms for"<<(tBlinkEnd-tBlinkStart)*1e3<<"ms";

    burst(tstart, tBlinkStart);
    acceptorOnly(tBlinkStart, tBlinkEnd);
    burst(tBlinkEnd, tend);

    Photons photonsTemp;
    photonsTemp<<burst(tstart, tBlinkStart);
    photonsTemp<<acceptorOnly(tBlinkStart, tBlinkEnd);
    photonsTemp<<burst(tBlinkEnd, tend);
    photonsTemp.sort();
    photons<<photonsTemp;

}
示例#18
0
/////////////////////////////////////////////////////////////////////////////
// LognormalRandomDraw()
/////////////////////////////////////////////////////////////////////////////
float clModelMath::LognormalRandomDraw(float fMean, float fStdDev) {
  return (gsl_ran_lognormal(randgen, fMean, fStdDev));
}
示例#19
0
/**
 main simulation loop
*/
int main() {

  // init own parameters.
  initDerivedParams(); 

  // init random generator
  gsl_rng_env_setup();
  r = gsl_rng_alloc(gsl_rng_default);
  gsl_rng_set(r, SEED_MAIN);

  // file handle for xxx file
  FILE *postF = fopen(FILENAME_POST, FILEPOST_FLAG);

  // file handle for xxx file
  FILE *preF = fopen(FILENAME_PRE, "wb");
	
  // set up vectors:

  // to hold post synaptic potentials [unused??]
  gsl_vector *psp = gsl_vector_alloc(NPRE);
  // to hold post synaptic potentials 1st filtered
  gsl_vector *pspS = gsl_vector_alloc(NPRE);
  // to hold "excitatory" part of psp for Euler integration
  gsl_vector *sue = gsl_vector_alloc(NPRE);
  // to hold "inhibitory" part of psp for Euler integration
  gsl_vector *sui = gsl_vector_alloc(NPRE);
  // to hold psp 2nd filter
  gsl_vector *pspTilde = gsl_vector_alloc(NPRE);
  // to hold weights
  gsl_vector *w  = gsl_vector_alloc(NPRE);
  // to hold xxx
  gsl_vector *pres  = gsl_vector_alloc(NPRE);

  // ?? ou XXX \todo
#ifdef PREDICT_OU
  gsl_vector *ou = gsl_vector_alloc(N_OU);
  gsl_vector *preU = gsl_vector_calloc(NPRE);
  gsl_vector *wInput = gsl_vector_alloc(N_OU);
  gsl_matrix *wPre  = gsl_matrix_calloc(NPRE, N_OU);
  double *preUP = gsl_vector_ptr(preU,0);
  double *ouP = gsl_vector_ptr(ou,0);
  double *wInputP = gsl_vector_ptr(wInput,0);
  double *wPreP = gsl_matrix_ptr(wPre,0,0);
#endif

  // get pointers to array within the gsl_vector data structures above.
  double *pspP = gsl_vector_ptr(psp,0);
  double *pspSP = gsl_vector_ptr(pspS,0);
  double *sueP = gsl_vector_ptr(sue,0);
  double *suiP = gsl_vector_ptr(sui,0);
  double *pspTildeP = gsl_vector_ptr(pspTilde,0);
  double *wP = gsl_vector_ptr(w,0);
  double *presP = gsl_vector_ptr(pres,0);

  for(int i=0; i<NPRE; i++) {

    // init pspP etc to zero
    *(pspP+i) = 0;
    *(sueP+i) = 0;
    *(suiP+i) = 0;
#ifdef RANDI_WEIGHTS
    // Gaussian weights
    *(wP+i) = gsl_ran_gaussian(r, .1);
#else
    *(wP+i) = 0;
#endif
  }


  //! OU \todo what for?	
#ifdef PREDICT_OU
  for(int j=0; j < N_OU; j++) {
    *(ouP + j) = gsl_ran_gaussian(r, 1) + M_OU;
    *(wInputP + j) = gsl_ran_lognormal(r, 0., 2.)/N_OU/exp(2.)/2.;
    for(int i=0; i < NPRE; i++) *(wPreP + j*NPRE + i) = gsl_ran_lognormal(r, 0., 2.)/N_OU/exp(2.)/2.;
  }
#endif

  // temp variables for the simulation yyyy
  double 
    u = 0, // soma potential.
    uV = 0, // some potential from dendrite only (ie discounted
	    // dendrite potential
    rU = 0, // instantneou rate 
    rV = 0, // rate on dendritic potential only
    uI = 0, // soma potential only from somatic inputs
    rI = 0, // rate on somatic potential only
    uInput = 0; // for OU?

  // run simulatio TRAININGCYCLES number of times
  for( int s = 0; s < TRAININGCYCLES; s++) {

    // for all TIMEBINS
    for( int t = 0; t < TIMEBINS; t++) {

#ifdef PREDICT_OU
      for(int i = 0; i < N_OU; i++) {
	*(ouP+i) = runOU(*(ouP+i), M_OU, GAMMA_OU, S_OU);
      }
      gsl_blas_dgemv(CblasNoTrans, 1., wPre, ou, 0., preU); 
#endif

      // update PSP of our neurons for inputs from all presynaptic neurons
      for( int i = 0; i < NPRE; i++) {

#ifdef RAMPUPRATE
	/** just read in the PRE_ACT and generate a spike and store it in presP -- so PRE_ACT has inpretation of potential */
	updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = spiking(PRE_ACT[t*NPRE + i], gsl_rng_uniform(r)));

#elif defined PREDICT_OU
	//*(ouP+i) = runOU(*(ouP+i), M_OU, GAMMA_OU, S_OU); // why commented out?
	updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = DT * phi(*(preUP+i)));//spiking(DT * phi(*(preUP+i)), gsl_rng_uniform(r))); // why commented out?

#else
	// PRE_ACT intepreated as spikes
	updatePre(sueP+i, suiP+i, pspP + i, pspSP + i, pspTildeP + i, *(presP + i) = PRE_ACT[t*NPRE + i]);
#endif
      } // endfor NPRE

#ifdef PREDICT_OU
      gsl_blas_ddot(wInput, ou, &uInput);
      GE[t] = DT * phi(uInput);

#endif
      // now update the membrane potential.
      updateMembrane(&u, &uV, &uI, w, psp, GE[t], GI[t]);


      // now calculate rates from from potentials.
#ifdef POSTSPIKING // usually switch off as learning is faster when
		   // learning from U
      // with low-pass filtering of soma potential from actual
      // generation of spikes (back propgating dentric spikes?
      rU = GAMMA_POSTS*rU + (1-GAMMA_POSTS)*spiking(DT * phi(u),  gsl_rng_uniform(r))/DT;
#else
      // simpler -- direct.
      rU = phi(u); 
#endif
      rV = phi(uV); rI = phi(uI);

      // now update weights based on rU, RV, the 2nd filtered PSP and
      // the pspSP
      for(int i = 0; i < NPRE; i++) {
	updateWeight(wP + i, rU, *(pspTildeP+i), rV, *(pspSP+i));
      }
#ifdef TAUEFF
      /**
	 write rU to postF, but only for the last run of the
	 simulation and then only before the STIM_ONSET time --
	 ie it is the trained output without somatic drive.
       */
      if(s == TRAININGCYCLES - 1 && t < STIM_ONSET/DT) {
	fwrite(&rU, sizeof(double), 1, postF); 
      }
#else
      /**
	 for every 10th training cycle write all variables below to
	 postF in order:
       */
      if(s%(TRAININGCYCLES/10)==0) {
	fwrite(&rU, sizeof(double), 1, postF);
	fwrite(GE+t, sizeof(double), 1, postF);
	fwrite(&rV, sizeof(double), 1, postF);
	fwrite(&rI, sizeof(double), 1, postF);
	fwrite(&u, sizeof(double), 1, postF);
      }
      if(s == TRAININGCYCLES - 1) {
#ifdef RECORD_PREACT
	// for the last cycle also record the activity of the
	// presynaptic neurons
	fwrite(PRE_ACT + t * NPRE, sizeof(double), 20, preF);
	//fwrite(ouP, sizeof(double), 20, preF);
	fwrite(presP, sizeof(double), 20, preF);
#else
	// and the 1st and 2nd filtered PSP
	fwrite(pspSP, sizeof(double), 1, preF);
	fwrite(pspTildeP, sizeof(double), 1, preF);
#endif
      }
#endif
    }
  }
  
  fclose(preF);
  fclose(postF);
  
  return 0;
}
示例#20
0
double
test_lognormal (void)
{
  return gsl_ran_lognormal (r_global, 2.7, 1.3);
}
示例#21
0
int
main (int argc, char *argv[])
{
  size_t i,j;
  size_t n = 0;
  double mu = 0, nu = 0, nu1 = 0, nu2 = 0, sigma = 0, a = 0, b = 0, c = 0;
  double zeta = 0, sigmax = 0, sigmay = 0, rho = 0;
  double p = 0;
  double x = 0, y =0, z=0  ;
  unsigned int N = 0, t = 0, n1 = 0, n2 = 0 ;
  unsigned long int seed = 0 ;
  const char * name ;
  gsl_rng * r ;

  if (argc < 4) 
    {
      printf (
"Usage: gsl-randist seed n DIST param1 param2 ...\n"
"Generates n samples from the distribution DIST with parameters param1,\n"
"param2, etc. Valid distributions are,\n"
"\n"
"  beta\n"
"  binomial\n"
"  bivariate-gaussian\n"
"  cauchy\n"
"  chisq\n"
"  dir-2d\n"
"  dir-3d\n"
"  dir-nd\n"
"  erlang\n"
"  exponential\n"
"  exppow\n"
"  fdist\n"
"  flat\n"
"  gamma\n"
"  gaussian-tail\n"
"  gaussian\n"
"  geometric\n"
"  gumbel1\n"
"  gumbel2\n"
"  hypergeometric\n"
"  laplace\n"
"  landau\n"
"  levy\n"
"  levy-skew\n"
"  logarithmic\n"
"  logistic\n"
"  lognormal\n"
"  negative-binomial\n"
"  pareto\n"
"  pascal\n"
"  poisson\n"
"  rayleigh-tail\n"
"  rayleigh\n"
"  tdist\n"
"  ugaussian-tail\n"
"  ugaussian\n"
"  weibull\n") ;
      exit (0);
    }

  argv++ ; seed = atol (argv[0]); argc-- ;
  argv++ ; n = atol (argv[0]); argc-- ;
  argv++ ; name = argv[0] ; argc-- ; argc-- ;

  gsl_rng_env_setup() ;

  if (gsl_rng_default_seed != 0) {
    fprintf(stderr, 
            "overriding GSL_RNG_SEED with command line value, seed = %ld\n", 
            seed) ;
  }
  
  gsl_rng_default_seed = seed ;

  r = gsl_rng_alloc(gsl_rng_default) ;


#define NAME(x) !strcmp(name,(x))
#define OUTPUT(x) for (i = 0; i < n; i++) { printf("%g\n", (x)) ; }
#define OUTPUT1(a,x) for(i = 0; i < n; i++) { a ; printf("%g\n", x) ; }
#define OUTPUT2(a,x,y) for(i = 0; i < n; i++) { a ; printf("%g %g\n", x, y) ; }
#define OUTPUT3(a,x,y,z) for(i = 0; i < n; i++) { a ; printf("%g %g %g\n", x, y, z) ; }
#define INT_OUTPUT(x) for (i = 0; i < n; i++) { printf("%d\n", (x)) ; }
#define ARGS(x,y) if (argc != x) error(y) ;
#define DBL_ARG(x) if (argc) { x=atof((++argv)[0]);argc--;} else {error( #x);};
#define INT_ARG(x) if (argc) { x=atoi((++argv)[0]);argc--;} else {error( #x);};

  if (NAME("bernoulli"))
    {
      ARGS(1, "p = probability of success");
      DBL_ARG(p)
      INT_OUTPUT(gsl_ran_bernoulli (r, p));
    }
  else if (NAME("beta"))
    {
      ARGS(2, "a,b = shape parameters");
      DBL_ARG(a)
      DBL_ARG(b)
      OUTPUT(gsl_ran_beta (r, a, b));
    }
  else if (NAME("binomial"))
    {
      ARGS(2, "p = probability, N = number of trials");
      DBL_ARG(p)
      INT_ARG(N)
      INT_OUTPUT(gsl_ran_binomial (r, p, N));
    }
  else if (NAME("cauchy"))
    {
      ARGS(1, "a = scale parameter");
      DBL_ARG(a)
      OUTPUT(gsl_ran_cauchy (r, a));
    }
  else if (NAME("chisq"))
    {
      ARGS(1, "nu = degrees of freedom");
      DBL_ARG(nu)
      OUTPUT(gsl_ran_chisq (r, nu));
    }
  else if (NAME("erlang"))
    {
      ARGS(2, "a = scale parameter, b = order");
      DBL_ARG(a)
      DBL_ARG(b)
      OUTPUT(gsl_ran_erlang (r, a, b));
    }
  else if (NAME("exponential"))
    {
      ARGS(1, "mu = mean value");
      DBL_ARG(mu) ;
      OUTPUT(gsl_ran_exponential (r, mu));
    }
  else if (NAME("exppow"))
    {
      ARGS(2, "a = scale parameter, b = power (1=exponential, 2=gaussian)");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_exppow (r, a, b));
    }
  else if (NAME("fdist"))
    {
      ARGS(2, "nu1, nu2 = degrees of freedom parameters");
      DBL_ARG(nu1) ;
      DBL_ARG(nu2) ;
      OUTPUT(gsl_ran_fdist (r, nu1, nu2));
    }
  else if (NAME("flat"))
    {
      ARGS(2, "a = lower limit, b = upper limit");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_flat (r, a, b));
    }
  else if (NAME("gamma"))
    {
      ARGS(2, "a = order, b = scale");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_gamma (r, a, b));
    }
  else if (NAME("gaussian"))
    {
      ARGS(1, "sigma = standard deviation");
      DBL_ARG(sigma) ;
      OUTPUT(gsl_ran_gaussian (r, sigma));
    }
  else if (NAME("gaussian-tail"))
    {
      ARGS(2, "a = lower limit, sigma = standard deviation");
      DBL_ARG(a) ;
      DBL_ARG(sigma) ;
      OUTPUT(gsl_ran_gaussian_tail (r, a, sigma));
    }
  else if (NAME("ugaussian"))
    {
      ARGS(0, "unit gaussian, no parameters required");
      OUTPUT(gsl_ran_ugaussian (r));
    }
  else if (NAME("ugaussian-tail"))
    {
      ARGS(1, "a = lower limit");
      DBL_ARG(a) ;
      OUTPUT(gsl_ran_ugaussian_tail (r, a));
    }
  else if (NAME("bivariate-gaussian"))
    {
      ARGS(3, "sigmax = x std.dev., sigmay = y std.dev., rho = correlation");
      DBL_ARG(sigmax) ;
      DBL_ARG(sigmay) ;
      DBL_ARG(rho) ;
      OUTPUT2(gsl_ran_bivariate_gaussian (r, sigmax, sigmay, rho, &x, &y), 
              x, y);
    }
  else if (NAME("dir-2d"))
    {
      OUTPUT2(gsl_ran_dir_2d (r, &x, &y), x, y);
    }
  else if (NAME("dir-3d"))
    {
      OUTPUT3(gsl_ran_dir_3d (r, &x, &y, &z), x, y, z);
    }
  else if (NAME("dir-nd"))
    {
      double *xarr;  
      ARGS(1, "n1 = number of dimensions of hypersphere"); 
      INT_ARG(n1) ;
      xarr = (double *)malloc(n1*sizeof(double));

      for(i = 0; i < n; i++) { 
        gsl_ran_dir_nd (r, n1, xarr) ; 
        for (j = 0; j < n1; j++) { 
          if (j) putchar(' '); 
          printf("%g", xarr[j]) ; 
        } 
        putchar('\n'); 
      } ;

      free(xarr);
    }  
  else if (NAME("geometric"))
    {
      ARGS(1, "p = bernoulli trial probability of success");
      DBL_ARG(p) ;
      INT_OUTPUT(gsl_ran_geometric (r, p));
    }
  else if (NAME("gumbel1"))
    {
      ARGS(2, "a = order, b = scale parameter");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_gumbel1 (r, a, b));
    }
  else if (NAME("gumbel2"))
    {
      ARGS(2, "a = order, b = scale parameter");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_gumbel2 (r, a, b));
    }
  else if (NAME("hypergeometric"))
    {
      ARGS(3, "n1 = tagged population, n2 = untagged population, t = number of trials");
      INT_ARG(n1) ;
      INT_ARG(n2) ;
      INT_ARG(t) ;
      INT_OUTPUT(gsl_ran_hypergeometric (r, n1, n2, t));
    }
  else if (NAME("laplace"))
    {
      ARGS(1, "a = scale parameter");
      DBL_ARG(a) ;
      OUTPUT(gsl_ran_laplace (r, a));
    }
  else if (NAME("landau"))
    {
      ARGS(0, "no arguments required");
      OUTPUT(gsl_ran_landau (r));
    }
  else if (NAME("levy"))
    {
      ARGS(2, "c = scale, a = power (1=cauchy, 2=gaussian)");
      DBL_ARG(c) ;
      DBL_ARG(a) ;
      OUTPUT(gsl_ran_levy (r, c, a));
    }
  else if (NAME("levy-skew"))
    {
      ARGS(3, "c = scale, a = power (1=cauchy, 2=gaussian), b = skew");
      DBL_ARG(c) ;
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_levy_skew (r, c, a, b));
    }
  else if (NAME("logarithmic"))
    {
      ARGS(1, "p = probability");
      DBL_ARG(p) ;
      INT_OUTPUT(gsl_ran_logarithmic (r, p));
    }
  else if (NAME("logistic"))
    {
      ARGS(1, "a = scale parameter");
      DBL_ARG(a) ;
      OUTPUT(gsl_ran_logistic (r, a));
    }
  else if (NAME("lognormal"))
    {
      ARGS(2, "zeta = location parameter, sigma = scale parameter");
      DBL_ARG(zeta) ;
      DBL_ARG(sigma) ;
      OUTPUT(gsl_ran_lognormal (r, zeta, sigma));
    }
  else if (NAME("negative-binomial"))
    {
      ARGS(2, "p = probability, a = order");
      DBL_ARG(p) ;
      DBL_ARG(a) ;
      INT_OUTPUT(gsl_ran_negative_binomial (r, p, a));
    }
  else if (NAME("pareto"))
    {
      ARGS(2, "a = power, b = scale parameter");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_pareto (r, a, b));
    }
  else if (NAME("pascal"))
    {
      ARGS(2, "p = probability, n = order (integer)");
      DBL_ARG(p) ;
      INT_ARG(N) ;
      INT_OUTPUT(gsl_ran_pascal (r, p, N));
    }
  else if (NAME("poisson"))
    {
      ARGS(1, "mu = scale parameter");
      DBL_ARG(mu) ;
      INT_OUTPUT(gsl_ran_poisson (r, mu));
    }
  else if (NAME("rayleigh"))
    {
      ARGS(1, "sigma = scale parameter");
      DBL_ARG(sigma) ;
      OUTPUT(gsl_ran_rayleigh (r, sigma));
    }
  else if (NAME("rayleigh-tail"))
    {
      ARGS(2, "a = lower limit, sigma = scale parameter");
      DBL_ARG(a) ;
      DBL_ARG(sigma) ;
      OUTPUT(gsl_ran_rayleigh_tail (r, a, sigma));
    }
  else if (NAME("tdist"))
    {
      ARGS(1, "nu = degrees of freedom");
      DBL_ARG(nu) ;
      OUTPUT(gsl_ran_tdist (r, nu));
    }
  else if (NAME("weibull"))
    {
      ARGS(2, "a = scale parameter, b = exponent");
      DBL_ARG(a) ;
      DBL_ARG(b) ;
      OUTPUT(gsl_ran_weibull (r, a, b));
    }
  else
    {
      fprintf(stderr,"Error: unrecognized distribution: %s\n", name) ;
    }

  return 0 ;
}
scalar sasfit_ff_RNDMultiLamellarVesicle2(scalar q, sasfit_param * param)
{
	scalar sum, sumt;
	scalar Delta_s, DRi, Fi, Fj, rij;
	scalar xc, yc, zc;
	scalar t_sh, s_tsh, R_c, s_Rc, n, s_n, t_sol, s_tsol, Dt_sol, Delta_eta;
	int i, j, N, p, Nav = 200;
	static int idum = -1;
	static gsl_rng * r; 
	static const gsl_rng_type * T;
//	static float o_R_c=-1., o_t_sh=-1., o_t_sol=-1., o_Dt_sol=-1.,o_n=-1.;
	static scalar r_i[100][3], R_i[100], tsh_i[100];
	sasfit_param subParam;

	SASFIT_ASSERT_PTR(param);

	sasfit_get_param(param, 10, &t_sh, &s_tsh, &R_c, &s_Rc, &n, &s_n, &t_sol, &s_tsol, &Dt_sol, &Delta_eta);

	SASFIT_CHECK_COND1((q < 0.0), param, "q(%lg) < 0",q);
	SASFIT_CHECK_COND1((R_c <= 0.0), param, "R_c(%lg) <= 0",R_c);
	SASFIT_CHECK_COND1((s_Rc < 0.0), param, "s_Rc(%lg) < 0",s_Rc);
	SASFIT_CHECK_COND1((t_sol < 0.0), param, "t_sol(%lg) < 0",t_sol);
	SASFIT_CHECK_COND1((s_tsol < 0.0), param, "s_tsol(%lg) < 0",s_tsol);
	SASFIT_CHECK_COND1((t_sh < 0.0), param, "t_sh(%lg) < 0",t_sh);
	SASFIT_CHECK_COND1((s_tsh < 0.0), param, "s_tsh(%lg) < 0",s_tsh);
	SASFIT_CHECK_COND1((n < 1.0), param, "n(%lg) < 1",n);
	SASFIT_CHECK_COND1((n > 100), param, "n(%lg) > 100",n);
	SASFIT_CHECK_COND1((s_n < 0.0), param, "s_n(%lg) < 0",s_n);

	if (idum < 0) 
	{
		idum = 1;
		gsl_rng_env_setup();
		T = gsl_rng_default;
		r = gsl_rng_alloc(T);
	}
	if (20 < sasfit_eps_get_iter_4_mc()) 
	{
		Nav = sasfit_eps_get_iter_4_mc();
	} else {
		Nav =20;
	}

	sasfit_init_param( &subParam );
	sumt = 0.0;

	for (p=0; p < Nav ;p++) 
	{
		//  do {
		//	  N = (int) (gsl_ran_gaussian (r,s_n)+n);
		//  } while ((N>n+3*s_n) || (N<1));
		if (s_n== 0.0) {
			N = (int) n;
		} else {
			do {
				N = (int) gsl_ran_lognormal(r,log(n),s_n);
			} 
			while ((N>200) || (N<1));
		}
		r_i[0][0] = 0.0;
		r_i[0][1] = 0.0;
		r_i[0][2] = 0.0;

		for (i=0; i < N ;i++) 
		{
			if (s_tsh == 0.0) {
				tsh_i[i] = t_sh;
			} else {
				do {
					tsh_i[i] = gsl_ran_gaussian(r,s_tsh)+t_sh;
				} 
				while (tsh_i[i] <= 0);
			}
		}

		//	  do {
		//		  R_i[0] = gsl_ran_gaussian(r,s_Rc)+R_c;
		//	  } while (R_i[0] <= 0);
		if (s_Rc == 0.0) {
			R_i[0] = R_c;
		} else {
			do {
				R_i[0] = gsl_ran_lognormal(r,log(R_c),s_Rc);
			} 
			while (R_i[0] <= 0);
		}
		for (i=1; i < N ;i++) 
		{
			gsl_ran_dir_3d(r,&xc,&yc,&zc);
			if (s_tsol == 0.0) {
				DRi = t_sol;
			} else {
				do {
					DRi = gsl_ran_gaussian(r,s_tsol)+t_sol;
				} 
				while (DRi < 0);
			}
			R_i[i] = R_i[i-1]+tsh_i[i-1]+DRi;
			if (Dt_sol <= 0) {
				Delta_s = Dt_sol*DRi;
			} else {
				do {
					Delta_s = Dt_sol*DRi*gsl_rng_uniform(r);
				} 
				while (Delta_s < 0);
			}
			r_i[i][0] = r_i[i-1][0] + Delta_s*xc;
			r_i[i][1] = r_i[i-1][1] + Delta_s*yc;
			r_i[i][2] = r_i[i-1][2] + Delta_s*zc; 
		}
		sum=0.0;
		for (i=0; i < N ;i++) 
		{
			/*
			Fi =  K(interp,q,R_i[i]			,-Delta_eta,error)
				+ K(interp,q,R_i[i]+tsh_i[i], Delta_eta,error);
				*/
			subParam.p[0] = R_i[i];
			subParam.p[3] = -Delta_eta;
			Fi = sasfit_ff_sphere_f(q, &subParam);

			subParam.p[0] = R_i[i] + tsh_i[i];
			subParam.p[3] = Delta_eta;
			Fi += sasfit_ff_sphere_f(q, &subParam);

			sum = sum + Fi*Fi;
			for (j=i+1; j < N ;j++) 
			{
				/*
				Fj =  K(interp,q,R_i[j]			,-Delta_eta,error)
					+ K(interp,q,R_i[j]+tsh_i[j], Delta_eta,error);
				*/
				subParam.p[0] = R_i[j];
				subParam.p[3] = -Delta_eta;
				Fj = sasfit_ff_sphere_f(q, &subParam);
				
				subParam.p[0] = R_i[j] + tsh_i[j];
				subParam.p[3] = Delta_eta;
				Fj += sasfit_ff_sphere_f(q, &subParam);

				rij = sqrt( pow(r_i[i][0]-r_i[j][0],2)
					       +pow(r_i[i][1]-r_i[j][1],2)
					       +pow(r_i[i][2]-r_i[j][2],2)
						  );
				if (rij == 0) 
				{
					sum = sum + 2.0*Fi*Fj;
				} else 
				{
					sum = sum + 2.0*Fi*Fj*sin(q*rij)/(q*rij);
				}
			}
		}
		sumt = sumt+sum;
	}
	SASFIT_CHECK_SUB_ERR(param, subParam);

	return sumt/Nav;
}