OdeErrControl: Example and Test Using Maxabs Argument
Keywords: odeerrcontrol: example test using maxabs argument Odeerrcontrol

| Prev | Next |  |  |  |  |  | ode_err_maxabs.cpp | Headings

OdeErrControl: Example and Test Using Maxabs Argument
Define X : R → R 2 by X 0 ( t ) = - exp ( - w 0 t ) X 1 ( t ) = w 0 w 1 - w 0 [ exp ( - w 0 t ) - exp ( - w 1 t ) ] It follows that X 0 ( 0 ) = 1 , X 1 ( 0 ) = 0 and X 0 ( 1 ) ( t ) = - w 0 X 0 ( t ) X 1 ( 1 ) ( t ) = + w 0 X 0 ( t ) - w 1 X 1 ( t ) Note that X 1 ( 0 ) is zero an if w 0 t is large, X 0 ( t ) is near zero. This example tests OdeErrControl using the `maxabs` argument. `

    # include <cstddef>              // for size_t
    # include <cmath>                // for exp
    # include <cppad/utility/ode_err_control.hpp>   // CppAD::OdeErrControl
    # include <cppad/utility/near_equal.hpp>    // CppAD::NearEqual
    # include <cppad/utility/vector.hpp> // CppAD::vector
    # include <cppad/utility/runge_45.hpp>      // CppAD::Runge45

    namespace {
    	// --------------------------------------------------------------
    	class Fun {
    	private:
    		 CppAD::vector<double> w;
    	public:
    		// constructor
    		Fun(const CppAD::vector<double> &w_) : w(w_)
    		{ }

    		// set f = x'(t)
    		void Ode(
    			const double                &t,
    			const CppAD::vector<double> &x,
    			CppAD::vector<double>       &f)
    		{	f[0] = - w[0] * x[0];
    			f[1] = + w[0] * x[0] - w[1] * x[1];
    		}
    	};

    	// --------------------------------------------------------------
    	class Method {
    	private:
    		Fun F;
    	public:
    		// constructor
    		Method(const CppAD::vector<double> &w_) : F(w_)
    		{ }
    		void step(
    			double ta,
    			double tb,
    			CppAD::vector<double> &xa ,
    			CppAD::vector<double> &xb ,
    			CppAD::vector<double> &eb )
    		{	xb = CppAD::Runge45(F, 1, ta, tb, xa, eb);
    		}
    		size_t order(void)
    		{	return 4; }
    	};
    }

    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;
    }

`

Input File: example/ode_err_maxabs.cpp