Simbody
|
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_