Simbody  3.4 (development)
MeasureImplementation.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_MEASURE_IMPLEMENTATION_H_
00002 #define SimTK_SimTKCOMMON_MEASURE_IMPLEMENTATION_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2008-13 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00027 #include "SimTKcommon/basics.h"
00028 #include "SimTKcommon/Simmatrix.h"
00029 #include "SimTKcommon/internal/State.h"
00030 #include "SimTKcommon/internal/Measure.h"
00031 #include "SimTKcommon/internal/Subsystem.h"
00032 #include "SimTKcommon/internal/System.h"
00033 #include "SimTKcommon/internal/SubsystemGuts.h"
00034 
00035 #include <cmath>
00036 
00037 
00038 namespace SimTK {
00039 
00040 
00041 //==============================================================================
00042 //                    ABSTRACT MEASURE :: IMPLEMENTATION
00043 //==============================================================================
00044 
00048 class SimTK_SimTKCOMMON_EXPORT AbstractMeasure::Implementation {
00049 protected:
00052     Implementation() : copyNumber(0), mySubsystem(0), refCount(0) {}
00053 
00057     Implementation(const Implementation& src)
00058     :   copyNumber(src.copyNumber+1), mySubsystem(0), refCount(0) {}
00059     
00063     Implementation& operator=(const Implementation& src) {
00064         if (&src != this)
00065         {   copyNumber=src.copyNumber+1;
00066             refCount=0; mySubsystem=0; }
00067         return *this; 
00068     }
00069 
00070     // destructor is virtual; below
00071 
00072     // Increment the reference count and return its new value.
00073     int incrRefCount() const {return ++refCount;}
00074 
00075     // Decrement the reference count and return its new value.
00076     int decrRefCount() const {return --refCount;}
00077 
00078     // Get the current value of the reference counter.
00079     int getRefCount() const {return refCount;}
00080 
00081     int           getCopyNumber()  const {return copyNumber;}
00082 
00086     Implementation* clone() const {return cloneVirtual();}
00087 
00088     // realizeTopology() is pure virtual below for Measure_<T> to supply.
00089     void realizeModel       (State& s)       const {realizeMeasureModelVirtual(s);}
00090     void realizeInstance    (const State& s) const {realizeMeasureInstanceVirtual(s);}
00091     void realizeTime        (const State& s) const {realizeMeasureTimeVirtual(s);}
00092     void realizePosition    (const State& s) const {realizeMeasurePositionVirtual(s);}
00093     void realizeVelocity    (const State& s) const {realizeMeasureVelocityVirtual(s);}
00094     void realizeDynamics    (const State& s) const {realizeMeasureDynamicsVirtual(s);}
00095     void realizeAcceleration(const State& s) const {realizeMeasureAccelerationVirtual(s);}
00096     void realizeReport      (const State& s) const {realizeMeasureReportVirtual(s);}
00097 
00101     void initialize(State& s) const {initializeVirtual(s);}
00102 
00103     int getNumTimeDerivatives() const {return getNumTimeDerivativesVirtual();}
00104 
00105     Stage getDependsOnStage(int derivOrder) const {
00106         SimTK_ERRCHK2(0 <= derivOrder && derivOrder <= getNumTimeDerivatives(),
00107             "Measure::getDependsOnStage()",
00108             "derivOrder %d was out of range; this Measure allows 0-%d.",
00109             derivOrder, getNumTimeDerivatives()); 
00110         return getDependsOnStageVirtual(derivOrder); 
00111     }
00112 
00113 
00114     void setSubsystem(Subsystem& sub, MeasureIndex mx) 
00115     {   assert(!mySubsystem && mx.isValid()); 
00116         mySubsystem = &sub; myIndex = mx; }
00117 
00118     bool             isInSubsystem() const {return mySubsystem != 0;}
00119     const Subsystem& getSubsystem() const {assert(mySubsystem); return *mySubsystem;}
00120     Subsystem&       updSubsystem() {assert(mySubsystem); return *mySubsystem;}
00121     MeasureIndex     getSubsystemMeasureIndex() const {assert(mySubsystem); return myIndex;}
00122     SubsystemIndex   getSubsystemIndex() const
00123     {   return getSubsystem().getMySubsystemIndex(); }
00124 
00125     void invalidateTopologyCache() const
00126     {   if (isInSubsystem()) getSubsystem().invalidateSubsystemTopologyCache(); }
00127 
00128     Stage getStage(const State& s) const {return getSubsystem().getStage(s);}
00129 
00130     // VIRTUALS //
00131     // Ordinals must retain the same meaning from release to release
00132     // to preserve binary compatibility.
00133 
00134     /* 0*/virtual ~Implementation() {}
00135     /* 1*/virtual Implementation* cloneVirtual() const = 0;
00136 
00137     /* 2*/virtual void realizeTopology(State&)const = 0;
00138 
00139     /* 3*/virtual void realizeMeasureModelVirtual(State&) const {}
00140     /* 4*/virtual void realizeMeasureInstanceVirtual(const State&) const {}
00141     /* 5*/virtual void realizeMeasureTimeVirtual(const State&) const {}
00142     /* 6*/virtual void realizeMeasurePositionVirtual(const State&) const {}
00143     /* 7*/virtual void realizeMeasureVelocityVirtual(const State&) const {}
00144     /* 8*/virtual void realizeMeasureDynamicsVirtual(const State&) const {}
00145     /* 9*/virtual void realizeMeasureAccelerationVirtual(const State&) const {}
00146     /*10*/virtual void realizeMeasureReportVirtual(const State&) const {}
00147 
00148     /*11*/virtual void initializeVirtual(State&) const {}
00149     /*12*/virtual int  
00150           getNumTimeDerivativesVirtual() const {return 0;}
00151     /*13*/virtual Stage 
00152           getDependsOnStageVirtual(int order) const = 0;
00153 
00154 private:
00155     int             copyNumber; // bumped each time we do a deep copy
00156 
00157     // These are set when this Measure is adopted by a Subsystem.
00158     Subsystem*      mySubsystem;
00159     MeasureIndex    myIndex;
00160 
00161     // Measures have shallow copy semantics so they share the Implementation 
00162     // objects, which are only deleted when the refCount goes to zero.
00163     mutable int     refCount;
00164 
00165 friend class AbstractMeasure;
00166 friend class Subsystem::Guts;
00167 friend class Subsystem::Guts::GutsRep;
00168 };
00169 
00170 //==============================================================================
00171 //                      ABSTRACT MEASURE DEFINITIONS
00172 //==============================================================================
00173 // These had to wait for AbstractMeasure::Implementation to be defined.
00174 
00175 inline AbstractMeasure::
00176 AbstractMeasure(Implementation* g) 
00177 :   impl(g)
00178 {   if (impl) impl->incrRefCount(); }
00179 
00180 inline AbstractMeasure::
00181 AbstractMeasure(Subsystem& sub, Implementation* g, const SetHandle&) 
00182 :   impl(g) {
00183     SimTK_ERRCHK(hasImpl(), "AbstractMeasure::AbstractMeasure()",
00184         "An empty Measure handle can't be put in a Subsystem.");
00185     impl->incrRefCount();
00186     sub.adoptMeasure(*this);
00187 }
00188 
00189 // Shallow copy constructor.
00190 inline AbstractMeasure::AbstractMeasure(const AbstractMeasure& src) 
00191 :   impl(0) {
00192     if (src.impl) {
00193         impl = src.impl;
00194         impl->incrRefCount();
00195     }
00196 }
00197 
00198 // Shallow assignment.
00199 inline AbstractMeasure& AbstractMeasure::
00200 shallowAssign(const AbstractMeasure& src) {
00201     if (impl != src.impl) {
00202         if (impl && impl->decrRefCount()==0) delete impl;
00203         impl = src.impl;
00204         impl->incrRefCount();
00205     }
00206     return *this;
00207 }
00208 
00209 // Note that even if the source and destination are currently pointing
00210 // to the same Implementation, we still have to make a new copy so that
00211 // afterwards the destination has its own, refcount==1 copy.
00212 inline AbstractMeasure& AbstractMeasure::
00213 deepAssign(const AbstractMeasure& src) {
00214     if (&src != this) {
00215         if (impl && impl->decrRefCount()==0) delete impl;
00216         if (src.impl) {
00217             impl = src.impl->clone();
00218             impl->incrRefCount();
00219         } else
00220             impl = 0;
00221     }
00222     return *this;
00223 }
00224 
00225 inline AbstractMeasure::
00226 ~AbstractMeasure()
00227 {   if (impl && impl->decrRefCount()==0) delete impl;}
00228 
00229 inline bool AbstractMeasure::
00230 isInSubsystem() const
00231 {   return hasImpl() && getImpl().isInSubsystem(); }
00232 
00233 inline const Subsystem& AbstractMeasure::
00234 getSubsystem() const
00235 {   return getImpl().getSubsystem(); }
00236 
00237 inline MeasureIndex AbstractMeasure::
00238 getSubsystemMeasureIndex() const
00239 {   return getImpl().getSubsystemMeasureIndex();}
00240 
00241 inline int AbstractMeasure::
00242 getNumTimeDerivatives() const
00243 {   return getImpl().getNumTimeDerivatives(); }
00244 
00245 inline Stage AbstractMeasure::
00246 getDependsOnStage(int derivOrder) const
00247 {   return getImpl().getDependsOnStage(derivOrder); }
00248 
00249 inline int AbstractMeasure::
00250 getRefCount() const
00251 {   return getImpl().getRefCount(); }
00252 
00253  // Hide from Doxygen.
00255 // This is a helper class that makes it possible to treat Real, Vec, and 
00256 // Vector objects uniformly.
00257 template <class T> class Measure_Num {
00258 };
00259 
00260 template <> class Measure_Num<float> {
00261 public:
00262     typedef float Element;
00263     static int size(const float&) {return 1;}
00264     static const float& get(const float& v, int i) {assert(i==0); return v;}
00265     static float& upd(float& v, int i) {assert(i==0); return v;}
00266     static void makeNaNLike(const float&, float& nanValue) 
00267     {   nanValue = CNT<float>::getNaN();}
00268     static void makeZeroLike(const float&, float& zeroValue) {zeroValue=0.f;}
00269 };
00270 
00271 template <> class Measure_Num<double> {
00272 public:
00273     typedef double Element;
00274     static int size(const double&) {return 1;}
00275     static const double& get(const double& v, int i) {assert(i==0); return v;}
00276     static double& upd(double& v, int i) {assert(i==0); return v;}
00277     static void makeNaNLike(const double&, double& nanValue) 
00278     {  nanValue = CNT<double>::getNaN(); }
00279     static void makeZeroLike(const double&, double& zeroValue) {zeroValue=0.;}
00280 };
00281 
00282 // We only support stride 1 (densely packed) Vec types.
00283 template <int M, class E>
00284 class Measure_Num< Vec<M,E,1> > {
00285     typedef Vec<M,E,1> T;
00286 public:
00287     typedef E Element;
00288     static int size(const T&) {return M;}
00289     static const E& get(const T& v, int i) {return v[i];}
00290     static E& upd(T& v, int i) {return v[i];}
00291     static void makeNaNLike (const T&, T& nanValue)  {nanValue.setToNaN();}
00292     static void makeZeroLike(const T&, T& zeroValue) {zeroValue.setToZero();}
00293 };
00294 
00295 // We only support column major (densely packed) Mat types.
00296 template <int M, int N, class E>
00297 class Measure_Num< Mat<M,N,E> > {
00298     typedef Mat<M,N,E> T;
00299 public:
00300     typedef E Element;
00301     static int size(const T&) {return N;} // number of columns
00302     static const typename T::TCol& get(const T& m, int j) {return m.col(j);}
00303     static typename T::TCol& upd(T& m, int j) {return m.col(j);}
00304     static void makeNaNLike (const T&, T& nanValue)  {nanValue.setToNaN();}
00305     static void makeZeroLike(const T&, T& zeroValue) {zeroValue.setToZero();}
00306 };
00307 
00308 
00309 template <class E>
00310 class Measure_Num< Vector_<E> > {
00311     typedef Vector_<E> T;
00312 public:
00313     typedef E Element;
00314     static int size(const T& v) {return v.size();}
00315     static const E& get(const T& v, int i) {return v[i];}
00316     static E& upd(T& v, int i) {return v[i];}
00317     static void makeNaNLike(const T& v, T& nanValue) 
00318     {   nanValue.resize(v.size()); nanValue.setToNaN(); }
00319     static void makeZeroLike(const T& v, T& zeroValue)
00320     {   zeroValue.resize(v.size()); zeroValue.setToZero(); }
00321 
00322 };
00323 
00326 //==============================================================================
00327 //                       MEASURE_<T> :: IMPLEMENTATION
00328 //==============================================================================
00335 template <class T>
00336 class Measure_<T>::Implementation : public AbstractMeasure::Implementation {
00337 public:
00338     const T& getValue(const State& s, int derivOrder) const {
00339         SimTK_ERRCHK2(0 <= derivOrder && derivOrder <= getNumTimeDerivatives(),
00340             "Measure_<T>::getValue()",
00341             "derivOrder %d was out of range; this Measure allows 0-%d.",
00342             derivOrder, getNumTimeDerivatives()); 
00343 
00344         // We require the stage to have been advanced to at least the one
00345         // before this measure's depends-on stage since this will get called
00346         // towards the end of the depends-on stage realization.
00347         if (getDependsOnStage(derivOrder) != Stage::Empty) {
00348             Stage prevStage = getDependsOnStage(derivOrder).prev();
00349 
00350             SimTK_ERRCHK2
00351                 (   ( isInSubsystem() && getStage(s)>=prevStage)
00352                  || (!isInSubsystem() && s.getSystemStage()>=prevStage),
00353                 "Measure_<T>::getValue()",
00354                 "Expected State to have been realized to at least stage "
00355                 "%s but stage was %s.", 
00356                 prevStage.getName().c_str(), 
00357                 (isInSubsystem() ? getStage(s) : s.getSystemStage())
00358                     .getName().c_str());
00359         }
00360 
00361         if (derivOrder < getNumCacheEntries()) {
00362             if (!isCacheValueRealized(s,derivOrder)) {
00363                 T& value = updCacheEntry(s,derivOrder);
00364                 calcCachedValueVirtual(s, derivOrder, value);
00365                 markCacheValueRealized(s,derivOrder);
00366                 return value;
00367             }
00368             return getCacheEntry(s,derivOrder);
00369         }
00370 
00371         // We can't handle it here -- punt to the concrete Measure
00372         // for higher order derivatives.
00373         return getUncachedValueVirtual(s,derivOrder); 
00374     }
00375 
00378     void setDefaultValue(const T& defaultValue) {
00379         this->defaultValue = defaultValue;
00380         Measure_Num<T>::makeZeroLike(defaultValue, zeroValue);
00381         this->invalidateTopologyCache(); 
00382     }
00383 
00387     const T& getDefaultValue() const {return defaultValue;}
00388 
00389     void setIsPresumedValidAtDependsOnStage(bool presume) 
00390     {   presumeValidAtDependsOnStage = presume;
00391         this->invalidateTopologyCache(); }
00392 
00393     bool getIsPresumedValidAtDependsOnStage() const 
00394     {   return presumeValidAtDependsOnStage; }
00395 
00396 protected:
00397     explicit Implementation(const T& defaultValue, int numCacheEntries=1)
00398     :   presumeValidAtDependsOnStage(false),
00399         defaultValue(defaultValue),
00400         derivIx(numCacheEntries) 
00401     {
00402         Measure_Num<T>::makeZeroLike(defaultValue, zeroValue);
00403     }
00404 
00408     explicit Implementation(int numCacheEntries=1) 
00409     :   presumeValidAtDependsOnStage(false),
00410         defaultValue(),
00411         derivIx(numCacheEntries) 
00412     {
00413         Measure_Num<T>::makeZeroLike(defaultValue, zeroValue);
00414     }
00415 
00419     Implementation(const Implementation& source) 
00420     :   presumeValidAtDependsOnStage(source.presumeValidAtDependsOnStage),
00421         defaultValue(source.defaultValue),
00422         derivIx(source.derivIx.size()) 
00423     {
00424         Measure_Num<T>::makeZeroLike(defaultValue, zeroValue);
00425     }
00426 
00427 
00430     int size() const {return Measure_Num<T>::size(defaultValue);}
00431 
00434     int getNumCacheEntries() const {return (int)derivIx.size();}
00435 
00439     const T& getCacheEntry(const State& s, int derivOrder) const {
00440         SimTK_ERRCHK2(0 <= derivOrder && derivOrder < getNumCacheEntries(),
00441             "Measure_<T>::Implementation::getCacheEntry()",
00442             "Derivative order %d is out of range; only %d cache entries"
00443             " were allocated.", derivOrder, getNumCacheEntries());
00444 
00445         return Value<T>::downcast(
00446             this->getSubsystem().getCacheEntry(s, derivIx[derivOrder]));
00447     }
00448 
00452     T& updCacheEntry(const State& s, int derivOrder) const {
00453         SimTK_ERRCHK2(0 <= derivOrder && derivOrder < getNumCacheEntries(),
00454             "Measure_<T>::Implementation::updCacheEntry()",
00455             "Derivative order %d is out of range; only %d cache entries"
00456             " were allocated.", derivOrder, getNumCacheEntries());
00457 
00458         return Value<T>::updDowncast(
00459             this->getSubsystem().updCacheEntry(s, derivIx[derivOrder]));
00460     }
00461 
00464     bool isCacheValueRealized(const State& s, int derivOrder) const {
00465         SimTK_ERRCHK2(0 <= derivOrder && derivOrder < getNumCacheEntries(),
00466             "Measure_<T>::Implementation::isCacheValueRealized()",
00467             "Derivative order %d is out of range; only %d cache entries"
00468             " were allocated.", derivOrder, getNumCacheEntries());
00469 
00470         return this->getSubsystem().isCacheValueRealized(s, derivIx[derivOrder]);
00471     }
00472 
00476     void markCacheValueRealized(const State& s, int derivOrder) const {
00477         SimTK_ERRCHK2(0 <= derivOrder && derivOrder < getNumCacheEntries(),
00478             "Measure_<T>::Implementation::markCacheValueRealized()",
00479             "Derivative order %d is out of range; only %d cache entries"
00480             " were allocated.", derivOrder, getNumCacheEntries());
00481 
00482         this->getSubsystem().markCacheValueRealized(s, derivIx[derivOrder]);
00483     }
00484 
00489     void markCacheValueNotRealized(const State& s, int derivOrder) const {
00490         SimTK_ERRCHK2(0 <= derivOrder && derivOrder < getNumCacheEntries(),
00491             "Measure_<T>::Implementation::markCacheValueNotRealized()",
00492             "Derivative order %d is out of range; only %d cache entries"
00493             " were allocated.", derivOrder, getNumCacheEntries());
00494 
00495         this->getSubsystem().markCacheValueNotRealized(s, derivIx[derivOrder]);
00496     }
00497 
00498     // VIRTUALS //
00499     // Ordinals must retain the same meaning from release to release
00500     // to preserve binary compatibility.
00501 
00504     /* 0*/virtual void realizeMeasureTopologyVirtual(State&) const
00505     {}
00506 
00509     /* 1*/virtual void 
00510     calcCachedValueVirtual(const State&, int derivOrder, T& value) const
00511     {   SimTK_ERRCHK1_ALWAYS(!"implemented", 
00512         "Measure_<T>::Implementation::calcCachedValueVirtual()",
00513         "This method should have been overridden by the derived"
00514         " Measure but was not. It is needed to calculate the"
00515         " cached value for derivOrder=%d.", derivOrder); }
00516 
00522     /* 2*/virtual const T& 
00523     getUncachedValueVirtual(const State&, int derivOrder) const
00524     {   SimTK_ERRCHK1_ALWAYS(!"implemented", 
00525             "Measure_<T>::Implementation::getUncachedValueVirtual()",
00526             "This method should have been overridden by the derived"
00527             " Measure but was not. It is needed to return the uncached"
00528             " value at derivOrder=%d.", derivOrder);
00529         return *reinterpret_cast<T*>(0);
00530     }
00531 
00534     const T& getValueZero() const {return zeroValue;}
00535 
00536 private:
00537     // Satisfy the realizeTopology() pure virtual here now that we know the 
00538     // data type T. Allocate lazy- or auto-validated- cache entries depending 
00539     // on the setting of presumeValidAtDependsOnStage.
00540     void realizeTopology(State& s) const FINAL_11 {
00541         // Allocate cache entries. Initialize the value cache entry to
00542         // the given defaultValue; all the derivative cache entries should be
00543         // initialized to a NaN of the same size.
00544         if (getNumCacheEntries()) {
00545             derivIx[0] = presumeValidAtDependsOnStage 
00546                 ? this->getSubsystem().allocateCacheEntry
00547                         (s, getDependsOnStage(0), new Value<T>(defaultValue))
00548                 : this->getSubsystem().allocateLazyCacheEntry
00549                         (s, getDependsOnStage(0), new Value<T>(defaultValue));
00550 
00551             if (getNumCacheEntries() > 1) {
00552                 T nanValue; Measure_Num<T>::makeNaNLike(defaultValue, nanValue);
00553                 for (int i=1; i < getNumCacheEntries(); ++i) {
00554                     derivIx[i] = presumeValidAtDependsOnStage 
00555                         ? this->getSubsystem().allocateCacheEntry
00556                             (s, getDependsOnStage(i), new Value<T>(nanValue))
00557                         : this->getSubsystem().allocateLazyCacheEntry
00558                             (s, getDependsOnStage(i), new Value<T>(nanValue));
00559                 }
00560             }
00561         }
00562 
00563         // Call the concrete class virtual if any.
00564         realizeMeasureTopologyVirtual(s);
00565     }
00566 
00567 //------------------------------------------------------------------------------
00568 private:
00569     // TOPOLOGY STATE
00570     bool    presumeValidAtDependsOnStage;
00571     T       defaultValue;
00572     T       zeroValue;
00573 
00574     // TOPOLOGY CACHE
00575     mutable Array_<CacheEntryIndex> derivIx;
00576 };
00577 
00578 
00579 
00580 //==============================================================================
00581 //                       CONSTANT :: IMPLEMENTATION
00582 //==============================================================================
00583 template <class T>
00584 class Measure_<T>::Constant::Implementation 
00585 :   public Measure_<T>::Implementation 
00586 {
00587 public:
00588     // We don't want the base class to allocate *any* cache entries.
00589     Implementation() : Measure_<T>::Implementation(0) {}
00590     explicit Implementation(const T& value) 
00591     :   Measure_<T>::Implementation(value,0) {}
00592 
00595     void setValue(const T& v) {this->setDefaultValue(v);}
00596 
00597     // Implementations of virtual methods.
00598     // Measure_<T> virtuals:
00599     // No cached values.
00600 
00601     const T& getUncachedValueVirtual(const State&, int derivOrder) const 
00602         OVERRIDE_11
00603     {   return derivOrder>0 ? this->getValueZero() : this->getDefaultValue(); }
00604 
00605     // AbstractMeasure virtuals:
00606     Implementation* cloneVirtual() const OVERRIDE_11
00607     {   return new Implementation(*this); }
00608     Stage getDependsOnStageVirtual(int derivOrder) const OVERRIDE_11 
00609     {   return derivOrder>0 ? Stage::Empty : Stage::Topology; }
00610     int getNumTimeDerivativesVirtual() const OVERRIDE_11 
00611     {   return std::numeric_limits<int>::max(); }
00612 };
00613 
00614 
00615 
00616 //==============================================================================
00617 //                        MEASURE ZERO and ONE
00618 //==============================================================================
00619 // These had to wait for Constant::Implementation to be declared.
00620 
00621 template <class T> inline
00622 Measure_<T>::Zero::Zero() : Constant(T(0)) {}
00623 template <class T> inline
00624 Measure_<T>::Zero::Zero(Subsystem& sub) : Constant(sub, T(0)) {}
00625 
00626 inline Measure_< Vector >::Zero::Zero(int size) 
00627 :   Constant(Vector(size, Real(0))) {}
00628 inline Measure_< Vector >::Zero::Zero(Subsystem& sub, int size) 
00629 :  Constant(sub, Vector(size, Real(0))) {}
00630 
00631 template <class T> inline
00632 Measure_<T>::One::One() : Constant(T(1)) {}
00633 template <class T> inline
00634 Measure_<T>::One::One(Subsystem& sub) : Constant(sub, T(1)) {}
00635 
00636 inline Measure_< Vector >::One::One(int size) 
00637 :   Constant(Vector(size, Real(1))) {}
00638 inline Measure_< Vector >::One::One(Subsystem& sub, int size) 
00639 :  Constant(sub, Vector(size, Real(1))) {}
00640 
00641 
00642 
00643 //==============================================================================
00644 //                         TIME :: IMPLEMENTATION
00645 //==============================================================================
00646 template <class T>
00647 class Measure_<T>::Time::Implementation {};
00648 
00649 template <>
00650 class Measure_<Real>::Time::Implementation 
00651 :   public Measure_<Real>::Implementation 
00652 {
00653 public:
00654     // We don't want the base class to allocate *any* cache entries.
00655     Implementation() : Measure_<Real>::Implementation(0) {}
00656 
00657     // Implementations of virtual methods.
00658     // Measure_<Real> virtuals:
00659     // No cached values.
00660 
00661     const Real& getUncachedValueVirtual(const State& s, int derivOrder) const
00662         OVERRIDE_11
00663     {   return derivOrder==0 ? s.getTime()
00664             : (derivOrder==1 ? SimTK::One 
00665                              : SimTK::Zero); } 
00666 
00667     // AbstractMeasure virtuals:
00668     Implementation* cloneVirtual() const OVERRIDE_11
00669     {   return new Implementation(*this); }
00670     Stage getDependsOnStageVirtual(int derivOrder) const OVERRIDE_11
00671     {   return derivOrder>0 ? Stage::Empty : Stage::Time; }
00672 
00673     // Value is t, 1st derivative is 1, the rest are 0.
00674     int getNumTimeDerivativesVirtual() const OVERRIDE_11 
00675     {   return std::numeric_limits<int>::max(); }
00676 };
00677 
00678 
00679 
00680 //==============================================================================
00681 //                        VARIABLE :: IMPLEMENTATION
00682 //==============================================================================
00683 template <class T>
00684 class Measure_<T>::Variable::Implementation 
00685 :   public Measure_<T>::Implementation 
00686 {
00687 public:
00688     // We don't want the base class to allocate *any* cache entries;
00689     // we'll use the variable as its own value and zeroes for all
00690     // the derivatives.
00691     Implementation() 
00692     :   Measure_<T>::Implementation(0),
00693         invalidatedStage(Stage::Empty) {}
00694 
00695     Implementation(Stage invalidated, const T& defaultValue) 
00696     :   Measure_<T>::Implementation(defaultValue, 0),
00697         invalidatedStage(invalidated) {}
00698 
00699     // Copy constructor should not copy the variable.
00700     Implementation(const Implementation& source)
00701     :   Measure_<T>::Implementation(source.getDefaultValue(), 0),
00702         invalidatedStage(source.invalidatedStage) {}
00703 
00704     void setInvalidatedStage(Stage invalidates) {
00705         invalidatedStage = invalidates;
00706         this->invalidateTopologyCache();
00707     }
00708 
00709     Stage getInvalidatedStage() const {return invalidatedStage;}
00710 
00714     void setValue(State& state, const T& value) const 
00715     {   updVarValue(state) = value; }
00716 
00717     // Implementations of virtual methods.
00718     Implementation* cloneVirtual() const OVERRIDE_11
00719     {   return new Implementation(*this); }
00720 
00721     int getNumTimeDerivativesVirtual() const OVERRIDE_11 
00722     {   return std::numeric_limits<int>::max(); }
00723 
00724     // Discrete variable is available after Model stage; but all its 
00725     // derivatives are zero so are always available.
00726     Stage getDependsOnStageVirtual(int derivOrder) const OVERRIDE_11 
00727     {   return derivOrder>0 ? Stage::Empty : Stage::Model;}
00728 
00729     const T& getUncachedValueVirtual(const State& s, int derivOrder) const
00730         OVERRIDE_11
00731     {   return derivOrder>0 ? this->getValueZero() : getVarValue(s); }
00732 
00733     // No cached values.
00734 
00735     void realizeMeasureTopologyVirtual(State& s) const OVERRIDE_11 {
00736         discreteVarIndex = this->getSubsystem().allocateDiscreteVariable
00737             (s, invalidatedStage, new Value<T>(this->getDefaultValue()));
00738     }
00739 private:
00740     const T& getVarValue(const State& s) const {
00741         assert(discreteVarIndex.isValid());
00742         return Value<T>::downcast(
00743             this->getSubsystem().getDiscreteVariable(s, discreteVarIndex));
00744     }
00745     T& updVarValue(State& s) const {
00746         assert(discreteVarIndex.isValid());
00747         return Value<T>::downcast(
00748             this->getSubsystem().updDiscreteVariable(s, discreteVarIndex));
00749     }
00750 
00751     // TOPOLOGY STATE
00752     Stage   invalidatedStage; // TODO this shouldn't be needed
00753 
00754     // TOPOLOGY CACHE
00755     mutable DiscreteVariableIndex discreteVarIndex;
00756 };
00757 
00758 
00759 
00760 //==============================================================================
00761 //                         RESULT :: IMPLEMENTATION
00762 //==============================================================================
00763 template <class T>
00764 class Measure_<T>::Result::Implementation 
00765 :   public Measure_<T>::Implementation 
00766 {
00767 public:
00768     // We want the base class to allocate a single cache entry of type T.
00769     Implementation() 
00770     :   Measure_<T>::Implementation(1), 
00771         dependsOnStage(Stage::Topology), invalidatedStage(Stage::Infinity) {}
00772 
00773     Implementation(Stage dependsOn, Stage invalidated) 
00774     :   Measure_<T>::Implementation(1), 
00775         dependsOnStage(dependsOn==Stage::Empty ? Stage::Topology : dependsOn), 
00776         invalidatedStage(invalidated)
00777     {   SimTK_ERRCHK2_ALWAYS(invalidated > dependsOn,"Measure::Result::ctor()",
00778             "Got invalidated stage %s and dependsOn stage %s which is illegal "
00779             "because the invalidated stage must be later than dependsOn.",
00780             invalidated.getName().c_str(), dependsOn.getName().c_str());
00781     }
00782 
00783     // Copy constructor will not copy the cache entry index.
00784     Implementation(const Implementation& source)
00785     :   Measure_<T>::Implementation(source),
00786         dependsOnStage(source.dependsOnStage), 
00787         invalidatedStage(source.invalidatedStage) {} 
00788 
00789     void setDependsOnStage(Stage dependsOn) {
00790         if (dependsOn == Stage::Empty) dependsOn = Stage::Topology;
00791         SimTK_ERRCHK2_ALWAYS(dependsOn < getInvalidatedStage(),
00792             "Measure::Result::setDependsOnStage()",
00793             "The provided dependsOn stage %s is illegal because it is not "
00794             "less than the current invalidated stage %s. Change the "
00795             "invalidated stage first with setInvalidatedStage().",
00796             dependsOn.getName().c_str(), 
00797             getInvalidatedStage().getName().c_str());
00798 
00799         dependsOnStage = dependsOn;
00800         this->invalidateTopologyCache();
00801     }
00802 
00803     void setInvalidatedStage(Stage invalidated) {
00804         SimTK_ERRCHK2_ALWAYS(invalidated > getDependsOnStage(),
00805             "Measure::Result::setInvalidatedStage()",
00806             "The provided invalidated stage %s is illegal because it is not "
00807             "greater than the current dependsOn stage %s. Change the "
00808             "dependsOn stage first with setDependsOnStage().",
00809             invalidated.getName().c_str(),
00810             getDependsOnStage().getName().c_str());
00811 
00812         invalidatedStage = invalidated;
00813         this->invalidateTopologyCache();
00814     }
00815 
00816 
00817     Stage getDependsOnStage()   const {return dependsOnStage;}
00818     Stage getInvalidatedStage() const {return invalidatedStage;}
00819 
00820 
00821     void markAsValid(const State& state) const
00822     {   const Stage subsystemStage = this->getSubsystem().getStage(state);
00823         SimTK_ERRCHK3_ALWAYS(subsystemStage >= getDependsOnStage().prev(),
00824             "Measure::Result::markAsValid()",
00825             "This Result Measure cannot be marked valid in a State where this "
00826             "measure's Subsystem has been realized only to stage %s, because "
00827             "its value was declared to depend on stage %s. To mark it valid, "
00828             "we require that the State have been realized at least to the "
00829             "previous stage (%s in this case); that is, you must at least be "
00830             "*working on* the dependsOn stage in order to claim this result is "
00831             "available.",
00832             subsystemStage.getName().c_str(),
00833             getDependsOnStage().getName().c_str(),
00834             getDependsOnStage().prev().getName().c_str());
00835         this->markCacheValueRealized(state, 0); }
00836 
00837     bool isValid(const State& state) const
00838     {   return this->isCacheValueRealized(state, 0); }
00839     
00840     void markAsNotValid(const State& state) const
00841     {   this->markCacheValueNotRealized(state, 0); 
00842         state.invalidateAllCacheAtOrAbove(invalidatedStage); }
00843 
00844     T& updValue(const State& state) const 
00845     {   markAsNotValid(state); return this->updCacheEntry(state, 0); }
00846 
00847 
00848     // Implementations of virtual methods.
00849     Implementation* cloneVirtual() const OVERRIDE_11
00850     {   return new Implementation(*this); }
00851 
00852     int getNumTimeDerivativesVirtual() const OVERRIDE_11 {return 0;} 
00853 
00856     Stage getDependsOnStageVirtual(int derivOrder) const OVERRIDE_11 
00857     {   return derivOrder>0 ? Stage::Empty : dependsOnStage;}
00858 
00859     void calcCachedValueVirtual(const State&, int derivOrder, T& value) const
00860         OVERRIDE_11
00861     {   SimTK_ERRCHK_ALWAYS(!"calcCachedValueVirtual() implemented",
00862         "Measure_<T>::Result::getValue()",
00863         "Measure_<T>::Result::getValue() was called when the value was not "
00864         "yet valid. For most Measure types, this would have initiated "
00865         "computation of the value, but Result measures must have their values "
00866         "calculated and set externally, and then marked valid."); }
00867 
00868 private:
00869     // TOPOLOGY STATE
00870     Stage   dependsOnStage;
00871     Stage   invalidatedStage;
00872 };
00873 
00874 
00875 
00876 //==============================================================================
00877 //                        SINUSOID :: IMPLEMENTATION
00878 //==============================================================================
00879 template <class T>
00880 class Measure_<T>::Sinusoid::Implementation
00881 :   public Measure_<T>::Implementation 
00882 {
00883     static const int NumDerivs = 3;
00884 public:
00885     Implementation() 
00886     :   Measure_<T>::Implementation(NumDerivs+1),
00887         a(CNT<T>::getNaN()), w(CNT<T>::getNaN()), p(CNT<T>::getNaN()) {}
00888 
00889     Implementation(const T& amplitude, 
00890                    const T& frequency, 
00891                    const T& phase=T(0))
00892     :   Measure_<T>::Implementation(NumDerivs+1),
00893         a(amplitude), w(frequency), p(phase) {}
00894 
00895     // Default copy constructor is fine.
00896 
00897     // Implementations of virtual methods.
00898     Implementation* cloneVirtual() const OVERRIDE_11
00899     {   return new Implementation(*this); }
00900 
00901     int getNumTimeDerivativesVirtual() const OVERRIDE_11 {return NumDerivs;}
00902 
00903     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11 
00904     {   return Stage::Time; }
00905 
00906     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
00907         OVERRIDE_11
00908     {
00909         // We need to allow the compiler to select std::sin or SimTK::sin
00910         // based on the argument type.
00911         using std::sin; using std::cos;
00912 
00913         assert(NumDerivs == 3);
00914         const Real t = s.getTime();
00915         const T arg = w*t + p;
00916 
00917         switch (derivOrder) {
00918         case 0: value =        a*sin(arg); break;
00919         case 1: value =      w*a*cos(arg); break;
00920         case 2: value =   -w*w*a*sin(arg); break;
00921         case 3: value = -w*w*w*a*cos(arg); break;
00922         default: SimTK_ASSERT1_ALWAYS(!"out of range",
00923                      "Measure::Sinusoid::Implementation::calcCachedValueVirtual():"
00924                      " derivOrder %d is out of range 0-3.", derivOrder);
00925         }
00926     }
00927 
00928     // There are no uncached values.
00929 
00930 private:
00931     // TOPOLOGY STATE
00932     T a, w, p;
00933 
00934     // TOPOLOGY CACHE
00935     // nothing
00936 };
00937 
00938 
00939 
00940 //==============================================================================
00941 //                          PLUS :: IMPLEMENTATION
00942 //==============================================================================
00943 template <class T>
00944 class Measure_<T>::Plus::Implementation : public Measure_<T>::Implementation {
00945 public:
00946     // TODO: Currently allocates just one cache entry.
00947     // left and right will be empty handles.
00948     Implementation() {}
00949 
00950     Implementation(const Measure_<T>& left, 
00951                    const Measure_<T>& right)
00952     :   left(left), right(right) {}
00953 
00954     // Default copy constructor gives us a new Implementation object,
00955     // but with references to the *same* operand measures.
00956 
00957     // Implementations of virtual methods.
00958 
00959     // This uses the default copy constructor.
00960     Implementation* cloneVirtual() const OVERRIDE_11 
00961     {   return new Implementation(*this); }
00962 
00963     // TODO: Let this be settable up to the min number of derivatives 
00964     // provided by the arguments.
00965     int getNumTimeDerivativesVirtual() const OVERRIDE_11 {return 0;} 
00966     //{   return std::min(left.getNumTimeDerivatives(), 
00967     //                    right.getNumTimeDerivatives()); }
00968 
00969     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11 
00970     {   return Stage(std::max(left.getDependsOnStage(order),
00971                               right.getDependsOnStage(order))); }
00972 
00973 
00974     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
00975         OVERRIDE_11
00976     {
00977         value = left.getValue(s,derivOrder) + right.getValue(s,derivOrder);
00978     }
00979 
00980     // There are no uncached values.
00981 
00982 private:
00983     // TOPOLOGY STATE
00984     Measure_<T> left;
00985     Measure_<T> right;
00986 
00987     // TOPOLOGY CACHE
00988     // nothing
00989 };
00990 
00991 
00992 
00993 //==============================================================================
00994 //                          MINUS :: IMPLEMENTATION
00995 //==============================================================================
00996 template <class T>
00997 class Measure_<T>::Minus::Implementation : public Measure_<T>::Implementation {
00998 public:
00999     // TODO: Currently allocates just one cache entry.
01000     // left and right will be empty handles.
01001     Implementation() {}
01002 
01003     Implementation(const Measure_<T>& left, 
01004                    const Measure_<T>& right)
01005     :   left(left), right(right) {}
01006 
01007     // Default copy constructor gives us a new Implementation object,
01008     // but with references to the *same* operand measures.
01009 
01010     // Implementations of virtual methods.
01011 
01012     // This uses the default copy constructor.
01013     Implementation* cloneVirtual() const OVERRIDE_11 
01014     {   return new Implementation(*this); }
01015 
01016     // TODO: Let this be settable up to the min number of derivatives 
01017     // provided by the arguments.
01018     int getNumTimeDerivativesVirtual() const OVERRIDE_11 {return 0;} 
01019     //{   return std::min(left.getNumTimeDerivatives(), 
01020     //                    right.getNumTimeDerivatives()); }
01021 
01022     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11 
01023     {   return Stage(std::max(left.getDependsOnStage(order),
01024                               right.getDependsOnStage(order))); }
01025 
01026 
01027     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
01028         OVERRIDE_11
01029     {
01030         value = left.getValue(s,derivOrder) - right.getValue(s,derivOrder);
01031     }
01032 
01033     // There are no uncached values.
01034 
01035 private:
01036     // TOPOLOGY STATE
01037     Measure_<T> left;
01038     Measure_<T> right;
01039 
01040     // TOPOLOGY CACHE
01041     // nothing
01042 };
01043 
01044 
01045 
01046 //==============================================================================
01047 //                          SCALE :: IMPLEMENTATION
01048 //==============================================================================
01049 template <class T>
01050 class Measure_<T>::Scale::Implementation
01051 :   public Measure_<T>::Implementation 
01052 {
01053 public:
01054     // TODO: Currently allocates just one cache entry.
01055     // scale will be uninitialized, operand will be empty handle.
01056     Implementation() : factor(NaN) {}
01057 
01058     Implementation(Real factor, const Measure_<T>& operand)
01059     :   factor(factor), operand(operand) {}
01060 
01061     // Default copy constructor gives us a new Implementation object,
01062     // but with references to the *same* operand measure.
01063 
01064     void setScaleFactor(Real sf) {
01065         factor = sf;
01066         this->invalidateTopologyCache();
01067     }
01068 
01069     const Measure_<T>& getOperandMeasure() const
01070     {
01071         return operand;
01072     }
01073 
01074     // Implementations of virtual methods.
01075 
01076     // This uses the default copy constructor.
01077     Implementation* cloneVirtual() const OVERRIDE_11 
01078     {   return new Implementation(*this); }
01079 
01080     // TODO: Let this be settable up to the min number of derivatives 
01081     // provided by the arguments.
01082     int getNumTimeDerivativesVirtual() const OVERRIDE_11 {return 0;} 
01083     //{   return std::min(left.getNumTimeDerivatives(), 
01084     //                    right.getNumTimeDerivatives()); }
01085 
01086     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11
01087     {   return operand.getDependsOnStage(order); }
01088 
01089 
01090     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
01091         OVERRIDE_11
01092     {
01093         value = factor * operand.getValue(s,derivOrder);
01094     }
01095 
01096     // There are no uncached values.
01097 
01098 private:
01099     // TOPOLOGY STATE
01100     Real        factor;
01101     Measure_<T> operand;
01102 
01103     // TOPOLOGY CACHE
01104     // nothing
01105 };
01106 
01107 
01108 
01109 //==============================================================================
01110 //                        INTEGRATE :: IMPLEMENTATION
01111 //==============================================================================
01118 template <class T>
01119 class Measure_<T>::Integrate::Implementation 
01120 :   public Measure_<T>::Implementation {
01121 public:
01124     Implementation() : Measure_<T>::Implementation(1) {}
01125 
01128     Implementation(const Measure_<T>& deriv, const Measure_<T>& ic,
01129                    const T& defaultValue)
01130     :   Measure_<T>::Implementation(defaultValue, 1), 
01131         derivMeasure(deriv), icMeasure(ic) {}
01132 
01135     Implementation(const Implementation& source)
01136     :   Measure_<T>::Implementation(source.getDefaultValue(), 1), 
01137         derivMeasure(source.derivMeasure), icMeasure(source.icMeasure) {}
01138 
01142     void setValue(State& s, const T& value) const
01143     {   assert(zIndex >= 0);
01144         for (int i=0; i < this->size(); ++i)
01145             this->getSubsystem().updZ(s)[zIndex+i] = 
01146                 Measure_Num<T>::get(value, i); }
01147     
01148     const Measure_<T>& getDerivativeMeasure() const
01149     {   SimTK_ERRCHK(!derivMeasure.isEmptyHandle(), 
01150             "Measure_<T>::Integrate::getDerivativeMeasure()",
01151             "No derivative measure is available for this integrated measure."); 
01152         return derivMeasure; }
01153 
01154     const Measure_<T>& getInitialConditionMeasure() const
01155     {   SimTK_ERRCHK(!icMeasure.isEmptyHandle(), 
01156             "Measure_<T>::Integrate::getInitialConditionMeasure()",
01157             "No initial condition measure is available for this "
01158             "integrated measure."); 
01159         return icMeasure; }
01160 
01161     void setDerivativeMeasure(const Measure_<T>& d)
01162     {   derivMeasure = d; this->invalidateTopologyCache(); }
01163     void setInitialConditionMeasure(const Measure_<T>& ic)
01164     {   icMeasure = ic; this->invalidateTopologyCache(); }
01165 
01166     // Implementations of virtuals.
01167 
01168     // This uses the copy constructor defined above.
01169     Implementation* cloneVirtual() const OVERRIDE_11 
01170     {   return new Implementation(*this); }
01171 
01173     int getNumTimeDerivativesVirtual() const OVERRIDE_11 
01174     {   int integralDerivs = getDerivativeMeasure().getNumTimeDerivatives();
01175         // Careful - can't add 1 to max int and stay an int.
01176         if (integralDerivs < std::numeric_limits<int>::max())
01177             ++integralDerivs;        
01178         return integralDerivs; }
01179 
01180     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
01181         OVERRIDE_11
01182     {   assert(derivOrder == 0); // only one cache entry
01183         assert(Measure_Num<T>::size(value) == this->size());
01184         assert(zIndex.isValid());
01185         const Vector& allZ = this->getSubsystem().getZ(s);
01186         for (int i=0; i < this->size(); ++i)
01187             Measure_Num<T>::upd(value,i) = allZ[zIndex+i];
01188     }
01189 
01190     const T& getUncachedValueVirtual(const State& s, int derivOrder) const
01191         OVERRIDE_11
01192     {   assert(derivOrder > 0); // 0th entry is cached
01193         return getDerivativeMeasure().getValue(s, derivOrder-1);
01194     }
01195 
01196     Stage getDependsOnStageVirtual(int derivOrder) const OVERRIDE_11 
01197     {   return derivOrder>0 
01198             ? getDerivativeMeasure().getDependsOnStage(derivOrder-1)
01199             : Stage::Time; }
01200 
01203     void initializeVirtual(State& s) const OVERRIDE_11 {
01204         assert(zIndex.isValid());
01205         Vector& allZ = this->getSubsystem().updZ(s);
01206         if (!icMeasure.isEmptyHandle()) {
01207             this->getSubsystem().getSystem()
01208                 .realize(s, icMeasure.getDependsOnStage());
01209             const T& ic = icMeasure.getValue(s);
01210             for (int i=0; i < this->size(); ++i)
01211                 allZ[zIndex+i] = Measure_Num<T>::get(ic,i);
01212         } else {
01213             for (int i=0; i < this->size(); ++i)
01214                 allZ[zIndex+i] = Measure_Num<T>::get(this->getDefaultValue(),i);
01215         }
01216     }
01217 
01222     void realizeMeasureTopologyVirtual(State& s) const OVERRIDE_11 {
01223         Vector init(this->size());
01224         for (int i=0; i < this->size(); ++i) 
01225             init[i] = Measure_Num<T>::get(this->getDefaultValue(),i);
01226         zIndex = this->getSubsystem().allocateZ(s, init);
01227     }
01228 
01231     void realizeMeasureAccelerationVirtual(const State& s) const OVERRIDE_11 {
01232         assert(zIndex.isValid());
01233         Vector& allZDot = this->getSubsystem().updZDot(s);
01234         if (!derivMeasure.isEmptyHandle()) {
01235             const T& deriv = derivMeasure.getValue(s);
01236              for (int i=0; i < this->size(); ++i)
01237                  allZDot[zIndex+i] = Measure_Num<T>::get(deriv,i);
01238         } else {
01239             allZDot(zIndex,this->size()) = 0; // derivative is zero
01240         }
01241     }
01242 
01243 private:
01244     // TOPOLOGY STATE
01245     Measure_<T> derivMeasure; // just handles
01246     Measure_<T> icMeasure;
01247 
01248     // TOPOLOGY CACHE
01249     mutable ZIndex zIndex;  // This is the first index if more than one z.
01250 };
01251 
01252 
01253 
01254 //==============================================================================
01255 //                      DIFFERENTIATE :: IMPLEMENTATION
01256 //==============================================================================
01257  // Hide from Doxygen.
01259 // This helper class is the contents of the discrete state variable and 
01260 // corresponding cache entry maintained by this measure. The variable is 
01261 // auto-update, meaning the value of the cache entry replaces the state 
01262 // variable at the start of each step.
01263 // TODO: This was a local class in Measure_<T>::Differentiate::Implementation
01264 // but VC++ 8 (2005) failed to properly instantiate the templatized operator<<()
01265 // in that case; doing it this way is a workaround.
01266 template <class T>
01267 class Measure_Differentiate_Result {
01268 public:
01269     Measure_Differentiate_Result() : derivIsGood(false) {}
01270     T       operand;    // previous value of operand
01271     T       operandDot; // previous value of derivative
01272     bool    derivIsGood; // do we think the deriv is a good one?
01273 };
01276 template <class T>
01277 class Measure_<T>::Differentiate::Implementation
01278 :   public Measure_<T>::Implementation 
01279 {
01280     typedef Measure_Differentiate_Result<T> Result;
01281 public:
01282     // Don't allocate any cache entries in the base class.
01283     Implementation() : Measure_<T>::Implementation(0) {}
01284 
01285     Implementation(const Measure_<T>& operand)
01286     :   Measure_<T>::Implementation(0),
01287         operand(operand), forceUseApprox(false), isApproxInUse(false) {}
01288 
01289     // Default copy constructor gives us a new Implementation object,
01290     // but with reference to the *same* operand measure.
01291 
01292     void setForceUseApproximation(bool mustApproximate) {
01293         forceUseApprox = mustApproximate;
01294         this->invalidateTopologyCache();
01295     }
01296 
01297     void setOperandMeasure(const Measure_<T>& operand) {
01298         this->operand = operand;
01299         this->invalidateTopologyCache();
01300     }
01301 
01302     bool getForceUseApproximation() const {return forceUseApprox;}
01303     bool isUsingApproximation() const {return isApproxInUse;}
01304     const Measure_<T>& getOperandMeasure() const {return operand;}
01305 
01306     // Implementations of virtual methods.
01307 
01308     // This uses the default copy constructor.
01309     Implementation* cloneVirtual() const OVERRIDE_11
01310     {   return new Implementation(*this); }
01311 
01312     // This has one fewer than the operand.
01313     int getNumTimeDerivativesVirtual() const OVERRIDE_11
01314     {   if (!isApproxInUse) return operand.getNumTimeDerivatives()-1;
01315         else return 0; }
01316 
01317     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11 
01318     {   if (!isApproxInUse) return operand.getDependsOnStage(order+1);
01319         else return operand.getDependsOnStage(order); }
01320 
01321 
01322     // We're not using the Measure_<T> base class cache services, but
01323     // we do have one of our own. It looks uncached from the base class
01324     // point of view which is why we're implementing it here.
01325     const T& getUncachedValueVirtual(const State& s, int derivOrder) const
01326         OVERRIDE_11
01327     {   if (!isApproxInUse) 
01328             return operand.getValue(s, derivOrder+1);
01329 
01330         ensureDerivativeIsRealized(s);
01331         const Subsystem& subsys = this->getSubsystem();
01332         const Result& result = Value<Result>::downcast
01333                                 (subsys.getDiscreteVarUpdateValue(s,resultIx));
01334         return result.operandDot; // has a value but might not be a good one
01335     }
01336 
01337     void initializeVirtual(State& s) const OVERRIDE_11 {
01338         if (!isApproxInUse) return;
01339 
01340         assert(resultIx.isValid());
01341         const Subsystem& subsys = this->getSubsystem();
01342         Result& result = Value<Result>::updDowncast
01343                             (subsys.updDiscreteVariable(s,resultIx));
01344         this->getSubsystem().getSystem().realize(s,operand.getDependsOnStage());
01345         result.operand = operand.getValue(s);
01346         result.operandDot = this->getValueZero();
01347         result.derivIsGood = false;
01348     }
01349 
01350     void realizeMeasureTopologyVirtual(State& s) const OVERRIDE_11 {
01351         isApproxInUse = (forceUseApprox || operand.getNumTimeDerivatives()==0);
01352         if (!isApproxInUse)
01353             return;
01354 
01355         resultIx = this->getSubsystem()
01356             .allocateAutoUpdateDiscreteVariable(s, operand.getDependsOnStage(0),
01357                 new Value<Result>(), operand.getDependsOnStage(0));
01358     }
01359 
01362     void realizeMeasureAccelerationVirtual(const State& s) const OVERRIDE_11 {
01363         ensureDerivativeIsRealized(s);
01364     }
01365 
01366     void ensureDerivativeIsRealized(const State& s) const {
01367         assert(resultIx.isValid());
01368         const Subsystem& subsys = this->getSubsystem();
01369         if (subsys.isDiscreteVarUpdateValueRealized(s,resultIx))
01370             return;
01371 
01372         const Real t0 = subsys.getDiscreteVarLastUpdateTime(s,resultIx);
01373         const Result& prevResult = Value<Result>::downcast
01374            (subsys.getDiscreteVariable(s,resultIx));
01375         const T&   f0         = prevResult.operand;
01376         const T&   fdot0      = prevResult.operandDot;   // may be invalid
01377         const bool good0      = prevResult.derivIsGood;
01378 
01379         const Real t  = s.getTime();
01380         Result& result = Value<Result>::updDowncast
01381            (subsys.updDiscreteVarUpdateValue(s,resultIx));
01382         T&         f          = result.operand;          // renaming
01383         T&         fdot       = result.operandDot;
01384         bool&      good       = result.derivIsGood;
01385 
01386         f = operand.getValue(s);
01387         good = false;
01388         if (!isFinite(t0))
01389             fdot = this->getValueZero(); 
01390         else if (t == t0) {
01391             fdot = fdot0;
01392             good = good0;
01393         } else {
01394             fdot = (f-f0)/(t-t0); // 1st order
01395             if (good0)
01396                 fdot = Real(2)*fdot - fdot0; // now 2nd order
01397             good = true; // either 1st or 2nd order estimate
01398         }
01399         subsys.markDiscreteVarUpdateValueRealized(s,resultIx);
01400     }
01401 private:
01402     // TOPOLOGY STATE
01403     Measure_<T>     operand;
01404     bool            forceUseApprox;
01405 
01406     // TOPOLOGY CACHE
01407     mutable bool                    isApproxInUse;
01408     mutable DiscreteVariableIndex   resultIx;    // auto-update
01409 };
01410 
01411 
01412 
01413 //==============================================================================
01414 //                         EXTREME :: IMPLEMENTATION
01415 //==============================================================================
01416 template <class T>
01417 class Measure_<T>::Extreme::Implementation : public Measure_<T>::Implementation 
01418 {
01419     typedef typename Measure_<T>::Extreme Extreme;
01420     typedef typename Extreme::Operation   Operation;
01421 public:
01424     Implementation() 
01425     :   Measure_<T>::Implementation(0), operation(Extreme::MaxAbs) {}
01426 
01429     Implementation(const Measure_<T>& operand, Operation op)
01430     :   Measure_<T>::Implementation(0), operand(operand), operation(op) {}
01431 
01432     // Default copy constructor gives us a new Implementation object,
01433     // but with reference to the *same* operand measure.
01434 
01438     void setOperandMeasure(const Measure_<T>& operand) {
01439         this->operand = operand;
01440         this->invalidateTopologyCache();
01441     }
01442 
01446     void setOperation(Operation op) {
01447         this->operation = op;
01448         this->invalidateTopologyCache();
01449     }
01450 
01452     const Measure_<T>& getOperandMeasure() const {return operand;}
01453 
01456     Operation getOperation() const {return operation;}
01457 
01460     void setValue(State& s, const T& value) const {
01461         assert(extremeIx.isValid());
01462         const Subsystem& subsys = this->getSubsystem();
01463         T& prevMin = Value<T>::updDowncast
01464                             (subsys.updDiscreteVariable(s,extremeIx));
01465         prevMin = value;
01466     }
01467 
01471     Real getTimeOfExtremeValue(const State& s) const {
01472         const Subsystem& subsys = this->getSubsystem();
01473         const bool hasNewExtreme = ensureExtremeHasBeenUpdated(s);
01474         Real tUpdate;
01475         if (hasNewExtreme)
01476             tUpdate = s.getTime(); // i.e., now
01477         else
01478             tUpdate = subsys.getDiscreteVarLastUpdateTime(s,extremeIx);
01479         return tUpdate;
01480     }
01481 
01482     // Implementations of virtual methods.
01483 
01484     // This uses the default copy constructor.
01485     Implementation* cloneVirtual() const OVERRIDE_11 
01486     {   return new Implementation(*this); }
01487 
01490     int getNumTimeDerivativesVirtual() const OVERRIDE_11
01491     {   return operand.getNumTimeDerivatives(); }
01492 
01495     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11
01496     {   return operand.getDependsOnStage(order); }
01497 
01498 
01502     const T& getUncachedValueVirtual(const State& s, int derivOrder) const
01503         OVERRIDE_11
01504     {   
01505         const Subsystem& subsys = this->getSubsystem();
01506         const bool hasNewExtreme = ensureExtremeHasBeenUpdated(s);
01507         if (derivOrder > 0) {
01508             // TODO: should be handled elementwise and zero unless the
01509             // derivative is acting in the direction that changes the 
01510             // extreme.
01511             return hasNewExtreme ? operand.getValue(s, derivOrder)
01512                                  : this->getValueZero();
01513         }
01514         if (hasNewExtreme) {
01515             const T& newExt = Value<T>::downcast
01516                                 (subsys.getDiscreteVarUpdateValue(s,extremeIx));
01517             return newExt;
01518         } else {
01519             const T& currentExt = Value<T>::downcast
01520                                 (subsys.getDiscreteVariable(s,extremeIx));
01521             return currentExt;
01522         }
01523     }
01524 
01527     void initializeVirtual(State& s) const OVERRIDE_11 {
01528         this->getSubsystem().getSystem().realize(s,operand.getDependsOnStage()); 
01529         setValue(s, operand.getValue(s));
01530     }
01531 
01539     void realizeMeasureTopologyVirtual(State& s) const OVERRIDE_11 {
01540         // TODO: this should be NaN once initialization is working properly.
01541         T initVal = this->getDefaultValue();
01542         switch(operation) {
01543         case Minimum: initVal = Infinity; break;
01544         case Maximum: initVal = -Infinity; break;
01545         case MinAbs:  initVal = Infinity; break;
01546         case MaxAbs:  initVal = 0; break;
01547         };
01548 
01549         extremeIx = this->getSubsystem()
01550             .allocateAutoUpdateDiscreteVariable(s, Stage::Dynamics,
01551                 new Value<T>(initVal), operand.getDependsOnStage(0));
01552 
01553         isNewExtremeIx = this->getSubsystem()
01554             .allocateAutoUpdateDiscreteVariable(s, Stage::Dynamics,              
01555                 new Value<bool>(false), operand.getDependsOnStage(0));
01556     }
01557 
01560     void realizeMeasureAccelerationVirtual(const State& s) const OVERRIDE_11 {
01561         ensureExtremeHasBeenUpdated(s);
01562     }
01563 
01569     bool ensureExtremeHasBeenUpdated(const State& s) const {
01570         assert(extremeIx.isValid() && isNewExtremeIx.isValid());
01571         const Subsystem& subsys = this->getSubsystem();
01572 
01573         // We may have already determined whether we're at a new extreme in 
01574         // which case we don't need to do it again.
01575         if (subsys.isDiscreteVarUpdateValueRealized(s, isNewExtremeIx))
01576             return Value<bool>::downcast
01577                (subsys.getDiscreteVarUpdateValue(s,isNewExtremeIx));
01578 
01579         // We're going to have to decide if we're at a new extreme, and if
01580         // so record the new extreme value in the auto-update cache entry of
01581         // the extreme value state variable.
01582 
01583         // Get the previous extreme value and the current operand value.
01584         const T& prevExtreme = Value<T>::downcast
01585                                     (subsys.getDiscreteVariable(s,extremeIx));
01586         const T& currentVal = operand.getValue(s);
01587 
01588         // Search to see if any element has reached a new extreme.
01589         bool foundNewExt = false;
01590         for (int i=0; i < this->size() && !foundNewExt; ++i) 
01591             foundNewExt = isNewExtreme(Measure_Num<T>::get(currentVal,i), 
01592                                        Measure_Num<T>::get(prevExtreme,i));
01593 
01594         // Record the result and mark the auto-update cache entry valid
01595         // so we won't have to recalculate. When the integrator advances to the
01596         // next step this cache entry will be swapped with the corresponding 
01597         // state and marked invalid so we'll be sure to recalculate each step. 
01598         Value<bool>::updDowncast
01599            (subsys.updDiscreteVarUpdateValue(s,isNewExtremeIx)) = foundNewExt;
01600         subsys.markDiscreteVarUpdateValueRealized(s,isNewExtremeIx);
01601 
01602         // Don't update the auto-update cache entry if we didn't see a new
01603         // extreme. That way no auto-update will occur and the state variable
01604         // will remain unchanged with the existing update time preserved.
01605         if (!foundNewExt)
01606             return false;
01607 
01608         // We have encountered a new extreme. We'll record the new extreme
01609         // in the auto-update cache entry which will be used as the current
01610         // result until the integrator advances to the next step at which time
01611         // this will be swapped with the state variable to serve as the previous
01612         // extreme value until a further extreme is encountered.
01613         T& newExtreme = Value<T>::updDowncast
01614                                 (subsys.updDiscreteVarUpdateValue(s,extremeIx));
01615 
01616         for (int i=0; i < this->size(); ++i)
01617             Measure_Num<T>::upd(newExtreme,i) =
01618                 extremeOf(Measure_Num<T>::get(currentVal,i),
01619                           Measure_Num<T>::get(prevExtreme,i));
01620 
01621         // Marking this valid is what ensures that an auto-update occurs later.
01622         subsys.markDiscreteVarUpdateValueRealized(s,extremeIx);
01623         return true;
01624     }
01625 private:
01626     // Return true if newVal is "more extreme" than oldExtreme, according
01627     // to the operation we're performing.
01628     bool isNewExtreme(const typename Measure_Num<T>::Element& newVal,
01629                       const typename Measure_Num<T>::Element& oldExtreme) const
01630     {
01631         switch (operation) {
01632         case Extreme::Maximum: return newVal > oldExtreme;
01633         case Extreme::Minimum: return newVal < oldExtreme;
01634         case Extreme::MaxAbs: return std::abs(newVal) > std::abs(oldExtreme);
01635         case Extreme::MinAbs: return std::abs(newVal) < std::abs(oldExtreme);
01636         };
01637         SimTK_ASSERT1_ALWAYS(!"recognized", 
01638             "Measure::Extreme::Implementation::isNewExtreme(): "
01639             "unrecognized operation %d", (int)operation);
01640         return false; /*NOTREACHED*/
01641     }
01642 
01643     // Given the value of one element of the operand, and that value's time
01644     // derivative, determine whether the derivative is moving the element
01645     // into the "more extreme" direction, according to the operation.
01646     bool isExtremeDir(const typename Measure_Num<T>::Element& value,
01647                       const typename Measure_Num<T>::Element& deriv) const 
01648     {
01649         const int sv = sign(value), sd = sign(deriv);
01650         if (sd == 0) return false; // derivative is zero; not changing
01651         switch (operation) {
01652         case Extreme::Maximum: return sd ==  1; // getting larger
01653         case Extreme::Minimum: return sd == -1; // getting smaller
01654         case Extreme::MaxAbs: return sv==0 || sd==sv; // abs is growing
01655         case Extreme::MinAbs: return sd == -sv;
01656         };
01657         SimTK_ASSERT1_ALWAYS(!"recognized", 
01658             "Measure::Extreme::Implementation::isExtremeDir(): "
01659             "unrecognized operation %d", (int)operation);
01660         return false; /*NOTREACHED*/
01661     }
01662 
01663     typename Measure_Num<T>::Element 
01664     extremeOf(const typename Measure_Num<T>::Element& newVal,
01665               const typename Measure_Num<T>::Element& oldExtreme) const
01666     {
01667         return isNewExtreme(newVal,oldExtreme) ? newVal : oldExtreme;
01668     }
01669 
01670     // TOPOLOGY STATE
01671     Measure_<T>                     operand;
01672     Operation                       operation;
01673 
01674     // TOPOLOGY CACHE
01675     mutable DiscreteVariableIndex   extremeIx; // extreme so far; auto-update
01676 
01677     // This auto-update flag records whether the current value is a new
01678     // extreme. We don't really need to save it as a state variable since you
01679     // can figure this out from the timestamp, but we need to to get invalidated
01680     // by the auto-update swap so that we'll figure it out anew each step.
01681     mutable DiscreteVariableIndex   isNewExtremeIx;
01682 };
01683 
01684 
01685 
01686 //==============================================================================
01687 //                         DELAY :: IMPLEMENTATION
01688 //============================================================================== // Hide from Doxygen.
01690 // This helper class is the contents of the discrete state variable and 
01691 // corresponding cache entry maintained by this measure. The variable is 
01692 // auto-update, meaning the value of the cache entry replaces the state 
01693 // variable at the start of each step.
01694 //
01695 // Circular buffers look like this:
01696 //
01697 //             oldest=0, n=0
01698 //                  v
01699 // Empty buffer:   |    available    |
01700 //
01701 // By convention, oldest=0 whenever the buffer is empty. 
01702 //
01703 //
01704 //           oldest            next=(oldest+n)%capacity
01705 //                 v           v
01706 //    | available | | | | | | | available |
01707 //     ^                n=6                ^
01708 //     0                                   capacity
01709 //     v                                   v
01710 // or | | | | | | available | | | | | | | |    n=12
01711 //               ^           ^
01712 //               next        oldest
01713 //                 = (oldest+n)%capacity
01714 //
01715 // Number of entries = n (called size() below)
01716 // Empty = n==0
01717 // Full = n==capacity()
01718 // Next available = (oldest+n)%capacity()
01719 template <class T>
01720 class Measure_Delay_Buffer {
01721 public:
01722     explicit Measure_Delay_Buffer() {initDataMembers();}
01723     void clear() {initDataMembers();}
01724     int  size() const {return m_size;} // # saved entries, *not* size of arrays
01725     int  capacity() const {return m_times.size();}
01726     bool empty() const {return size()==0;}
01727     bool full()  const {return size()==capacity();}
01728 
01729     double getEntryTime(int i) const
01730     {   assert(i < size()); return m_times[getArrayIndex(i)];}
01731     const T& getEntryValue(int i) const
01732     {   assert(i < size()); return m_values[getArrayIndex(i)];}
01733 
01734     enum {  
01735         InitialAllocation  = 8,  // smallest allocation 
01736         GrowthFactor       = 2,  // how fast to grow (double)
01737         MaxShrinkProofSize = 16, // won't shrink unless bigger
01738         TooBigFactor       = 5   // 5X too much->maybe shrink
01739     };
01740 
01741     // Add a new entry to the end of the list, throwing out old entries that
01742     // aren't needed to answer requests at tEarliest or later.
01743     void append(double tEarliest, double tNow, const T& valueNow) {
01744         forgetEntriesMuchOlderThan(tEarliest);
01745         removeEntriesLaterOrEq(tNow);
01746         if (full()) 
01747             makeMoreRoom();
01748         else if (capacity() > std::max((int)MaxShrinkProofSize, 
01749                                        (int)TooBigFactor * (size()+1)))
01750             makeLessRoom(); // less than 1/TooBigFactor full
01751         const int nextFree = getArrayIndex(m_size++);
01752         m_times[nextFree] = tNow;
01753         m_values[nextFree] = valueNow;
01754         m_maxSize = std::max(m_maxSize, size());
01755     }
01756 
01757     // Prepend an older entry to the beginning of the list. No cleanup is done.
01758     void prepend(double tNewOldest, const T& value) {
01759         assert(empty() || tNewOldest < m_times[m_oldest]);
01760         if (full()) makeMoreRoom();
01761         m_oldest = empty() ? 0 : getArrayIndex(-1);
01762         m_times[m_oldest] = tNewOldest;
01763         m_values[m_oldest] = value;
01764         ++m_size;
01765         m_maxSize = std::max(m_maxSize, size());
01766     }
01767 
01768     // This is a specialized copy assignment for copying an old buffer
01769     // to a new one with updated contents. We are told the earliest time we'll
01770     // be asked about from now on, and won't copy any entries older than those
01771     // needed to answer that earliest request. We won't copy anything at or
01772     // newer than tNow, and finally we'll push (tNow,valueNow) as the newest
01773     // entry.
01774     void copyInAndUpdate(const Measure_Delay_Buffer& oldBuf, double tEarliest,
01775                          double tNow, const T& valueNow) {
01776         // clear all current entries (no heap activity)
01777         m_oldest = m_size = 0;
01778 
01779         // determine how may old entries we have to keep
01780         int firstNeeded = oldBuf.countNumUnneededOldEntries(tEarliest);
01781         int lastNeeded  = oldBuf.findLastEarlier(tNow); // might be -1
01782         int numOldEntriesToKeep = lastNeeded-firstNeeded+1;
01783         int newSize = numOldEntriesToKeep+1; // includes the new one
01784 
01785         int newSizeRequest = -1;
01786         if (capacity() < newSize) {
01787             newSizeRequest = std::max((int)InitialAllocation, 
01788                                       (int)GrowthFactor * newSize);
01789             ++m_nGrows;
01790         } else if (capacity() > std::max((int)MaxShrinkProofSize, 
01791                                          (int)TooBigFactor * newSize)) {
01792             newSizeRequest = std::max((int)MaxShrinkProofSize, 
01793                                       (int)GrowthFactor * newSize);
01794             ++m_nShrinks;
01795         }
01796 
01797         // Reallocate space if advisable.
01798         if (newSizeRequest != -1) {
01799             const double dNaN = NTraits<double>::getNaN();
01800             m_values.resize(newSizeRequest); 
01801             if (m_values.capacity() > m_values.size())
01802                 m_values.resize(m_values.capacity()); // don't waste any     
01803             m_times.resize(m_values.size(), dNaN); 
01804         }
01805 
01806         m_maxCapacity = std::max(m_maxCapacity, capacity());
01807         
01808         // Copy the entries we need to keep.
01809         int nxt = 0;
01810         for (int i=firstNeeded; i<=lastNeeded; ++i, ++nxt) {
01811             m_times[nxt]  = oldBuf.getEntryTime(i);
01812             m_values[nxt] = oldBuf.getEntryValue(i);
01813         }
01814         // Now add the newest entry and set the size.
01815         m_times[nxt]  = tNow;
01816         m_values[nxt] = valueNow;
01817         assert(nxt+1==newSize);
01818         m_size = nxt+1;
01819         m_maxSize = std::max(m_maxSize, size());
01820     }
01821 
01822     // Given the current time and value and the earlier time at which the
01823     // value is needed, use the buffer and (if necessary) the current value
01824     // to estimate the delayed value.
01825     T calcValueAtTime(double tDelay, double tNow, const T& valueNow) const;
01826 
01827     // Given the current time but *not* the current value of the source measure,
01828     // provide an estimate for the value at tDelay=tNow-delay using only the 
01829     // buffer contents and linear interpolation or extrapolation.
01830     void calcValueAtTimeLinearOnly(double tDelay, T& delayedValue) const {
01831         if (empty()) {
01832             // Nothing in the buffer?? Shouldn't happen. Return empty Vector
01833             // or NaN for fixed-size types.
01834             Measure_Num<T>::makeNaNLike(T(), delayedValue);
01835             return;
01836         }
01837 
01838         int firstLater = findFirstLaterOrEq(tDelay);
01839 
01840         if (firstLater > 0) {
01841             // Normal case: tDelay is between two buffer entries.
01842             int firstEarlier = firstLater-1;
01843             double t0=getEntryTime(firstEarlier), t1=getEntryTime(firstLater);
01844             const T& v0=getEntryValue(firstEarlier);
01845             const T& v1=getEntryValue(firstLater);
01846             Real fraction = Real((tDelay-t0)/(t1-t0));
01847             delayedValue = T(v0 + fraction*(v1-v0));
01848             return;
01849         }
01850 
01851         if (firstLater==0) {
01852             // Startup case: tDelay is at or before the oldest buffer entry.
01853             // Assume the value was flat before that.
01854             delayedValue = getEntryValue(firstLater);
01855             return;
01856         }
01857 
01858         // tDelay is later than the latest entry in the buffer. We are going
01859         // to have to extrapolate (yuck).
01860 
01861         if (size() == 1) {
01862             // Just one entry; we'll have to assume the value is flat.
01863             delayedValue = getEntryValue(0);
01864             return;
01865         }
01866 
01867         // Extrapolate using the last two entries.
01868         double t0=getEntryTime(size()-2), t1=getEntryTime(size()-1);
01869         const T& v0=getEntryValue(size()-2);
01870         const T& v1=getEntryValue(size()-1);
01871         Real fraction = Real((tDelay-t0)/(t1-t0));  // > 1
01872         assert(fraction > 1.0);
01873         delayedValue = T(v0 + fraction*(v1-v0));   // Extrapolate.
01874     }
01875 
01876     // Return the number of times we had to grow the buffer.
01877     int getNumGrows() const {return m_nGrows;}
01878     // Return the number of times we decided the buffer was so overallocated
01879     // that we had to shrink it.
01880     int getNumShrinks() const {return m_nShrinks;}
01881     // Return the largest number of values we ever had in the buffer.
01882     int getMaxSize() const {return m_maxSize;}
01883     // Return the largest capacity the buffer ever had.
01884     int getMaxCapacity() const {return m_maxCapacity;}
01885 
01886 private:
01887     // Return the i'th oldest entry 
01888     // (0 -> oldest, size-1 -> newest, size -> first free, -1 -> last free)
01889     int getArrayIndex(int i) const 
01890     {   assert(-1<=i && i<=size()); 
01891         const int rawIndex = m_oldest + i;
01892         if (rawIndex < 0) return rawIndex + capacity();
01893         else return rawIndex % capacity(); }
01894 
01895     // Remove all but two entries older than the given time.
01896     void forgetEntriesMuchOlderThan(double tEarliest) {
01897         const int numToRemove = countNumUnneededOldEntries(tEarliest);
01898         if (numToRemove) {
01899             m_oldest = getArrayIndex(numToRemove);
01900             m_size -= numToRemove;
01901         }
01902     }
01903 
01904     // Count up how many old entries at the beginning of the buffer are so old
01905     // that they wouldn't be needed to respond to a request at time tEarliest or
01906     // later. We'll keep no more than two entries earlier than tEarliest.
01907     int countNumUnneededOldEntries(double tEarliest) const {
01908         const int firstLater = findFirstLaterOrEq(tEarliest);
01909         return std::max(0, firstLater-2);
01910     }
01911 
01912     // Given the time now, delete anything at the end of the queue that is
01913     // at that same time or later.
01914     void removeEntriesLaterOrEq(double t) {
01915         int lastEarlier = findLastEarlier(t);
01916         m_size = lastEarlier+1;
01917         if (m_size==0) m_oldest=0; // restart at beginning of array
01918     }
01919 
01920     // Return the entry number (0..size-1) of the first entry whose time 
01921     // is >= the given time, or -1 if there is none such.
01922     int findFirstLaterOrEq(double tDelay) const {
01923         for (int i=0; i < size(); ++i)
01924             if (getEntryTime(i) >= tDelay)
01925                 return i;
01926         return -1;
01927     }
01928 
01929     // Return the entry number(size-1..0) of the last entry whose time 
01930     // is < the given time, or -1 if there is none such.
01931     int findLastEarlier(double t) const {
01932         for (int i=size()-1; i>=0; --i)
01933             if (getEntryTime(i) < t)
01934                 return i;
01935         return -1;
01936     }
01937 
01938     // We don't have enough space. This is either the initial allocation or
01939     // we need to double the current space.
01940     void makeMoreRoom() {
01941         const int newSizeRequest = std::max((int)InitialAllocation, 
01942                                             (int)GrowthFactor * size());
01943         resize(newSizeRequest);
01944         ++m_nGrows;
01945         m_maxCapacity = std::max(m_maxCapacity, capacity());
01946     }
01947 
01948     // We are wasting a lot of space, reduce the heap allocation to just 
01949     // double what we're using now.
01950     void makeLessRoom() {
01951         const int targetMaxSize = std::max((int)MaxShrinkProofSize, 
01952                                            (int)GrowthFactor * size());
01953         if (capacity() > targetMaxSize) {
01954             resize(targetMaxSize);
01955             ++m_nShrinks;
01956         }
01957     }
01958 
01959     // Reallocate memory to get more space or stop wasting space. The new
01960     // size request must be big enough to hold all the current contents. The
01961     // amount we actually get may be somewhat larger than the request. On 
01962     // return, the times and values arrays will have been resized and the 
01963     // oldest entry will now be entry 0.
01964     void resize(int newSizeRequest) {
01965         assert(newSizeRequest >= size());
01966         const double dNaN = NTraits<double>::getNaN();
01967         Array_<T,int> newValues(newSizeRequest); 
01968         if (newValues.capacity() > newValues.size())
01969             newValues.resize(newValues.capacity()); // don't waste any     
01970         Array_<double,int> newTimes(newValues.size(), dNaN); 
01971 
01972         // Pack existing values into start of new arrays.
01973         for (int i=0; i < size(); ++i) {
01974             const int ix = getArrayIndex(i);
01975             newTimes[i]  = m_times[ix];
01976             newValues[i] = m_values[ix];
01977         }
01978         m_times.swap(newTimes); // switch heap space
01979         m_values.swap(newValues);
01980         m_oldest = 0; // starts at the beginning now; size unchanged
01981     }
01982 
01983     // Initialize everything to its default-constructed state.
01984     void initDataMembers() {
01985         m_times.clear(); m_values.clear();
01986         m_oldest=m_size=0;
01987         m_nGrows=m_nShrinks=m_maxSize=m_maxCapacity=0;
01988     }
01989 
01990     // These are circular buffers of the same size.
01991     Array_<double,int>  m_times;
01992     Array_<T,int>       m_values;
01993     int                 m_oldest; // Array index of oldest (time,value)
01994     int                 m_size;   // number of entries in use
01995 
01996     // Statistics.
01997     int m_nGrows, m_nShrinks, m_maxSize, m_maxCapacity;
01998 };
02001 template <class T>
02002 class Measure_<T>::Delay::Implementation: public Measure_<T>::Implementation {
02003     typedef Measure_Delay_Buffer<T> Buffer;
02004 public:
02005     // Allocate one cache entry in the base class for the value; we allocate
02006     // a specialized one for the buffer.
02007     Implementation() 
02008     :   Measure_<T>::Implementation(1), m_delay(NaN),
02009         m_canUseCurrentValue(false), m_useLinearInterpolationOnly(false) {}
02010 
02011     Implementation(const Measure_<T>& source, Real delay)
02012     :   Measure_<T>::Implementation(1), m_source(source), m_delay(delay),
02013         m_canUseCurrentValue(false), m_useLinearInterpolationOnly(false) {}
02014 
02015     // Default copy constructor gives us a new Implementation object,
02016     // but with reference to the *same* source measure.
02017 
02018     void setSourceMeasure(const Measure_<T>& source) {
02019         if (!source.isSameMeasure(this->m_source)) {
02020             this->m_source = source;
02021             this->invalidateTopologyCache();
02022         }
02023     }
02024 
02025     void setDelay(Real delay) {
02026         if (delay != this->m_delay) {
02027             this->m_delay = delay;
02028             this->invalidateTopologyCache();
02029         }
02030     }
02031 
02032     void setUseLinearInterpolationOnly(bool linearOnly) {
02033         if (linearOnly != this->m_useLinearInterpolationOnly) {
02034             this->m_useLinearInterpolationOnly = linearOnly;
02035             this->invalidateTopologyCache();
02036         }
02037     }
02038 
02039     void setCanUseCurrentValue(bool canUseCurrentValue) {
02040         if (canUseCurrentValue != this->m_canUseCurrentValue) {
02041             this->m_canUseCurrentValue = canUseCurrentValue;
02042             this->invalidateTopologyCache();
02043         }
02044     }
02045 
02046     const Measure_<T>& getSourceMeasure() const {return this->m_source;}
02047     Real getDelay() const {return this->m_delay;}
02048     bool getUseLinearInterpolationOnly() const
02049     {   return this->m_useLinearInterpolationOnly; }
02050     bool getCanUseCurrentValue() const
02051     {   return this->m_canUseCurrentValue; }
02052 
02053 
02054     // Implementations of virtual methods.
02055 
02056     // This uses the default copy constructor.
02057     Implementation* cloneVirtual() const OVERRIDE_11
02058     {   return new Implementation(*this); }
02059 
02060     // Currently no derivative supported.
02061     int getNumTimeDerivativesVirtual() const OVERRIDE_11
02062     {   return 0; }
02063 
02064     // If we are allowed to use the current value of the source measure to
02065     // determine the delayed value, the depends-on stage here is the same as
02066     // for the source; otherwise it is Stage::Time.
02067     Stage getDependsOnStageVirtual(int order) const OVERRIDE_11 
02068     {   return this->m_canUseCurrentValue ? m_source.getDependsOnStage(order)
02069                                           : Stage::Time; }
02070 
02071     // Calculate the delayed value and return it to the Measure base class to
02072     // be put in a cache entry.
02073     void calcCachedValueVirtual(const State& s, int derivOrder, T& value) const
02074         OVERRIDE_11
02075     {   const Subsystem& subsys = this->getSubsystem();
02076         const Buffer& buffer = Value<Buffer>::downcast
02077                                 (subsys.getDiscreteVariable(s,m_bufferIx));
02078         //TODO: use cubic interpolation if allowed
02079         buffer.calcValueAtTimeLinearOnly(s.getTime()-m_delay, value);
02080     }
02081 
02082     void initializeVirtual(State& s) const OVERRIDE_11 {
02083         assert(m_bufferIx.isValid());
02084         const Subsystem& subsys = this->getSubsystem();
02085         Buffer& buffer = Value<Buffer>::updDowncast
02086                             (subsys.updDiscreteVariable(s,m_bufferIx));
02087         buffer.clear();
02088         this->getSubsystem().getSystem().realize(s,m_source.getDependsOnStage());
02089         buffer.append(s.getTime()-m_delay, s.getTime(), m_source.getValue(s));
02090     }
02091 
02092     void realizeMeasureTopologyVirtual(State& s) const OVERRIDE_11 {
02093         m_bufferIx = this->getSubsystem()
02094             .allocateAutoUpdateDiscreteVariable(s, Stage::Report,
02095                 new Value<Buffer>(), getDependsOnStageVirtual(0));
02096     }
02097 
02100     void realizeMeasureAccelerationVirtual(const State& s) const OVERRIDE_11 {
02101         updateBuffer(s);
02102     }
02103 
02104     // This uses the buffer from the state to update the one in the
02105     // corresponding cache entry. The update adds the current value of the
02106     // source to the end of the buffer and tosses out unneeded old entries.
02107     void updateBuffer(const State& s) const {
02108         assert(m_bufferIx.isValid());
02109         const Subsystem& subsys = this->getSubsystem();
02110 
02111         const Buffer& prevBuffer = Value<Buffer>::downcast
02112            (subsys.getDiscreteVariable(s,m_bufferIx));
02113 
02114         Buffer& nextBuffer = Value<Buffer>::updDowncast
02115            (subsys.updDiscreteVarUpdateValue(s,m_bufferIx));
02116 
02117         const Real t = s.getTime();
02118         nextBuffer.copyInAndUpdate(prevBuffer, t-m_delay, 
02119                                    t, m_source.getValue(s));
02120 
02121         subsys.markDiscreteVarUpdateValueRealized(s,m_bufferIx);
02122     }
02123 private:
02124     // TOPOLOGY STATE
02125     Measure_<T>     m_source;
02126     Real            m_delay;
02127     bool            m_canUseCurrentValue;
02128     bool            m_useLinearInterpolationOnly;
02129 
02130     // TOPOLOGY CACHE
02131     mutable DiscreteVariableIndex   m_bufferIx;    // auto-update
02132 };
02133 
02134 
02135 } // namespace SimTK
02136 
02137 
02138 
02139 
02140 #endif // SimTK_SimTKCOMMON_MEASURE_IMPLEMENTATION_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines