示例#1
1
void ode_evaluate(
	CppAD::vector<Float> &x  , 
	size_t m                 , 
	CppAD::vector<Float> &fm )
{
	typedef CppAD::vector<Float> Vector;

	size_t n = x.size();
	size_t ell;
	CPPAD_ASSERT_KNOWN( m == 0 || m == 1,
		"ode_evaluate: m is not zero or one"
	);
	CPPAD_ASSERT_KNOWN( 
		((m==0) & (fm.size()==n)) || ((m==1) & (fm.size()==n*n)),
		"ode_evaluate: the size of fm is not correct"
	);
	if( m == 0 )
		ell = n;
	else	ell = n + n * n;

	// set up the case we are integrating
	Float  ti   = 0.;
	Float  tf   = 1.;
	Float  smin = 1e-5;
	Float smax  = 1.;
	Float scur  = 1.;
	Float erel  = 0.;
	vector<Float> yi(ell), eabs(ell);
	size_t i, j;
	for(i = 0; i < ell; i++)
	{	eabs[i] = 1e-10;
		if( i < n )
			yi[i] = 1.;
		else	yi[i]  = 0.;
	}

	// return values
	Vector yf(ell), ef(ell), maxabs(ell);
	size_t nstep;

	// construct ode method for taking one step
	ode_evaluate_method<Float> method(m, x);

	// solve differential equation
	yf = OdeErrControl(method, 
		ti, tf, yi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);

	if( m == 0 )
	{	for(i = 0; i < n; i++)
			fm[i] = yf[i];
	}
	else
	{	for(i = 0; i < n; i++)
			for(j = 0; j < n; j++)
				fm[i * n + j] = yf[n + i * n + j];
	}
	return;
}
示例#2
0
bool OdeErrMaxabs(void)
{   bool ok = true;     // initial return value

    CppAD::vector<double> w(2);
    w[0] = 10.;
    w[1] = 1.;
    Method method(w);

    CppAD::vector<double> xi(2);
    xi[0] = 1.;
    xi[1] = 0.;

    CppAD::vector<double> eabs(2);
    eabs[0] = 0.;
    eabs[1] = 0.;

    CppAD::vector<double> ef(2);
    CppAD::vector<double> xf(2);
    CppAD::vector<double> maxabs(2);

    double ti   = 0.;
    double tf   = 1.;
    double smin = .5;
    double smax = 1.;
    double scur = .5;
    double erel = 1e-4;

    bool accurate = false;
    while( ! accurate )
    {   xf = OdeErrControl(method,
                           ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs);
        accurate = true;
        size_t i;
        for(i = 0; i < 2; i++)
            accurate &= ef[i] <= erel * maxabs[i];
        if( ! accurate )
            smin = smin / 2;
    }

    double x0 = exp(-w[0]*tf);
    ok &= CppAD::NearEqual(x0, xf[0], erel, 0.);
    ok &= CppAD::NearEqual(0., ef[0], erel, erel);

    double x1 = w[0] * (exp(-w[0]*tf) - exp(-w[1]*tf))/(w[1] - w[0]);
    ok &= CppAD::NearEqual(x1, xf[1], erel, 0.);
    ok &= CppAD::NearEqual(0., ef[1], erel, erel);

    return ok;
}
示例#3
0
bool OdeErrControl_three(void)
{	bool ok = true;     // initial return value

	double alpha = 10.;
	Method_three method(alpha);

	CppAD::vector<double> xi(2);
	xi[0] = 1.;
	xi[1] = 0.;

	CppAD::vector<double> eabs(2);
	eabs[0] = 1e-4;
	eabs[1] = 1e-4;

	// inputs
	double ti   = 0.;
	double tf   = 1.;
	double smin = 1e-4;
	double smax = 1.;
	double scur = 1.;
	double erel = 0.;

	// outputs
	CppAD::vector<double> ef(2);
	CppAD::vector<double> xf(2);
	CppAD::vector<double> maxabs(2);
	size_t nstep;


	xf = OdeErrControl(method,
		ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);


	double x0       = exp( alpha * tf * tf );
	ok &= CppAD::NearEqual(x0, xf[0], 1e-4, 1e-4);
	ok &= CppAD::NearEqual(0., ef[0], 1e-4, 1e-4);

	double root_pi    = sqrt( 4. * atan(1.));
	double root_alpha = sqrt( alpha );
	double x1 = CppAD::erf(alpha * tf) * root_pi / (2 * root_alpha);
	ok &= CppAD::NearEqual(x1, xf[1], 1e-4, 1e-4);
	ok &= CppAD::NearEqual(0., ef[1], 1e-4, 1e-4);

	ok &= method.F.was_negative();

	return ok;
}
示例#4
0
Vector OdeErrControl(
	Method          &method,
	const Scalar    &ti    ,
	const Scalar    &tf    ,
	const Vector    &xi    ,
	const Scalar    &smin  ,
	const Scalar    &smax  ,
	Scalar          &scur  ,
	const Vector    &eabs  ,
	const Scalar    &erel  ,
	Vector          &ef    ,
	Vector          &maxabs)
{	size_t nstep;
	return OdeErrControl(
	method, ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep
	);
}
示例#5
0
bool OdeErrControl_two(void)
{	bool ok = true;     // initial return value

	CppAD::vector<double> w(2);
	w[0] = 10.;
	w[1] = 1.;
	Method_two method(w);

	CppAD::vector<double> xi(2);
	xi[0] = 1.;
	xi[1] = 0.;

	CppAD::vector<double> eabs(2);
	eabs[0] = 1e-4;
	eabs[1] = 1e-4;

	// inputs
	double ti   = 0.;
	double tf   = 1.;
	double smin = 1e-4;
	double smax = 1.;
	double scur = .5;
	double erel = 0.;

	// outputs
	CppAD::vector<double> ef(2);
	CppAD::vector<double> xf(2);
	CppAD::vector<double> maxabs(2);
	size_t nstep;


	xf = OdeErrControl(method,
		ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep);

	double x0 = exp(-w[0]*tf);
	ok &= CppAD::NearEqual(x0, xf[0], 1e-4, 1e-4);
	ok &= CppAD::NearEqual(0., ef[0], 1e-4, 1e-4);

	double x1 = w[0] * (exp(-w[0]*tf) - exp(-w[1]*tf))/(w[1] - w[0]);
	ok &= CppAD::NearEqual(x1, xf[1], 1e-4, 1e-4);
	ok &= CppAD::NearEqual(0., ef[1], 1e-4, 1e-4);

	return ok;
}
示例#6
0
bool OdeErrControl_one(void)
{	bool   ok = true;     // initial return value

	// Runge45 should yield exact results for x_i (t) = t^(i+1), i < 4
	size_t  n = 6;

	// construct method for n component solution
	Method_one method(n);

	// inputs to OdeErrControl

	double ti   = 0.;
	double tf   = .9;
	double smin = 1e-2;
	double smax = 1.;
	double scur = .5;
	double erel = 1e-7;

	CppAD::vector<double> xi(n);
	CppAD::vector<double> eabs(n);
	size_t i;
	for(i = 0; i < n; i++)
	{	xi[i]   = 0.;
		eabs[i] = 0.;
	}

	// outputs from OdeErrControl

	CppAD::vector<double> ef(n);
	CppAD::vector<double> xf(n);

	xf = OdeErrControl(method,
		ti, tf, xi, smin, smax, scur, eabs, erel, ef);

	double check = 1.;
	for(i = 0; i < n; i++)
	{	check *= tf;
		ok &= CppAD::NearEqual(check, xf[i], erel, 0.);
	}

	return ok;
}
示例#7
0
bool OdeErrControl_four(void)
{	bool   ok = true;     // initial return value

	// construct method for n component solution
	size_t  n = 6;
	Method_four method(n);

	// inputs to OdeErrControl

	// special case where scur is converted to ti - tf
	// (so it is not equal to smin)
	double ti   = 0.;
	double tf   = .9;
	double smin = .8;
	double smax = 1.;
	double scur = smin;
	double erel = 1e-7;

	CppAD::vector<double> xi(n);
	CppAD::vector<double> eabs(n);
	size_t i;
	for(i = 0; i < n; i++)
	{	xi[i]   = 0.;
		eabs[i] = 0.;
	}

	// outputs from OdeErrControl
	CppAD::vector<double> ef(n);
	CppAD::vector<double> xf(n);

	xf = OdeErrControl(method,
		ti, tf, xi, smin, smax, scur, eabs, erel, ef);

	// check that Fun_four always returning nan results in nan
	for(i = 0; i < n; i++)
	{	ok &= CppAD::isnan(xf[i]);
		ok &= CppAD::isnan(ef[i]);
	}

	return ok;
}