29 #ifndef Rythmos_CUBIC_SPLINE_INTERPOLATOR_DEF_H 
   30 #define Rythmos_CUBIC_SPLINE_INTERPOLATOR_DEF_H 
   32 #include "Rythmos_CubicSplineInterpolator_decl.hpp" 
   33 #include "Rythmos_InterpolatorBaseHelpers.hpp" 
   34 #include "Thyra_VectorStdOps.hpp" 
   35 #include "Thyra_VectorSpaceBase.hpp" 
   36 #include "Teuchos_VerboseObjectParameterListHelpers.hpp" 
   40 template<
class Scalar>
 
   41 Teuchos::RCP<Rythmos::CubicSplineInterpolator<Scalar> >
 
   42 cubicSplineInterpolator()
 
   44   RCP<CubicSplineInterpolator<Scalar> > csi = Teuchos::rcp(
new CubicSplineInterpolator<Scalar>() );
 
   48 template<
class Scalar>
 
   49 void computeCubicSplineCoeff(
 
   50     const typename DataStore<Scalar>::DataStoreVector_t & data,
 
   51     const Ptr<CubicSplineCoeff<Scalar> > & coeffPtr
 
   54   using Teuchos::outArg;
 
   55   typedef Teuchos::ScalarTraits<Scalar> ST;
 
   56   using Thyra::createMember;
 
   57   TEUCHOS_TEST_FOR_EXCEPTION( 
 
   58       (data.size() < 2), std::logic_error,
 
   59       "Error!  A minimum of two data points is required for this cubic spline." 
   63   Array<Teuchos::RCP<const Thyra::VectorBase<Scalar> > > x_vec, xdot_vec;
 
   64   dataStoreVectorToVector<Scalar>( data, &t, &x_vec, &xdot_vec, NULL );
 
   65 #ifdef HAVE_RYTHMOS_DEBUG 
   66   assertTimePointsAreSorted<Scalar>( t );
 
   67 #endif // HAVE_RYTHMOS_DEBUG 
   70   CubicSplineCoeff<Scalar>& coeff = *coeffPtr;
 
   75     coeff.a.clear(); coeff.b.clear(); coeff.c.clear(); coeff.d.clear();
 
   77     coeff.a.reserve(1); coeff.b.reserve(1); coeff.c.reserve(1); coeff.d.reserve(1);
 
   78     coeff.t.push_back(t[0]);
 
   79     coeff.t.push_back(t[1]);
 
   80     coeff.a.push_back(x_vec[0]->clone_v());
 
   81     coeff.b.push_back(createMember(x_vec[0]->space()));
 
   82     coeff.c.push_back(createMember(x_vec[0]->space()));
 
   83     coeff.d.push_back(createMember(x_vec[0]->space()));
 
   84     Scalar h = coeff.t[1] - coeff.t[0];
 
   85     V_StVpStV(outArg(*coeff.b[0]),ST::one()/h,*x_vec[1],-ST::one()/h,*x_vec[0]);
 
   86     V_S(outArg(*coeff.c[0]),ST::zero());
 
   87     V_S(outArg(*coeff.d[0]),ST::zero());
 
   92   coeff.t.clear(); coeff.t.reserve(n+1);
 
   93   coeff.a.clear(); coeff.a.reserve(n+1);
 
   94   coeff.b.clear(); coeff.b.reserve(n);
 
   95   coeff.c.clear(); coeff.c.reserve(n+1);
 
   96   coeff.d.clear(); coeff.d.reserve(n);
 
   99   Array<RCP<Thyra::VectorBase<Scalar> > > alpha(n), z(n+1);
 
  100   Array<Scalar> l(n+1), mu(n);
 
  101   for (
int i=0 ; i<n ; ++i) {
 
  102     coeff.t.push_back(t[i]);
 
  103     coeff.a.push_back(x_vec[i]->clone_v());
 
  104     coeff.b.push_back(Thyra::createMember(x_vec[0]->space()));
 
  105     coeff.c.push_back(Thyra::createMember(x_vec[0]->space()));
 
  106     coeff.d.push_back(Thyra::createMember(x_vec[0]->space()));
 
  107     alpha[i] = Thyra::createMember(x_vec[0]->space());
 
  108     z[i] = Thyra::createMember(x_vec[0]->space());
 
  110   coeff.a.push_back(x_vec[n]->clone_v());
 
  111   coeff.t.push_back(t[n]);
 
  112   coeff.c.push_back(Thyra::createMember(x_vec[0]->space()));
 
  113   z[n] = Thyra::createMember(x_vec[0]->space());
 
  114   Scalar zero = ST::zero();
 
  115   Scalar one = ST::one();
 
  116   Scalar two = Scalar(2*ST::one());
 
  117   Scalar three = Scalar(3*ST::one());
 
  120   for (
int i=0 ; i<n ; ++i) {
 
  121     h[i] = coeff.t[i+1]-coeff.t[i];
 
  123   for (
int i=1 ; i<n ; ++i) {
 
  124     V_StVpStV(outArg(*(alpha[i])),three/h[i],*coeff.a[i+1],-3/h[i],*coeff.a[i]);
 
  125     Vp_StV(outArg(*(alpha[i])),-three/h[i-1],*coeff.a[i]);
 
  126     Vp_StV(outArg(*(alpha[i])),+three/h[i-1],*coeff.a[i-1]);
 
  130   V_S(outArg(*(z[0])),zero);
 
  131   for (
int i=1 ; i<n ; ++i) {
 
  132     l[i] = 2*(coeff.t[i+1]-coeff.t[i-1])-h[i-1]*mu[i-1];
 
  134     V_StVpStV(outArg(*(z[i])),one/l[i],*alpha[i],-h[i-1]/l[i],*z[i-1]);
 
  137   V_S(outArg(*(z[n])),zero);
 
  138   V_S(outArg(*(coeff.c[n])),zero);
 
  139   for (
int j=n-1 ; j >= 0 ; --j) {
 
  140     V_StVpStV(outArg(*(coeff.c[j])),one,*z[j],-mu[j],*coeff.c[j+1]);
 
  141     V_StVpStV(outArg(*(coeff.b[j])),one/h[j],*coeff.a[j+1],-one/h[j],*coeff.a[j]);
 
  142     Vp_StV(outArg(*(coeff.b[j])),-h[j]/three,*coeff.c[j+1]);
 
  143     Vp_StV(outArg(*(coeff.b[j])),-h[j]*two/three,*coeff.c[j]);
 
  144     V_StVpStV(outArg(*(coeff.d[j])),one/(three*h[j]),*coeff.c[j+1],-one/(three*h[j]),*coeff.c[j]);
 
  147   coeff.a.erase(coeff.a.end()-1);
 
  148   coeff.c.erase(coeff.c.end()-1);
 
  152 template<
class Scalar>
 
  153 void validateCubicSplineCoeff(
const CubicSplineCoeff<Scalar>& coeff) 
 
  155   int t_n = coeff.t.size();
 
  156   int a_n = coeff.a.size();
 
  157   int b_n = coeff.b.size();
 
  158   int c_n = coeff.c.size();
 
  159   int d_n = coeff.d.size();
 
  160   TEUCHOS_TEST_FOR_EXCEPTION( 
 
  161       ((a_n != t_n-1) || (a_n != b_n) || (a_n != c_n) || (a_n != d_n)),
 
  163       "Error!  The sizes of the data structures in the CubicSplineCoeff object do not match" 
  168 template<
class Scalar>
 
  169 void evaluateCubicSpline(
 
  170     const CubicSplineCoeff<Scalar>& coeff,
 
  173     const Ptr<Thyra::VectorBase<Scalar> >& S,
 
  174     const Ptr<Thyra::VectorBase<Scalar> >& Sp, 
 
  175     const Ptr<Thyra::VectorBase<Scalar> >& Spp
 
  178   using Teuchos::outArg;
 
  180   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  182   validateCubicSplineCoeff<Scalar>(coeff);
 
  183   TEUCHOS_TEST_FOR_EXCEPTION( as<Teuchos::Ordinal>(j) >= coeff.a.size(),
 
  184      std::out_of_range, 
"Error!, j is out of range" );
 
  186   Scalar dt = t-coeff.t[j];
 
  187   const Thyra::VectorBase<Scalar>& a = *(coeff.a[j]);
 
  188   const Thyra::VectorBase<Scalar>& b = *(coeff.b[j]);
 
  189   const Thyra::VectorBase<Scalar>& c = *(coeff.c[j]);
 
  190   const Thyra::VectorBase<Scalar>& d = *(coeff.d[j]);
 
  192   if (!Teuchos::is_null(S)) {
 
  195     V_StVpStV(outArg(*S),dt*dt*dt,d,dt*dt,c);
 
  196     Vp_StV(outArg(*S),dt,b);
 
  197     Vp_StV(outArg(*S),ST::one(),a);
 
  199   if (!Teuchos::is_null(Sp)) {
 
  202     V_StVpStV(outArg(*Sp),Scalar(3*ST::one())*dt*dt,d,Scalar(2*ST::one())*dt,c);
 
  203     Vp_StV(outArg(*Sp),ST::one(),b);
 
  205   if (!Teuchos::is_null(Spp)) {
 
  208     V_StVpStV(outArg(*Spp),Scalar(6*ST::one())*dt,d,Scalar(2*ST::one()),c);
 
  215 template<
class Scalar>
 
  218   splineCoeffComputed_ = 
false;
 
  223 template<
class Scalar>
 
  230 template<
class Scalar>
 
  231 RCP<InterpolatorBase<Scalar> >
 
  234   RCP<CubicSplineInterpolator<Scalar> >
 
  236   if (!is_null(parameterList_))
 
  237     interpolator->parameterList_ = parameterList(*parameterList_);
 
  241 template<
class Scalar>
 
  243     const RCP<
const typename DataStore<Scalar>::DataStoreVector_t> & nodesPtr
 
  248   splineCoeffComputed_ = 
false;
 
  249 #ifdef HAVE_RYTHMOS_DEBUG 
  250   const typename DataStore<Scalar>::DataStoreVector_t & nodes = *nodesPtr;
 
  252   nodes_copy_ = Teuchos::rcp(
new typename DataStore<Scalar>::DataStoreVector_t);
 
  253   nodes_copy_->reserve(nodes.size());
 
  254   for (
int i=0 ; i<Teuchos::as<int>(nodes.size()) ; ++i) {
 
  255     nodes_copy_->push_back(*nodes[i].clone());
 
  257 #endif // HAVE_RYTHMOS_DEBUG 
  260 template<
class Scalar>
 
  262   const Array<Scalar> &t_values,
 
  263   typename DataStore<Scalar>::DataStoreVector_t *data_out
 
  267   using Teuchos::outArg;
 
  268   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  270   TEUCHOS_TEST_FOR_EXCEPTION( nodesSet_ == 
false, std::logic_error,
 
  271       "Error!, setNodes must be called before interpolate" 
  273 #ifdef HAVE_RYTHMOS_DEBUG 
  275   assertNodesUnChanged<Scalar>(*nodes_,*nodes_copy_);
 
  277   assertBaseInterpolatePreconditions(*nodes_,t_values,data_out);
 
  278 #endif // HAVE_RYTHMOS_DEBUG 
  281   const RCP<FancyOStream> out = this->getOStream();
 
  282   const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 
 
  283   Teuchos::OSTab ostab(out,1,
"CSI::interpolator");
 
  284   if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
 
  285     *out << 
"nodes_:" << std::endl;
 
  286     for (Teuchos::Ordinal i=0 ; i<(*nodes_).size() ; ++i) {
 
  287       *out << 
"nodes_[" << i << 
"] = " << std::endl;
 
  288       (*nodes_)[i].describe(*out,Teuchos::VERB_EXTREME);
 
  290     *out << 
"t_values = " << std::endl;
 
  291     for (Teuchos::Ordinal i=0 ; i<t_values.size() ; ++i) {
 
  292       *out << 
"t_values[" << i << 
"] = " << t_values[i] << std::endl;
 
  299   if (t_values.size() == 0) {
 
  303   if ((*nodes_).size() == 1) {
 
  306     DataStore<Scalar> DS((*nodes_)[0]);
 
  307     data_out->push_back(DS);
 
  315     for (Teuchos::Ordinal i=0 ; i < (*nodes_).size()-1; ++i) {
 
  316       const Scalar& ti = (*nodes_)[i].time;
 
  317       const Scalar& tip1 = (*nodes_)[i+1].time;
 
  321       while ( range_i.
isInRange(t_values[n]) ) {
 
  323         if (compareTimeValues(t_values[n],ti)==0) {
 
  324           DataStore<Scalar> DS((*nodes_)[i]);
 
  325           data_out->push_back(DS);
 
  327         else if (compareTimeValues(t_values[n],tip1)==0) {
 
  328           DataStore<Scalar> DS((*nodes_)[i+1]);
 
  329           data_out->push_back(DS);
 
  331           if (!splineCoeffComputed_) {
 
  332             computeCubicSplineCoeff<Scalar>(*nodes_,outArg(splineCoeff_));
 
  333             splineCoeffComputed_ = 
true;
 
  335           DataStore<Scalar> DS;
 
  336           RCP<Thyra::VectorBase<Scalar> > x = createMember((*nodes_)[i].x->space());
 
  337           evaluateCubicSpline<Scalar>( splineCoeff_, i, t_values[n], outArg(*x) );
 
  338           DS.time = t_values[n];
 
  340           DS.accuracy = ST::zero();
 
  341           data_out->push_back(DS);
 
  345         if (n == as<int>(t_values.size())) {
 
  356 template<
class Scalar>
 
  363 template<
class Scalar>
 
  366   std::string name = 
"Rythmos::CubicSplineInterpolator";
 
  371 template<
class Scalar>
 
  374   const Teuchos::EVerbosityLevel verbLevel
 
  378   if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) ||
 
  379        (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)     )
 
  382     out << description() << 
"::describe" << std::endl;
 
  384   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW))
 
  386   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM))
 
  388   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH))
 
  393 template <
class Scalar>
 
  395   RCP<ParameterList> 
const& paramList
 
  398   TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
 
  399   paramList->validateParametersAndSetDefaults(*this->getValidParameters());
 
  400   parameterList_ = paramList;
 
  401   Teuchos::readVerboseObjectSublist(&*parameterList_,
this);
 
  405 template <
class Scalar>
 
  409   return(parameterList_);
 
  413 template <
class Scalar>
 
  417   RCP<ParameterList> temp_param_list;
 
  418   std::swap( temp_param_list, parameterList_ );
 
  419   return(temp_param_list);
 
  422 template<
class Scalar>
 
  423 RCP<const Teuchos::ParameterList>
 
  426   static RCP<Teuchos::ParameterList> validPL;
 
  427   if (is_null(validPL)) {
 
  428     RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
 
  429     Teuchos::setupVerboseObjectSublist(&*pl);
 
  443 #define RYTHMOS_CUBIC_SPLINE_INTERPOLATOR_INSTANT(SCALAR) \ 
  445   template class CubicSplineInterpolator< SCALAR >; \ 
  447   template class CubicSplineCoeff< SCALAR >; \ 
  448   template RCP<CubicSplineInterpolator< SCALAR > > cubicSplineInterpolator(); \ 
  449   template void computeCubicSplineCoeff( \ 
  450       const DataStore< SCALAR >::DataStoreVector_t & data, \ 
  451       const Ptr<CubicSplineCoeff< SCALAR > > & coeffPtr \ 
  453   template void validateCubicSplineCoeff(const CubicSplineCoeff< SCALAR >& coeff); \ 
  454   template void evaluateCubicSpline( \ 
  455       const CubicSplineCoeff< SCALAR >& coeff, \ 
  456       Teuchos::Ordinal j,  \ 
  458       const Ptr<Thyra::VectorBase< SCALAR > >& S, \ 
  459       const Ptr<Thyra::VectorBase< SCALAR > >& Sp,  \ 
  460       const Ptr<Thyra::VectorBase< SCALAR > >& Spp \ 
  468 #endif // Rythmos_CUBIC_SPLINE_INTERPOLATOR_DEF_H 
CubicSplineInterpolator()
 
virtual bool isInRange(const TimeType &t) const 
 
void setNodes(const RCP< const typename DataStore< Scalar >::DataStoreVector_t > &nodes)
 
RCP< const Teuchos::ParameterList > getValidParameters() const 
 
RCP< ParameterList > unsetParameterList()
 
RCP< InterpolatorBase< Scalar > > cloneInterpolator() const 
 
Concrete implemenation of InterpolatorBase that implements cubic spline interpolation. 
 
std::string description() const 
 
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const 
 
void setParameterList(RCP< ParameterList > const ¶mList)
 
void interpolate(const Array< Scalar > &t_values, typename DataStore< Scalar >::DataStoreVector_t *data_out) const 
 
RCP< ParameterList > getNonconstParameterList()
 
bool supportsCloning() const