Simbody

Measure.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_MEASURE_H_
00002 #define SimTK_SimTKCOMMON_MEASURE_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core 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.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2008-10 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00045 #include "SimTKcommon/basics.h"
00046 #include "SimTKcommon/Simmatrix.h"
00047 
00048 #include <cassert>
00049 
00068 #define SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
00069     class Implementation;                                           \
00070     explicit MH(Implementation* imp) : PH(imp) {}                   \
00071     MH(Subsystem& sub, Implementation* imp, const SetHandle& sh)    \
00072     :   PH(sub,imp,sh) {}                                           \
00073     MH& operator=(const MH& src) {PH::operator=(src); return *this;}\
00074     MH& shallowAssign(const MH& src) {PH::shallowAssign(src); return *this;}\
00075     MH& deepAssign(const MH& src) {PH::deepAssign(src); return *this;}
00076 
00077 // The default constructor for concrete classes should instantiate
00078 // a default-constructed Implementation object if no Implementation
00079 // is provided.
00080 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH)    \
00081     SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH)   \
00082     MH() : PH(new Implementation()) {}          \
00083     explicit MH(Subsystem& sub)                 \
00084     : PH(sub,new Implementation(), SetHandle()) {}
00085 
00086 // The default constructor for a still-abstract derived class can't
00087 // instantiate an Implementation.
00088 #define SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(MH,PH)   \
00089     SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH)           \
00090     MH() : PH() {}                                      \
00091     explicit MH(Subsystem& sub) : PH(sub) {}    
00092 
00114 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH) \
00115     static bool isA(const AbstractMeasure& m)                               \
00116     {   return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; }    \
00117     static const MH& getAs(const AbstractMeasure& m)                        \
00118     {   assert(isA(m)); return static_cast<const MH&>(m); }                 \
00119     static MH& updAs(AbstractMeasure& m)                                    \
00120     {   assert(isA(m)); return static_cast<MH&>(m); }                       \
00121     const Implementation& getImpl() const                                   \
00122     {   return dynamic_cast<const Implementation&>                          \
00123                     (AbstractMeasure::getImpl());}                          \
00124     Implementation& updImpl()                                               \
00125     {   return dynamic_cast<Implementation&>(AbstractMeasure::updImpl());} 
00126 
00127 namespace SimTK {
00128 
00129 class State;
00130 class Subsystem;
00131 class System;
00132 class EventIndex;
00133 
00135 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
00136 
00138     // ABSTRACT MEASURE //
00140 
00156 class SimTK_SimTKCOMMON_EXPORT AbstractMeasure {
00157 protected:
00158     // An object of this type is used as a dummy argument to make sure the 
00159     // automatically-generated handle constructor's signature doesn't conflict 
00160     // with an explicitly-defined one.
00161     class SetHandle {};
00162 
00163 public:
00164     class Implementation; // local; name is AbstractMeasure::Implementation
00165 
00169     explicit AbstractMeasure(Implementation* g=0);
00170 
00175     AbstractMeasure(Subsystem&, Implementation* g, const SetHandle&);
00176 
00179     AbstractMeasure(const AbstractMeasure&);
00180 
00184     AbstractMeasure& operator=(const AbstractMeasure& source)
00185     {   return shallowAssign(source); }
00186 
00189     ~AbstractMeasure();
00190 
00196     AbstractMeasure& shallowAssign(const AbstractMeasure&);
00197 
00202     AbstractMeasure& deepAssign(const AbstractMeasure& source);
00203 
00211     int getNumTimeDerivatives() const;
00212 
00221     Stage getDependsOnStage(int derivOrder=0) const;
00222 
00223 
00225     bool isSameMeasure(const AbstractMeasure& other) const
00226     {   return impl && impl==other.impl;}
00227 
00228     bool isEmptyHandle() const {return !hasImpl();}
00229 
00231     bool isInSubsystem() const;
00235     const Subsystem& getSubsystem()  const;
00239     MeasureIndex getSubsystemMeasureIndex() const;
00240 
00241     // Internal use only
00242 
00243     // dynamic_cast the returned reference to a reference to your concrete
00244     // Implementation class.
00245     const Implementation& getImpl() const {assert(impl); return *impl;}
00246     Implementation&       updImpl()       {assert(impl); return *impl;}
00247     bool                  hasImpl() const {return impl!=0;}
00248 
00249     int getRefCount() const;
00250 private:
00251     // This is the only data member in this class. Also, any class derived 
00252     // from AbstractMeasure must have *NO* data members at all (data goes 
00253     // in the Implementation class).
00254     Implementation* impl;
00255 
00256 friend class Implementation;
00257 };
00258 
00259 
00261     // MEASURE_<T> //
00263 
00267 template <class T>
00268 class Measure_ : public AbstractMeasure {
00269 public:
00272     SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(Measure_, AbstractMeasure);
00273 
00281     inline const T& getValue(const State& s, int derivOrder=0) const 
00282     {   return getImpl().getValue(s,derivOrder); }
00283 
00284     // These are built-in Measures with local class names. 
00285 
00286     // Templatized measures may have restrictions on the allowable template
00287     // type and may be specialized for particular types.
00288     class Zero;         // T is any numerical type
00289     class One;          // T is any numerical type
00290     class Constant;     // T is any assignable type
00291     class Time;         // T is any type for which T(t) makes sense.
00292     class Variable;     // T is any assignable type (state)
00293     class Result;       // T is any assignable type (cache)
00294     class SampleAndHold;//    "
00295 
00296     // This requires any numerical type.
00297     class Plus;
00298     class Minus;
00299     class Scale;
00300     class Differentiate;
00301 
00302     // These accept any type that supports operator<, elementwise for 
00303     // vectors and matrices. TODO
00304     class Minimum;
00305     class Maximum;
00306 
00307     // These accept floating point numerical template arguments only.
00308     class Integrate;
00309     class Sinusoid;
00310 
00311     SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, AbstractMeasure);
00312 };
00313 
00316 typedef Measure_<Real> Measure;
00317 
00318 
00320     // CONSTANT //
00322 
00329 template <class T>
00330 class Measure_<T>::Constant : public Measure_<T> {
00331 public:
00332     SimTK_MEASURE_HANDLE_PREAMBLE(Constant, Measure_<T>);
00333 
00334     explicit Constant(const T& value)
00335     :   Measure_<T>(new Implementation(value)) {}
00336 
00337     Constant(Subsystem& sub, const T& value)
00338     :   Measure_<T>(sub, new Implementation(value), SetHandle()) {}
00339 
00342     Constant& setValue(const T& value) 
00343     {   updImpl().setValue(value); return *this; }
00344 
00345     SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant, Measure_<T>);
00346 };
00347 
00349     // ZERO //
00351 
00356 template <class T>
00357 class Measure_<T>::Zero : public Measure_<T>::Constant {
00358 public:
00359     SimTK_MEASURE_HANDLE_PREAMBLE(Zero, Measure_<T>::Constant);
00360 
00361     SimTK_MEASURE_HANDLE_POSTSCRIPT(Zero, Measure_<T>::Constant);
00362 private:
00363     Zero& setValue(const T&) 
00364     {   return *reinterpret_cast<Zero*>(0);} // suppressed!
00365 };
00366 
00368     // ONE //
00370 
00375 template <class T>
00376 class Measure_<T>::One : public Measure_<T>::Constant {
00377 public:
00378     SimTK_MEASURE_HANDLE_PREAMBLE(One, Measure_<T>::Constant);
00379 
00380     SimTK_MEASURE_HANDLE_POSTSCRIPT(One, Measure_<T>::Constant);
00381 private:
00382     One& setValue(const T&)     
00383     {   return *reinterpret_cast<One*>(0);} // suppressed!
00384 };
00385 
00387     // TIME //
00389 
00393 template <class T>
00394 class Measure_<T>::Time : public Measure_<T> {
00395 public:
00396     SimTK_MEASURE_HANDLE_PREAMBLE(Time, Measure_<T>);
00397 
00398     SimTK_MEASURE_HANDLE_POSTSCRIPT(Time, Measure_<T>);
00399 };
00400 
00402     // VARIABLE //
00404 
00409 template <class T>
00410 class Measure_<T>::Variable : public Measure_<T> {
00411 public:
00412     SimTK_MEASURE_HANDLE_PREAMBLE(Variable, Measure_<T>);
00413 
00414     // TODO: should not require invalidated Stage here. Instead, 
00415     // should have a unique "generation" counter for this variable
00416     // and allow subsequent users to check it.
00417     Variable(Subsystem& sub, Stage invalidates, const T& defaultValue)
00418     :   Measure_<T>(sub, new Implementation(invalidates, defaultValue), 
00419                     SetHandle()) {}
00420 
00423     Variable& setDefaultValue(const T& defaultValue) 
00424     {   updImpl().setDefaultValue(defaultValue); return *this; }
00425 
00426     const T& getDefaultValue() const
00427     {   return getImpl().getDefaultValue(); }
00428 
00429     void setValue(State& state, const T& value) const
00430     {   getImpl().setValue(state, value); }
00431 
00432     SimTK_MEASURE_HANDLE_POSTSCRIPT(Variable, Measure_<T>);
00433 };
00434 
00436     // RESULT //
00438 
00454 template <class T>
00455 class Measure_<T>::Result : public Measure_<T> {
00456 public:
00457     SimTK_MEASURE_HANDLE_PREAMBLE(Result, Measure_<T>);
00458 
00459     // TODO: should not require invalidated Stage here. Instead, 
00460     // should have a unique "generation" counter for this cache entry
00461     // and allow subsequent users of the value to check it.
00462 
00477     Result(Subsystem& sub, Stage dependsOn, Stage invalidated)
00478     :   Measure_<T>(sub, new Implementation(dependsOn, invalidated), 
00479                     SetHandle()) {}
00480 
00482     Stage getDependsOnStage() const {return getImpl().getDependsOnStage();}
00484     Stage getInvalidatedStage() const {return getImpl().getInvalidatedStage();}
00492     Result& setDependsOnStage(Stage dependsOn) 
00493     {   updImpl().setDependsOnStage(dependsOn); return *this; }
00499     Result& setInvalidatedStage(Stage invalidated) 
00500     {   updImpl().setInvalidatedStage(invalidated); return *this; }
00501 
00514     Result& setIsPresumedValidAtDependsOnStage(bool presume)
00515     {   updImpl().setIsPresumedValidAtDependsOnStage(presume); return *this; }
00516 
00519     bool getIsPresumedValidAtDependsOnStage() const
00520     {   return getImpl().getIsPresumedValidAtDependsOnStage(); }
00521 
00522 
00528     T& updValue(const State& state) const
00529     {   return getImpl().updValue(state); }
00530 
00537     void markAsValid(const State& state) const {getImpl().markAsValid(state);}
00538 
00542     bool isValid(const State& state) const {return getImpl().isValid(state);}
00543 
00551     void markAsNotValid(const State& state) const 
00552     {   getImpl().markAsNotValid(state); }
00553 
00557     void setValue(const State& state, const T& value) const
00558     {   updValue(state) = value; markAsValid(state); }
00559 
00560     SimTK_MEASURE_HANDLE_POSTSCRIPT(Result, Measure_<T>);
00561 };
00562 
00564     // SINUSOID //
00566 
00575 template <class T>
00576 class Measure_<T>::Sinusoid : public Measure_<T> {
00577 public:
00578     SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid, Measure_<T>);
00579 
00580     Sinusoid(Subsystem& sub,
00581              const T& amplitude, 
00582              const T& frequency,
00583              const T& phase=T(0))
00584     :   Measure_<T>(sub, new Implementation(amplitude,frequency,phase), SetHandle()) {}
00585 
00586     SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid, Measure_<T>);
00587 };
00588 
00590     // PLUS //
00592 
00596 template <class T>
00597 class Measure_<T>::Plus : public Measure_<T> {
00598 public:
00599     SimTK_MEASURE_HANDLE_PREAMBLE(Plus, Measure_<T>);
00600 
00601     Plus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00602     :   Measure_<T>(sub,
00603                     new Implementation(left, right), SetHandle())
00604     {   SimTK_ERRCHK_ALWAYS
00605            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00606             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00607             "Measure_<T>::Plus::ctor()",
00608             "Arguments must be in the same Subsystem as this Measure.");
00609     }
00610 
00611     SimTK_MEASURE_HANDLE_POSTSCRIPT(Plus, Measure_<T>);
00612 };
00613 
00615     // MINUS //
00617 
00621 template <class T>
00622 class Measure_<T>::Minus : public Measure_<T> {
00623 public:
00624     SimTK_MEASURE_HANDLE_PREAMBLE(Minus, Measure_<T>);
00625 
00626     Minus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00627     :   Measure_<T>(sub,
00628                     new Implementation(left, right), SetHandle())
00629     {   SimTK_ERRCHK_ALWAYS
00630            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00631             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00632             "Measure_<T>::Minus::ctor()",
00633             "Arguments must be in the same Subsystem as this Measure.");
00634     }
00635 
00636     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minus, Measure_<T>);
00637 };
00638 
00640     // SCALE //
00642 
00646 template <class T>
00647 class Measure_<T>::Scale : public Measure_<T> {
00648 public:
00649     SimTK_MEASURE_HANDLE_PREAMBLE(Scale, Measure_<T>);
00650 
00651     Scale(Subsystem& sub, Real factor, const Measure_<T>& operand)
00652     :   Measure_<T>(sub,
00653                     new Implementation(factor, operand), SetHandle())
00654     {   SimTK_ERRCHK_ALWAYS
00655            (this->getSubsystem().isSameSubsystem(operand.getSubsystem()),
00656             "Measure_<T>::Scale::ctor()",
00657             "Argument must be in the same Subsystem as this Measure.");
00658     }
00659 
00660     SimTK_MEASURE_HANDLE_POSTSCRIPT(Scale, Measure_<T>);
00661 };
00662 
00664     // INTEGRATE //
00666 
00667 template <class T>
00668 class Measure_<T>::Integrate : public Measure_<T> {
00669 public:
00670     SimTK_MEASURE_HANDLE_PREAMBLE(Integrate, Measure_<T>);
00671 
00672     Integrate(Subsystem& sub, const Measure_<T>& deriv, const Measure_<T>& ic)
00673     :   Measure_<T>(sub, new Implementation(deriv,ic), SetHandle()) {}
00674 
00675     void setValue(State& s, const T& value) const 
00676     {   return getImpl().setValue(s, value); }
00677     const Measure_<T>& getDerivativeMeasure() const 
00678     {   return getImpl().getDerivativeMeasure(); }
00679     const Measure_<T>& getInitialConditionMeasure() const 
00680     {   return getImpl().getInitialConditionMeasure(); }
00681 
00682     Integrate& setDerivativeMeasure(const Measure_<T>& d)
00683     {   updImpl().setDerivativeMeasure(d); return *this; }
00684     Integrate& setInitialConditionMeasure(const Measure_<T>& ic)
00685     {   updImpl().setInitialConditionMeasure(ic); return *this; }
00686 
00687     SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate, Measure_<T>);
00688 };
00689 
00691     // DIFFERENTIATE //
00693 
00718 template <class T>
00719 class Measure_<T>::Differentiate : public Measure_<T> {
00720 public:
00721     SimTK_MEASURE_HANDLE_PREAMBLE(Differentiate, Measure_<T>);
00722 
00727     Differentiate(Subsystem& subsystem, const Measure_<T>& operand)
00728     :   Measure_<T>(subsystem, new Implementation(operand), SetHandle()) {}
00729 
00734     bool isUsingApproximation() const 
00735     {   return getImpl().isUsingApproximation(); }
00736 
00739     const Measure_<T>& getOperandMeasure() const 
00740     {   return getImpl().getOperandMeasure(); }
00741 
00745     Differentiate& setOperandMeasure(const Measure_<T>& operand)
00746     {   updImpl().setOperandMeasure(operand); return *this; }
00747 
00751     void setForceUseApproximation(bool mustApproximate)
00752     {   updImpl().setForceUseApproximation(mustApproximate); }
00753 
00758     bool getForceUseApproximation() const 
00759     {   return getImpl().getForceUseApproximation(); }
00760 
00761     SimTK_MEASURE_HANDLE_POSTSCRIPT(Differentiate, Measure_<T>);
00762 };
00763 
00765     // MINIMUM //
00767 
00802 template <class T>
00803 class Measure_<T>::Minimum : public Measure_<T> {
00804 public:
00805     SimTK_MEASURE_HANDLE_PREAMBLE(Minimum, Measure_<T>);
00806 
00807     Minimum(Subsystem& sub, const Measure_<T>& source, const Measure_<T>& sourceDot)
00808     :   Measure_<T>(sub, new Implementation(source, sourceDot), SetHandle()) {}
00809 
00810     void setValue(State& s, const T& value) const 
00811     {   return getImpl().setValue(s, value); }
00812     const Measure_<T>& getSourceMeasure() const 
00813     {   return getImpl().getSourceMeasure(); }
00814     const Measure_<T>& getSourceDerivativeMeasure() const 
00815     {   return getImpl().getSourceDerivativeMeasure(); }
00816 
00817     Minimum& setSourceMeasure(const Measure_<T>& s)
00818     {   updImpl().setSourceMeasure(s); return *this; }
00819     Minimum& setSourceDerivativeMeasure(const Measure_<T>& sdot)
00820     {   updImpl().setSourceDerivativeMeasure(sdot); return *this; }
00821 
00822     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minimum, Measure_<T>);
00823 };
00824 
00840 template <class T>
00841 class Measure_<T>::SampleAndHold : public Measure_<T> {
00842 public:
00843     SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold, Measure_<T>);
00844 
00845     SampleAndHold(Subsystem& sub, const Measure_<T>& source, EventIndex e);
00846 
00849     void setValue(State& s, const T& value) const;
00850 
00852     void sample(State& s) const;
00853 
00854     const Measure_<T>& getSource() const;
00855     EventIndex         getEvent() const;
00856 
00857     SampleAndHold& setSource(const Measure_<T>& s);
00858     SampleAndHold& setEvent(EventIndex);
00859 
00860     SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold, Measure_<T>);
00861 };
00862 
00863 } // namespace SimTK
00864 
00865 #endif // SimTK_SimTKCOMMON_MEASURE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines