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
00293     class SampleAndHold;//    "
00294 
00295     // This requires any numerical type.
00296     class Plus;
00297     class Minus;
00298     class Scale;
00299     class Differentiate;
00300 
00301     // These accept any type that supports operator<, elementwise for 
00302     // vectors and matrices. TODO
00303     class Minimum;
00304     class Maximum;
00305 
00306     // These accept floating point numerical template arguments only.
00307     class Integrate;
00308     class Sinusoid;
00309 
00310     SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, AbstractMeasure);
00311 };
00312 
00315 typedef Measure_<Real> Measure;
00316 
00317 
00319     // CONSTANT //
00321 
00328 template <class T>
00329 class Measure_<T>::Constant : public Measure_<T> {
00330 public:
00331     SimTK_MEASURE_HANDLE_PREAMBLE(Constant, Measure_<T>);
00332 
00333     explicit Constant(const T& value)
00334     :   Measure_<T>(new Implementation(value)) {}
00335 
00336     Constant(Subsystem& sub, const T& value)
00337     :   Measure_<T>(sub, new Implementation(value), SetHandle()) {}
00338 
00341     Constant& setValue(const T& value) 
00342     {   updImpl().setValue(value); return *this; }
00343 
00344     SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant, Measure_<T>);
00345 };
00346 
00348     // ZERO //
00350 
00355 template <class T>
00356 class Measure_<T>::Zero : public Measure_<T>::Constant {
00357 public:
00358     SimTK_MEASURE_HANDLE_PREAMBLE(Zero, Measure_<T>::Constant);
00359 
00360     SimTK_MEASURE_HANDLE_POSTSCRIPT(Zero, Measure_<T>::Constant);
00361 private:
00362     Zero& setValue(const T&) 
00363     {   return *reinterpret_cast<Zero*>(0);} // suppressed!
00364 };
00365 
00367     // ONE //
00369 
00374 template <class T>
00375 class Measure_<T>::One : public Measure_<T>::Constant {
00376 public:
00377     SimTK_MEASURE_HANDLE_PREAMBLE(One, Measure_<T>::Constant);
00378 
00379     SimTK_MEASURE_HANDLE_POSTSCRIPT(One, Measure_<T>::Constant);
00380 private:
00381     One& setValue(const T&)     
00382     {   return *reinterpret_cast<One*>(0);} // suppressed!
00383 };
00384 
00386     // TIME //
00388 
00392 template <class T>
00393 class Measure_<T>::Time : public Measure_<T> {
00394 public:
00395     SimTK_MEASURE_HANDLE_PREAMBLE(Time, Measure_<T>);
00396 
00397     SimTK_MEASURE_HANDLE_POSTSCRIPT(Time, Measure_<T>);
00398 };
00399 
00401     // VARIABLE //
00403 
00408 template <class T>
00409 class Measure_<T>::Variable : public Measure_<T> {
00410 public:
00411     SimTK_MEASURE_HANDLE_PREAMBLE(Variable, Measure_<T>);
00412 
00413     // TODO: should not require invalidated Stage here. Instead, 
00414     // should have a unique "generation" counter for this variable
00415     // and allow subsequent users to check it.
00416     Variable(Subsystem& sub, Stage invalidates, const T& defaultValue)
00417     :   Measure_<T>(sub, new Implementation(invalidates, defaultValue), 
00418                     SetHandle()) {}
00419 
00422     Variable& setDefaultValue(const T& defaultValue) 
00423     {   updImpl().setDefaultValue(defaultValue); return *this; }
00424 
00425     const T& getDefaultValue() const
00426     {   return getImpl().getDefaultValue(); }
00427 
00428     void setValue(State& state, const T& value) const
00429     {   getImpl().setValue(state, value); }
00430 
00431     SimTK_MEASURE_HANDLE_POSTSCRIPT(Variable, Measure_<T>);
00432 };
00433 
00434 
00436     // SINUSOID //
00438 
00447 template <class T>
00448 class Measure_<T>::Sinusoid : public Measure_<T> {
00449 public:
00450     SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid, Measure_<T>);
00451 
00452     Sinusoid(Subsystem& sub,
00453              const T& amplitude, 
00454              const T& frequency,
00455              const T& phase=T(0))
00456     :   Measure_<T>(sub, new Implementation(amplitude,frequency,phase), SetHandle()) {}
00457 
00458     SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid, Measure_<T>);
00459 };
00460 
00462     // PLUS //
00464 
00468 template <class T>
00469 class Measure_<T>::Plus : public Measure_<T> {
00470 public:
00471     SimTK_MEASURE_HANDLE_PREAMBLE(Plus, Measure_<T>);
00472 
00473     Plus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00474     :   Measure_<T>(sub,
00475                     new Implementation(left, right), SetHandle())
00476     {   SimTK_ERRCHK_ALWAYS
00477            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00478             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00479             "Measure_<T>::Plus::ctor()",
00480             "Arguments must be in the same Subsystem as this Measure.");
00481     }
00482 
00483     SimTK_MEASURE_HANDLE_POSTSCRIPT(Plus, Measure_<T>);
00484 };
00485 
00487     // MINUS //
00489 
00493 template <class T>
00494 class Measure_<T>::Minus : public Measure_<T> {
00495 public:
00496     SimTK_MEASURE_HANDLE_PREAMBLE(Minus, Measure_<T>);
00497 
00498     Minus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00499     :   Measure_<T>(sub,
00500                     new Implementation(left, right), SetHandle())
00501     {   SimTK_ERRCHK_ALWAYS
00502            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00503             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00504             "Measure_<T>::Minus::ctor()",
00505             "Arguments must be in the same Subsystem as this Measure.");
00506     }
00507 
00508     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minus, Measure_<T>);
00509 };
00510 
00512     // SCALE //
00514 
00518 template <class T>
00519 class Measure_<T>::Scale : public Measure_<T> {
00520 public:
00521     SimTK_MEASURE_HANDLE_PREAMBLE(Scale, Measure_<T>);
00522 
00523     Scale(Subsystem& sub, Real factor, const Measure_<T>& operand)
00524     :   Measure_<T>(sub,
00525                     new Implementation(factor, operand), SetHandle())
00526     {   SimTK_ERRCHK_ALWAYS
00527            (this->getSubsystem().isSameSubsystem(operand.getSubsystem()),
00528             "Measure_<T>::Scale::ctor()",
00529             "Argument must be in the same Subsystem as this Measure.");
00530     }
00531 
00532     SimTK_MEASURE_HANDLE_POSTSCRIPT(Scale, Measure_<T>);
00533 };
00534 
00536     // INTEGRATE //
00538 
00539 template <class T>
00540 class Measure_<T>::Integrate : public Measure_<T> {
00541 public:
00542     SimTK_MEASURE_HANDLE_PREAMBLE(Integrate, Measure_<T>);
00543 
00544     Integrate(Subsystem& sub, const Measure_<T>& deriv, const Measure_<T>& ic)
00545     :   Measure_<T>(sub, new Implementation(deriv,ic), SetHandle()) {}
00546 
00547     void setValue(State& s, const T& value) const 
00548     {   return getImpl().setValue(s, value); }
00549     const Measure_<T>& getDerivativeMeasure() const 
00550     {   return getImpl().getDerivativeMeasure(); }
00551     const Measure_<T>& getInitialConditionMeasure() const 
00552     {   return getImpl().getInitialConditionMeasure(); }
00553 
00554     Integrate& setDerivativeMeasure(const Measure_<T>& d)
00555     {   updImpl().setDerivativeMeasure(d); return *this; }
00556     Integrate& setInitialConditionMeasure(const Measure_<T>& ic)
00557     {   updImpl().setInitialConditionMeasure(ic); return *this; }
00558 
00559     SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate, Measure_<T>);
00560 };
00561 
00563     // DIFFERENTIATE //
00565 
00590 template <class T>
00591 class Measure_<T>::Differentiate : public Measure_<T> {
00592 public:
00593     SimTK_MEASURE_HANDLE_PREAMBLE(Differentiate, Measure_<T>);
00594 
00599     Differentiate(Subsystem& subsystem, const Measure_<T>& operand)
00600     :   Measure_<T>(subsystem, new Implementation(operand), SetHandle()) {}
00601 
00606     bool isUsingApproximation() const 
00607     {   return getImpl().isUsingApproximation(); }
00608 
00611     const Measure_<T>& getOperandMeasure() const 
00612     {   return getImpl().getOperandMeasure(); }
00613 
00617     Differentiate& setOperandMeasure(const Measure_<T>& operand)
00618     {   updImpl().setOperandMeasure(operand); return *this; }
00619 
00623     void setForceUseApproximation(bool mustApproximate)
00624     {   updImpl().setForceUseApproximation(mustApproximate); }
00625 
00630     bool getForceUseApproximation() const 
00631     {   return getImpl().getForceUseApproximation(); }
00632 
00633     SimTK_MEASURE_HANDLE_POSTSCRIPT(Differentiate, Measure_<T>);
00634 };
00635 
00637     // MINIMUM //
00639 
00674 template <class T>
00675 class Measure_<T>::Minimum : public Measure_<T> {
00676 public:
00677     SimTK_MEASURE_HANDLE_PREAMBLE(Minimum, Measure_<T>);
00678 
00679     Minimum(Subsystem& sub, const Measure_<T>& source, const Measure_<T>& sourceDot)
00680     :   Measure_<T>(sub, new Implementation(source, sourceDot), SetHandle()) {}
00681 
00682     void setValue(State& s, const T& value) const 
00683     {   return getImpl().setValue(s, value); }
00684     const Measure_<T>& getSourceMeasure() const 
00685     {   return getImpl().getSourceMeasure(); }
00686     const Measure_<T>& getSourceDerivativeMeasure() const 
00687     {   return getImpl().getSourceDerivativeMeasure(); }
00688 
00689     Minimum& setSourceMeasure(const Measure_<T>& s)
00690     {   updImpl().setSourceMeasure(s); return *this; }
00691     Minimum& setSourceDerivativeMeasure(const Measure_<T>& sdot)
00692     {   updImpl().setSourceDerivativeMeasure(sdot); return *this; }
00693 
00694     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minimum, Measure_<T>);
00695 };
00696 
00712 template <class T>
00713 class Measure_<T>::SampleAndHold : public Measure_<T> {
00714 public:
00715     SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold, Measure_<T>);
00716 
00717     SampleAndHold(Subsystem& sub, const Measure_<T>& source, EventIndex e);
00718 
00721     void setValue(State& s, const T& value) const;
00722 
00724     void sample(State& s) const;
00725 
00726     const Measure_<T>& getSource() const;
00727     EventIndex         getEvent() const;
00728 
00729     SampleAndHold& setSource(const Measure_<T>& s);
00730     SampleAndHold& setEvent(EventIndex);
00731 
00732     SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold, Measure_<T>);
00733 };
00734 
00735 } // namespace SimTK
00736 
00737 #endif // SimTK_SimTKCOMMON_MEASURE_H_

Generated on Thu Aug 12 16:37:12 2010 for SimTKcore by  doxygen 1.6.1