コード例 #1
0
// Calculates the probability density of finding the particle at location z at
// timepoint t, given that the particle is still in the domain.
const Real
FirstPassageGreensFunction1DRad::calcpcum (const Real r, const Real t) const
{
    // BEWARE: HERE THERE IS SCALING OF R!
    const Real r_corr(r/this->l_scale);
    // p_survival is unscaled!
    return prob_r (r_corr, t)/p_survival (t);
}
コード例 #2
0
const Real GreensFunction2DAbs::drawR(const Real rnd, const Real t) const
{
    THROW_UNLESS(std::invalid_argument, 0.0<=rnd && rnd <= 1.0);

    if(a == r0)
        throw std::invalid_argument("a equal r0");

    if(t == 0e0 || D == 0e0)
        return r0;

    if(rnd == 1e0)
        return a;//!?

    Real p_surv(p_survival(t));
    assert(p_surv > 0e0);

    p_r_params params = {this, t, rnd * p_surv};

    gsl_function F =
    {
        reinterpret_cast<double (*)(double, void*)>(&p_r_F), &params
    };

    const Real low(0e0);
    const Real high(a);

    const gsl_root_fsolver_type* solverType(gsl_root_fsolver_brent);
    gsl_root_fsolver* solver(gsl_root_fsolver_alloc(solverType));

    const Real r(findRoot(F, solver, low, high, 1e-18, 1e-12,
                          "GreensFunction2DAbsSym::drawR"));

    gsl_root_fsolver_free(solver);

    return r;
}
コード例 #3
0
// Draws the position of the particle at a given time from p(r,t), assuming 
// that the particle is still in the domain
Real
GreensFunction1DAbsAbs::drawR (Real rnd, Real t) const
{
    THROW_UNLESS( std::invalid_argument, 0.0 <= rnd && rnd < 1.0 );
    THROW_UNLESS( std::invalid_argument, t >= 0.0 );

    const Real a(this->geta());
    const Real sigma(this->getsigma());
    const Real L(this->geta() - this->getsigma());
    const Real r0(this->getr0());
    const Real D(this->getD());
    const Real v(this->getv());

    // the trivial case: if there was no movement or the domain was zero
    if ( (D==0.0 && v==0.0) || L<0.0 || t==0.0)
    {
	return r0;
    }
    else
    {
	// if the initial condition is at the boundary, raise an error
	// The particle can only be at the boundary in the ABOVE cases
	THROW_UNLESS( std::invalid_argument,
	              (r0-sigma) >= L*EPSILON && (r0-sigma) <= L*(1.0-EPSILON) );
    }
    // else the normal case
    // From here on the problem is well defined


    // structure to store the numbers to calculate numbers for 1-S(t)
    struct drawR_params parameters;
    Real S_Cn_An;
    Real nPI;
    const Real expo (-D*t/(L*L));
    const Real r0s_L((r0-sigma)/L);
    const Real v2D(v/2.0/D);
    const Real Lv2D(L*v/2.0/D);
    const Real vexpo(-v*v*t/4.0/D - v*r0/2.0/D);	// exponent of the drift-prefactor, same as in survival prob.
    const Real S = 2.0*exp(vexpo)/p_survival(t);	// This is a prefactor to every term, so it also contains there
							// exponential drift-prefactor.

    // Construct the coefficients and the terms in the exponent and put them 
    // in the params structure
    int n=0;
    do
    {
	nPI = ((Real)(n+1))*M_PI;	    // note: summation starting with n=1, indexing with n=0, therefore we need n+1 here
	
	if(v==0.0)	S_Cn_An = S * exp(nPI*nPI*expo) * sin(nPI*r0s_L) / nPI;
	else		S_Cn_An = S * exp(nPI*nPI*expo) * sin(nPI*r0s_L) * nPI/(nPI*nPI + Lv2D*Lv2D);
	  // The rest is the z-dependent part, which has to be defined directly in drawR_f(z).
	  // Of course also the summation happens there because the terms now are z-dependent.
	  // The last term originates from the integrated prob. density including drift.
	  //
	  // In case of zero drift this expression becomes: 2.0/p_survival(t) * exp(nPI*nPI*expo) * sin(nPI*r0s_L) / nPI
	  
	// also store the values for the exponent, so they don't have to be recalculated in drawR_f
	parameters.S_Cn_An[n]= S_Cn_An;
	parameters.n_L[n]    = nPI/L;
	n++;
    }
    while (n<MAX_TERMS);

    // store the random number for the probability
    parameters.rnd = rnd ;
    // store the number of terms used
    parameters.terms = MAX_TERMS;
    
    // store needed constants
    parameters.H[0] = sigma;
    parameters.H[1] = v2D;

    // find the intersection on the y-axis between the random number and 
    // the function
    gsl_function F;
    F.function = &drawR_f;
    F.params = &parameters;

    // define a new solver type brent
    const gsl_root_fsolver_type* solverType( gsl_root_fsolver_brent );
    // make a new solver instance
    // TODO: incl typecast?
    gsl_root_fsolver* solver( gsl_root_fsolver_alloc( solverType ) );
    const Real r( findRoot( F, solver, sigma, a, L*EPSILON, EPSILON,
                            "GreensFunction1DAbsAbs::drawR" ) );

    // return the drawn time
    return r;
}
コード例 #4
0
// Calculates the probability density of finding the particle at location r at 
// timepoint t, given that the particle is still in the domain.
Real
GreensFunction1DAbsAbs::calcpcum (Real r, Real t) const
{
    return prob_r(r, t) / p_survival(t);
}
コード例 #5
0
const Real 
GreensFunction2DAbsSym::drawR( const Real rnd, const Real t ) const 
{
  
    THROW_UNLESS( std::invalid_argument, rnd <= 1.0 && rnd >= 0.0 );
    THROW_UNLESS( std::invalid_argument, t >= 0.0 );

    const Real a( geta() );
    const Real D( getD() );

    if( a == 0.0 || t == 0.0 || D == 0.0 )
    {
        return 0.0;
    }

    //const Real thresholdDistance( this->CUTOFF_H * sqrt( 4.0 * D * t ) );

    gsl_function F;
    Real psurv;

//  if( a <= thresholdDistance )	// if the domain is not so big, the boundaries are felt
//  {
        psurv = p_survival( t );
        //psurv = p_int_r( a, t );
        //printf("dr %g %g\n",psurv, p_survival( t ));
        //assert( fabs(psurv - p_int_r( a, t )) < psurv * 1e-8 );

        assert( psurv > 0.0 );

        F.function = reinterpret_cast<double (*)(double, void*)>( &p_r_F );
/*  }
    else				// if the domain is very big, just use the free solution
    {
        // p_int_r < p_int_r_free
        if( p_int_r_free( a, t ) < rnd )	// if the particle is outside the domain?
        {
            std::cerr << "p_int_r_free( a, t ) < rnd, returning a." 
                      << std::endl;
            return a;
        }

        psurv = 1.0;
        F.function = reinterpret_cast<double (*)(double, void*)>( &p_r_free_F );
    }
*/
    const Real target( psurv * rnd );
    p_r_params params = { this, t, target };

    F.params = &params;


    const Real low( 0.0 );
    const Real high( a );
    //const Real high( std::min( thresholdDistance, a ) );

    const gsl_root_fsolver_type* solverType( gsl_root_fsolver_brent );
    gsl_root_fsolver* solver( gsl_root_fsolver_alloc( solverType ) );

    const Real r( findRoot( F, solver, low, high, 1e-18, 1e-12,
                            "GreensFunction2DAbsSym::drawR" ) );
  
    gsl_root_fsolver_free( solver );

    return r;
}
コード例 #6
0
Real
GreensFunction1DRadAbs::drawR (Real rnd, Real t) const
{
    THROW_UNLESS( std::invalid_argument, 0.0 <= rnd && rnd < 1.0 );
    THROW_UNLESS( std::invalid_argument, t >= 0.0 );
    
    const Real sigma(this->getsigma());
    const Real a(this->geta());
    const Real L(this->geta()-this->getsigma());
    const Real r0(this->getr0());
    const Real D(this->getD());
    const Real v(this->getv());
    const Real k(this->getk());
    const Real h((this->getk()+this->getv()/2.0)/this->getD());
    

    if (t==0.0 || (D==0.0 && v==0.0) )
    {
	// the trivial case
	//return r0*this->l_scale;	// renormalized version, discontinued
	return r0;
    }
    if ( a<0.0 )
    {
	// if the domain had zero size
	return 0.0;
    }

    // the structure to store the numbers to calculate the numbers for 1-S
    struct drawR_params parameters;
    double root_n = 0;
    double S_Cn_root_n;
    double root_n2, root_n_r0_s;
    const Real vexpo(-v*v*t/4.0/D - v*r0/2.0/D); // exponent of the drift-prefactor, same as in survival prob.
    const Real v2D(v/2.0/D);
    const Real v2Dv2D(v2D*v2D);
    const Real S = 2.0*exp(vexpo)/p_survival(t); // This is a prefactor to every term, so it also contains
						 // the exponential drift-prefactor.


    // produce the coefficients and the terms in the exponent and put them
    // in the params structure
    for (int n=0; n<MAX_TERMS; n++)
    {
	root_n = this->root_n(n+1);  // get the n-th root of tan(alfa*a)=alfa/-k
	root_n2 = root_n * root_n;
	root_n_r0_s = root_n * (r0-sigma);
	S_Cn_root_n =	S * exp(-D*root_n2*t)
		      * (root_n*cos(root_n_r0_s) + h*sin(root_n_r0_s)) / (L*(root_n2 + h*h) + h)
		      * root_n / (root_n2 + v2Dv2D);

	// store the coefficients in the structure
	parameters.root_n[n] = root_n;
	// also store the values for the exponent
	parameters.S_Cn_root_n[n] = S_Cn_root_n;
    }
    
    // store the random number for the probability
    parameters.rnd = rnd;
    // store the number of terms used
    parameters.terms = MAX_TERMS;
    
    // also store constant prefactors that appear in the calculation of the
    // r-dependent terms
    parameters.H[0] = v2D;		// appears together with z in one of the prefactors
    parameters.H[1] = k/D;		// further constant terms of the cosine prefactor
    parameters.H[2] = h*v2D;		// further constant terms of the sine prefactor
    parameters.H[3] = sigma;


    // find the intersection on the y-axis between the random number and
    // the function
    gsl_function F;
    F.function = &GreensFunction1DRadAbs::drawR_f;
    F.params = &parameters;

    // define a new solver type brent
    const gsl_root_fsolver_type* solverType( gsl_root_fsolver_brent );
    // make a new solver instance
    // TODO: incl typecast?
    gsl_root_fsolver* solver( gsl_root_fsolver_alloc( solverType ) );
    Real r( findRoot( F, solver, sigma, a, EPSILON*L, EPSILON,
                            "GreensFunction1DRadAbs::drawR" ) );

    // return the drawn position
    return r;
}
コード例 #7
0
const Real
FirstPassageGreensFunction1DRad::drawR (const Real rnd, const Real t) const
{
    const Real L(this->getL());
    const Real D(this->getD());
    const Real r0(this->getr0());

    THROW_UNLESS( std::invalid_argument, 0.0 <= rnd && rnd < 1.0 );
    THROW_UNLESS( std::invalid_argument, t >= 0.0 );

    if (t == 0.0 || D == 0)
    {
        // the trivial case
        return r0*this->l_scale;
    }
    if ( L < 0.0 )
    {
        // if the domain had zero size
        return 0.0;
    }

    // the structure to store the numbers to calculate the numbers for 1-S
    struct drawR_params parameters;
    double An = 0;
    double S_Cn_An;
    double tmp0, tmp1;
    const Real h(this->getk()/D);
    const Real S = 2.0/p_survival(t);


    // produce the coefficients and the terms in the exponent and put them
    // in the params structure
    for (int n=0; n<MAX_TERMEN; n++)
    {
        An = a_n (n+1); // get the n-th root of tan(alfa*L)=alfa/-k
        tmp0 = An * An; // An^2
        tmp1 = An * r0; // An * z'
        S_Cn_An = S * exp(-D*tmp0*t) *
                  (An*cos(tmp1) + h*sin(tmp1)) / (L*(tmp0 + h*h) + h);

        // store the coefficients in the structure
        parameters.An[n]     = An;
        // also store the values for the exponent
        parameters.S_Cn_An[n]= S_Cn_An;
        parameters.b_An[n]   = h/An;

    }
    // store the random number for the probability
    parameters.rnd = rnd;
    // store the number of terms used
    parameters.terms = MAX_TERMEN;


    // find the intersection on the y-axis between the random number and
    // the function
    gsl_function F;
    F.function = &FirstPassageGreensFunction1DRad::drawR_f;
    F.params = &parameters;

    // define a new solver type brent
    const gsl_root_fsolver_type* solverType( gsl_root_fsolver_brent );
    // make a new solver instance
    // incl typecast?
    gsl_root_fsolver* solver( gsl_root_fsolver_alloc( solverType ) );
    const Real z( findRoot( F, solver, 0.0, L, EPSILON*L, EPSILON,
                            "FirstPassageGreensFunction1DRad::drawR" ) );

    // return the drawn place
    return z*this->l_scale;
}