Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Measure.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_MEASURE_H_
2 #define SimTK_SimTKCOMMON_MEASURE_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2008-13 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
37 #include "SimTKcommon/basics.h"
38 #include "SimTKcommon/Simmatrix.h"
39 
40 #include <cassert>
41 
62 // Helper macro shared by SimTK_MEASURE_HANDLE_PREAMBLE and
63 // SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT.
64 #define SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
65  class Implementation; \
66  explicit MH(Implementation* imp) : PH(imp) {} \
67  MH(SimTK::Subsystem& sub, Implementation* imp, \
68  const SimTK::AbstractMeasure::SetHandle& sh) \
69  : PH(sub,imp,sh) {} \
70  MH& operator=(const MH& src) {PH::operator=(src); return *this;}\
71  MH& shallowAssign(const MH& src) {PH::shallowAssign(src); return *this;}\
72  MH& deepAssign(const MH& src) {PH::deepAssign(src); return *this;}
73 
74 
75 // The default constructor for concrete classes should instantiate
76 // a default-constructed Implementation object if no Implementation object
77 // is provided.
78 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH) \
79  SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
80  MH() : PH(new Implementation()) {} \
81  explicit MH(SimTK::Subsystem& sub) \
82  : PH(sub,new Implementation(), typename PH::SetHandle()) {}
83 
84 
85 
86 // The default constructor for a still-abstract derived class can't
87 // instantiate an Implementation.
88 #define SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(MH,PH) \
89  SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
90  MH() : PH() {}
91 
111 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH) \
112  static bool isA(const SimTK::AbstractMeasure& m) \
113  { return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; } \
114  static const MH& getAs(const SimTK::AbstractMeasure& m) \
115  { assert(isA(m)); return static_cast<const MH&>(m); } \
116  static MH& updAs(SimTK::AbstractMeasure& m) \
117  { assert(isA(m)); return static_cast<MH&>(m); } \
118  const Implementation& getImpl() const \
119  { return SimTK_DYNAMIC_CAST_DEBUG<const Implementation&> \
120  (SimTK::AbstractMeasure::getImpl());} \
121  Implementation& updImpl() \
122  { return SimTK_DYNAMIC_CAST_DEBUG<Implementation&> \
123  (SimTK::AbstractMeasure::updImpl());}
124 
125 namespace SimTK {
126 
127 class State;
128 class Subsystem;
129 class System;
130 class EventId;
131 
133 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
134 
135 //==============================================================================
136 // ABSTRACT MEASURE
137 //==============================================================================
152 protected:
156  class SetHandle {};
157 
158 public:
159  class Implementation; // local; name is AbstractMeasure::Implementation
160 
164  explicit AbstractMeasure(Implementation* g=0);
165 
171 
175 
179  AbstractMeasure& operator=(const AbstractMeasure& source)
180  { return shallowAssign(source); }
181 
184  ~AbstractMeasure();
185 
191  AbstractMeasure& shallowAssign(const AbstractMeasure&);
192 
197  AbstractMeasure& deepAssign(const AbstractMeasure& source);
198 
206  int getNumTimeDerivatives() const;
207 
216  Stage getDependsOnStage(int derivOrder=0) const;
217 
218 
220  bool isSameMeasure(const AbstractMeasure& other) const
221  { return impl && impl==other.impl;}
222 
223  bool isEmptyHandle() const {return !hasImpl();}
224 
226  bool isInSubsystem() const;
230  const Subsystem& getSubsystem() const;
234  MeasureIndex getSubsystemMeasureIndex() const;
235 
236  // Internal use only
237 
238  // dynamic_cast the returned reference to a reference to your concrete
239  // Implementation class.
240  const Implementation& getImpl() const {assert(impl); return *impl;}
241  Implementation& updImpl() {assert(impl); return *impl;}
242  bool hasImpl() const {return impl!=0;}
243 
244  int getRefCount() const;
245 private:
246  // This is the only data member in this class. Also, any class derived
247  // from AbstractMeasure must have *NO* data members at all (data goes
248  // in the Implementation class).
249  Implementation* impl;
250 
251 friend class Implementation;
252 };
253 
254 
255 //==============================================================================
256 // MEASURE <T>
257 //==============================================================================
260 template <class T>
261 class Measure_ : public AbstractMeasure {
262 public:
266 
274  const T& getValue(const State& s, int derivOrder=0) const
275  { return getImpl().getValue(s,derivOrder); }
276 
283  Measure_& setDefaultValue(const T& defaultValue)
284  { updImpl().setDefaultValue(defaultValue); return *this; }
285 
288  const T& getDefaultValue() const
289  { return getImpl().getDefaultValue(); }
290 
291  // These are built-in Measures with local class names.
292 
293  // Templatized measures may have restrictions on the allowable template
294  // type and may be specialized for particular types.
295  class Zero; // T is any numerical type
296  class One; // T is any numerical type
297  class Constant; // T is any assignable type
298  class Time; // T is any type for which T(t) makes sense.
299  class Variable; // T is any assignable type (state)
300  class Result; // T is any assignable type (cache)
301  class SampleAndHold;// T is any assignable type
302  class Delay; // T is any assignable type
303 
304  // This requires any numerical type.
305  class Plus;
306  class Minus;
307  class Scale;
308  class Differentiate;
309 
310  // These find extreme values *in time*, not among inputs at the same
311  // time. They perform elementwise on aggregate types.
312  class Extreme; // base class for min/max/minabs/maxabs
313  class Minimum; // most positive value
314  class Maximum; // most negative value
315  class MinAbs; // the signed quantity whose absolute value was min
316  class MaxAbs; // the signed quantity whose absolute value was max
317 
318  // These accept floating point numerical template arguments only.
319  class Integrate;
320  class Sinusoid;
321 
323 };
324 
329 
330 
331 //==============================================================================
332 // CONSTANT
333 //==============================================================================
338 template <class T>
339 class Measure_<T>::Constant : public Measure_<T> {
340 public:
342 
345  explicit Constant(const T& value)
346  : Measure_<T>(new Implementation(value)) {}
347 
350  Constant(Subsystem& sub, const T& value)
351  : Measure_<T>(sub, new Implementation(value),
353 
356  Constant& setValue(const T& value)
357  { updImpl().setValue(value); return *this; }
358 
360 };
361 
362 //==============================================================================
363 // ZERO
364 //==============================================================================
368 template <class T>
369 class Measure_<T>::Zero : public Measure_<T>::Constant {
370 public:
371  Zero();
372  explicit Zero(Subsystem& sub);
373 };
374 
375 template <>
376 class Measure_< Vector >::Zero : public Measure_< Vector >::Constant {
377 public:
378  explicit Zero(int size);
379  Zero(Subsystem& sub, int size);
380 };
381 
382 //==============================================================================
383 // ONE
384 //==============================================================================
388 template <class T>
389 class Measure_<T>::One : public Measure_<T>::Constant {
390 public:
391  One();
392  explicit One(Subsystem& sub);
393 };
394 
395 template <>
396 class Measure_< Vector >::One : public Measure_< Vector >::Constant {
397 public:
398  explicit One(int size);
399  One(Subsystem& sub, int size);
400 };
401 
402 //==============================================================================
403 // TIME
404 //==============================================================================
406 template <class T>
407 class Measure_<T>::Time : public Measure_<T> {
408 public:
410 
412 };
413 
414 //==============================================================================
415 // VARIABLE
416 //==============================================================================
419 template <class T>
420 class Measure_<T>::Variable : public Measure_<T> {
421 public:
423 
424  // TODO: should not require invalidated Stage here. Instead,
425  // should have a unique "generation" counter for this variable
426  // and allow subsequent users to check it.
427  Variable(Subsystem& sub, Stage invalidates, const T& defaultValue)
428  : Measure_<T>(sub, new Implementation(invalidates, defaultValue),
430 
431 
432  void setValue(State& state, const T& value) const
433  { getImpl().setValue(state, value); }
434 
436 };
437 
438 //==============================================================================
439 // RESULT
440 //==============================================================================
454 template <class T>
455 class Measure_<T>::Result : public Measure_<T> {
456 public:
458 
459  // TODO: should not require invalidated Stage here. Instead,
460  // should have a unique "generation" counter for this cache entry
461  // and allow subsequent users of the value to check it.
462 
477  Result(Subsystem& sub, Stage dependsOn, Stage invalidated)
478  : Measure_<T>(sub, new Implementation(dependsOn, invalidated),
480 
484  Stage getInvalidatedStage() const {return getImpl().getInvalidatedStage();}
492  Result& setDependsOnStage(Stage dependsOn)
493  { updImpl().setDependsOnStage(dependsOn); return *this; }
499  Result& setInvalidatedStage(Stage invalidated)
500  { updImpl().setInvalidatedStage(invalidated); return *this; }
501 
514  Result& setIsPresumedValidAtDependsOnStage(bool presume)
515  { updImpl().setIsPresumedValidAtDependsOnStage(presume); return *this; }
516 
519  bool getIsPresumedValidAtDependsOnStage() const
521 
522 
528  T& updValue(const State& state) const
529  { return getImpl().updValue(state); }
530 
537  void markAsValid(const State& state) const {getImpl().markAsValid(state);}
538 
542  bool isValid(const State& state) const {return getImpl().isValid(state);}
543 
551  void markAsNotValid(const State& state) const
552  { getImpl().markAsNotValid(state); }
553 
557  void setValue(const State& state, const T& value) const
558  { updValue(state) = value; markAsValid(state); }
559 
561 };
562 
563 //==============================================================================
564 // SINUSOID
565 //==============================================================================
572 template <class T>
573 class Measure_<T>::Sinusoid : public Measure_<T> {
574 public:
576 
578  const T& amplitude,
579  const T& frequency,
580  const T& phase=T(0))
581  : Measure_<T>(sub, new Implementation(amplitude,frequency,phase),
583 
585 };
586 
587 //==============================================================================
588 // PLUS
589 //==============================================================================
594 template <class T>
595 class Measure_<T>::Plus : public Measure_<T> {
596 public:
598 
599  Plus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
600  : Measure_<T>(sub, new Implementation(left, right),
603  ( this->getSubsystem().isSameSubsystem(left.getSubsystem())
604  && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
605  "Measure_<T>::Plus::ctor()",
606  "Arguments must be in the same Subsystem as this Measure.");
607  }
608 
610 };
611 
612 //==============================================================================
613 // MINUS
614 //==============================================================================
619 template <class T>
620 class Measure_<T>::Minus : public Measure_<T> {
621 public:
623 
624  Minus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
625  : Measure_<T>(sub, new Implementation(left, right),
628  ( this->getSubsystem().isSameSubsystem(left.getSubsystem())
629  && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
630  "Measure_<T>::Minus::ctor()",
631  "Arguments must be in the same Subsystem as this Measure.");
632  }
633 
635 };
636 
637 //==============================================================================
638 // SCALE
639 //==============================================================================
644 template <class T>
645 class Measure_<T>::Scale : public Measure_<T> {
646 public:
648 
649  Scale(Subsystem& sub, Real factor, const Measure_<T>& operand)
650  : Measure_<T>(sub, new Implementation(factor, operand),
653  (this->getSubsystem().isSameSubsystem(operand.getSubsystem()),
654  "Measure_<T>::Scale::ctor()",
655  "Argument must be in the same Subsystem as this Measure.");
656  }
657 
659  const Measure_<T>& getOperandMeasure() const
660  { return getImpl().getOperandMeasure(); }
661 
663 };
664 
665 //==============================================================================
666 // INTEGRATE
667 //==============================================================================
674 template <class T>
675 class Measure_<T>::Integrate : public Measure_<T> {
676 public:
678 
685  Integrate(Subsystem& subsystem,
686  const Measure_<T>& deriv,
687  const Measure_<T>& ic,
688  const T& initAlloc=T(0))
689  : Measure_<T>(subsystem, new Implementation(deriv,ic,initAlloc),
691 
694  void setValue(State& s, const T& value) const
695  { return getImpl().setValue(s, value); }
696 
698  const Measure_<T>& getDerivativeMeasure() const
699 
700  { return getImpl().getDerivativeMeasure(); }
703  const Measure_<T>& getInitialConditionMeasure() const
704  { return getImpl().getInitialConditionMeasure(); }
705 
706  Integrate& setDerivativeMeasure(const Measure_<T>& d)
707  { updImpl().setDerivativeMeasure(d); return *this; }
708  Integrate& setInitialConditionMeasure(const Measure_<T>& ic)
709  { updImpl().setInitialConditionMeasure(ic); return *this; }
710 
712 };
713 
714 //==============================================================================
715 // DIFFERENTIATE
716 //==============================================================================
741 template <class T>
742 class Measure_<T>::Differentiate : public Measure_<T> {
743 public:
745 
750  Differentiate(Subsystem& subsystem, const Measure_<T>& operand)
751  : Measure_<T>(subsystem, new Implementation(operand),
753 
758  bool isUsingApproximation() const
759  { return getImpl().isUsingApproximation(); }
760 
763  const Measure_<T>& getOperandMeasure() const
764  { return getImpl().getOperandMeasure(); }
765 
769  Differentiate& setOperandMeasure(const Measure_<T>& operand)
770  { updImpl().setOperandMeasure(operand); return *this; }
771 
775  void setForceUseApproximation(bool mustApproximate)
776  { updImpl().setForceUseApproximation(mustApproximate); }
777 
782  bool getForceUseApproximation() const
783  { return getImpl().getForceUseApproximation(); }
784 
786 };
787 
788 //==============================================================================
789 // EXTREME, MINIMUM, MAXIMUM, MINABS, MAXABS
790 //==============================================================================
834 template <class T>
835 class Measure_<T>::Extreme : public Measure_<T> {
836 public:
838 
839  enum Operation {
840  MaxAbs, // default
844  };
845 
849  Extreme(Subsystem& sub, const Measure_<T>& operand, Operation op=MaxAbs)
850  : Measure_<T>(sub, new Implementation(operand, op),
852 
854  Extreme& setOperation(Operation op)
855  { updImpl().setOperation(op); return *this; }
856 
858  Operation getOperation() const {return getImpl().getOperation();}
859 
865  Real getTimeOfExtremeValue(const State& state) const
866  { return getImpl().getTimeOfExtremeValue(state); }
867 
868  void setValue(State& s, const T& value) const
869  { return getImpl().setValue(s, value); }
870 
871  const Measure_<T>& getOperandMeasure() const
872  { return getImpl().getOperandMeasure(); }
873 
874  Extreme& setOperandMeasure(const Measure_<T>& s)
875  { updImpl().setOperandMeasure(s); return *this; }
876 
878 };
879 
882 template <class T>
883 class Measure_<T>::Minimum : public Measure_<T>::Extreme {
884  typedef typename Measure_<T>::Extreme Super;
885 public:
886  Minimum(Subsystem& sub, const Measure_<T>& operand)
887  : Super(sub, operand, Super::Minimum) {}
888 };
889 
892 template <class T>
893 class Measure_<T>::Maximum : public Measure_<T>::Extreme {
894  typedef typename Measure_<T>::Extreme Super;
895 public:
896  Maximum(Subsystem& sub, const Measure_<T>& operand)
897  : Super(sub, operand, Super::Maximum) {}
898 };
899 
902 template <class T>
903 class Measure_<T>::MaxAbs : public Measure_<T>::Extreme {
904  typedef typename Measure_<T>::Extreme Super;
905 public:
906  MaxAbs(Subsystem& sub, const Measure_<T>& operand)
907  : Super(sub, operand, Super::MaxAbs) {}
908 };
909 
913 template <class T>
914 class Measure_<T>::MinAbs : public Measure_<T>::Extreme {
915  typedef typename Measure_<T>::Extreme Super;
916 public:
917  MinAbs(Subsystem& sub, const Measure_<T>& operand)
918  : Super(sub, operand, Super::MinAbs) {}
919 };
920 
921 //==============================================================================
922 // DELAY
923 //==============================================================================
970 template <class T>
971 class Measure_<T>::Delay : public Measure_<T> {
972 public:
979  Delay(Subsystem& sub, const Measure_<T>& source, Real delay)
980  : Measure_<T>(sub, new Implementation(source, delay),
982 
988  Delay& setUseLinearInterpolationOnly(bool linearOnly)
989  { updImpl().setUseLinearInterpolationOnly(linearOnly); return *this; }
990 
1004  Delay& setCanUseCurrentValue(bool canUseCurrentValue)
1005  { updImpl().setCanUseCurrentValue(canUseCurrentValue); return *this; }
1006 
1008  Delay& setSourceMeasure(const Measure_<T>& source)
1009  { updImpl().setSourceMeasure(source); return *this; }
1010 
1012  Delay& setDelay(Real delay)
1013  { updImpl().setDelay(delay); return *this; }
1014 
1016  bool getUseLinearInterpolationOnly() const
1017  { return getImpl().getUseLinearInterpolationOnly(); }
1018 
1020  bool getCanUseCurrentValue() const
1021  { return getImpl().getCanUseCurrentValue(); }
1022 
1024  const Measure_<T>& getSourceMeasure() const
1025  { return getImpl().getSourceMeasure(); }
1026 
1029  Real getDelay() const
1030  { return getImpl().getDelay(); }
1031 
1035 };
1036 
1037 //==============================================================================
1038 // SAMPLE AND HOLD
1039 //==============================================================================
1054 template <class T>
1055 class Measure_<T>::SampleAndHold : public Measure_<T> {
1056 public:
1058 
1059  SampleAndHold(Subsystem& sub, const Measure_<T>& source, EventId e);
1060 
1063  void setValue(State& s, const T& value) const;
1064 
1066  void sample(State& s) const;
1067 
1068  const Measure_<T>& getSource() const;
1069  EventId getEventId() const;
1070 
1071  SampleAndHold& setSource(const Measure_<T>& s);
1072  SampleAndHold& setEventId(EventId);
1073 
1075 };
1076 
1077 } // namespace SimTK
1078 
1079 #endif // SimTK_SimTKCOMMON_MEASURE_H_