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-9 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 
00066 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH)    \
00067     class Implementation;                                 \
00068     explicit MH(Implementation* imp=0) : PH(imp) {}           \
00069     MH(Subsystem& sub, Implementation* imp, const SetHandle& sh) : PH(sub,imp,sh) {}
00070 
00092 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH)                  \
00093     static bool isA(const Measure& m)                           \
00094     {   return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; }  \
00095     static const MH& getAs(const Measure& m)                    \
00096     {   assert(isA(m)); return static_cast<const MH&>(m); }     \
00097     static MH& updAs(Measure& m)                                \
00098     {   assert(isA(m)); return static_cast<MH&>(m); }           \
00099     const Implementation& getImpl() const                                 \
00100     {   return dynamic_cast<const Implementation&>(Measure::getImpl());}  \
00101     Implementation& updImpl()                                             \
00102     {   return dynamic_cast<Implementation&>(Measure::updImpl());} 
00103 
00104 namespace SimTK {
00105 
00106 class State;
00107 class Subsystem;
00108 class System;
00109 class EventIndex;
00110 
00112 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
00113 
00115     // MEASURE //
00117 
00132 class SimTK_SimTKCOMMON_EXPORT Measure {
00133 protected:
00134     // This is used to make sure the automatically-generated handle
00135     // constructor doesn't conflict with an explicitly-defined one.
00136     class SetHandle {};
00137 
00138 public:
00139     class Implementation; // local; name is Measure::Implementation
00140 
00141     explicit Measure(Implementation* g=0);
00142     Measure(Subsystem&, Implementation* g, const SetHandle&);
00143     Measure(const Measure&);
00144     Measure& operator=(const Measure&);
00145     ~Measure();
00146 
00147     // At what Stage can we expect the value of this Measure to be available?
00148     Stage getValueDependence(const State&) const;
00149 
00150     // There can be multiple handles on the same Measure_.
00151     bool isSameMeasure(const Measure& other) const
00152     {   return impl && impl==other.impl;}
00153 
00154     bool isInSubsystem() const;
00155     const Subsystem& getSubsystem() const;
00156     MeasureIndex     getSubsystemMeasureIndex() const;
00157 
00158     // Internal use only
00159 
00160     // dynamic_cast the returned reference to a reference to your concrete
00161     // Implementation class.
00162     const Implementation& getImpl() const {assert(impl); return *impl;}
00163     Implementation&       updImpl()       {assert(impl); return *impl;}
00164 
00165     bool hasImpl() const {return impl!=0;}
00166 
00167 public:
00168     // These are built-in Measures with local class names. 
00169 
00170     // Templatized measures may have restrictions on the allowable template
00171     // type and may be specialized for particular types.
00172     template <class T> class Constant_;     // T is any assignable type
00173     template <class T> class SampleAndHold_;//    "
00174 
00175     // These accept any type that supports operator<, elementwise for 
00176     // vectors and matrices.
00177     template <class T> class Minimum_;
00178     template <class T> class Maximum_;
00179 
00180     // These accept floating point numerical template arguments only.
00181     template <class T> class Integrate_;
00182     template <class T> class Sinusoid_;
00183 
00184 
00185 
00186     // Default template arguments for the built-in Measures.
00187     typedef Constant_<Real> Constant;
00188     typedef Integrate_<Real> Integrate;
00189     typedef Sinusoid_<Real> Sinusoid;
00190 
00191 
00192 private:
00193     // This is the only data member in this class. Also, any class derived from
00194     // Measure must have *NO* data members at all (data goes in the Implementation class).
00195     Implementation* impl;
00196 
00197 friend class Implementation;
00198 };
00199 
00200 
00202     // MEASURE_<T> //
00204 
00208 template <class T>
00209 class Measure_ : public Measure {
00210 public:
00211     SimTK_MEASURE_HANDLE_PREAMBLE(Measure_, Measure);
00212 
00213     const T& getValue(const State& s) const {return getImpl().getValue(s);}
00214 
00215     SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, Measure);
00216 };
00217 
00218 
00220     // CONSTANT_<T> //
00222 
00228 template <class T>
00229 class Measure::Constant_ : public Measure_<T> {
00230 public:
00231     SimTK_MEASURE_HANDLE_PREAMBLE(Constant_, Measure_<T>);
00232 
00233     Constant_(Subsystem& sub, const T& value)
00234     :   Measure_<T>(sub, new Implementation(value), SetHandle()) {}
00235 
00237     Constant_& setValue(const T& value) {updImpl().setValue(value); return *this;}
00238 
00239     SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant_, Measure_<T>);
00240 };
00241 
00242 
00244     // SINUSOID_<T> //
00246 
00252 template <class T>
00253 class Measure::Sinusoid_ : public Measure_<T> {
00254 public:
00255     SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid_, Measure_<T>);
00256 
00257     Sinusoid_(Subsystem& sub,
00258               const T& amplitude, 
00259               const T& frequency,
00260               const T& phase=T(0))
00261     :   Measure_<T>(sub, new Implementation(amplitude,frequency,phase), SetHandle()) {}
00262 
00263     SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid_, Measure_<T>);
00264 };
00265 
00266 
00268     // INTEGRATE_<T> //
00270 
00271 template <class T>
00272 class Measure::Integrate_ : public Measure_<T> {
00273 public:
00274     SimTK_MEASURE_HANDLE_PREAMBLE(Integrate_, Measure_<T>);
00275 
00276     Integrate_(Subsystem& sub, const Measure_<T>& deriv, const Measure_<T>& ic)
00277     :   Measure_<T>(sub, new Implementation(deriv,ic), SetHandle()) {}
00278 
00279     void setValue(State& s, const T& value) const {return getImpl().setValue(s, value);}
00280     const Measure_<T>& getDerivativeMeasure() const {return getImpl().getDerivativeMeasure();}
00281     const Measure_<T>& getInitialConditionMeasure() const {return getImpl().getInitialConditionMeasure();}
00282 
00283     Integrate_& setDerivativeMeasure(const Measure_<T>& d)
00284     {   updImpl().setDerivativeMeasure(d); return *this; }
00285     Integrate_& setInitialConditionMeasure(const Measure_<T>& ic)
00286     {   updImpl().setInitialConditionMeasure(ic); return *this; }
00287 
00288     SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate_, Measure_<T>);
00289 };
00290 
00291 
00293     // MINIMUM_<T> //
00295 
00330 template <class T>
00331 class Measure::Minimum_ : public Measure_<T> {
00332 public:
00333     SimTK_MEASURE_HANDLE_PREAMBLE(Minimum_, Measure_<T>);
00334 
00335     Minimum_(Subsystem& sub, const Measure_<T>& source, const Measure_<T>& sourceDot)
00336     :   Measure_<T>(sub, new Implementation(source, sourceDot), SetHandle()) {}
00337 
00338     void setValue(State& s, const T& value) const {return getImpl().setValue(s, value);}
00339     const Measure_<T>& getSourceMeasure() const {return getImpl().getSourceMeasure();}
00340     const Measure_<T>& getSourceDerivativeMeasure() const {return getImpl().getSourceDerivativeMeasure();}
00341 
00342     Minimum_& setSourceMeasure(const Measure_<T>& s)
00343     {   updImpl().setSourceMeasure(s); return *this; }
00344     Minimum_& setSourceDerivativeMeasure(const Measure_<T>& sdot)
00345     {   updImpl().setSourceDerivativeMeasure(sdot); return *this; }
00346 
00347     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minimum_, Measure_<T>);
00348 };
00349 
00364 template <class T>
00365 class Measure::SampleAndHold_ : public Measure_<T> {
00366 public:
00367     SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold_, Measure_<T>);
00368 
00369     SampleAndHold_(Subsystem& sub, const Measure_<T>& source, EventIndex e);
00370 
00373     void setValue(State& s, const T& value) const;
00374 
00376     void sample(State& s) const;
00377 
00378     const Measure_<T>& getSource() const;
00379     EventIndex         getEvent() const;
00380 
00381     SampleAndHold_& setSource(const Measure_<T>& s);
00382     SampleAndHold_& setEvent(EventIndex);
00383 
00384     SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold_, Measure_<T>);
00385 };
00386 
00387 } // namespace SimTK
00388 
00389 #endif // SimTK_SimTKCOMMON_MEASURE_H_

Generated by  doxygen 1.6.2