00001 #ifndef _INTEGRABLE_NUMBER_H_
00002 #define _INTEGRABLE_NUMBER_H_
00003
00004 #include "CyclicNumber.h"
00005 #include "AbstractFilteredNumber.h"
00006
00007 namespace luma
00008 {
00009 namespace numbers
00010 {
00028 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00029 class IntegrableNumber: public AbstractFilteredNumber<T, sampleCount, maxOrder>
00030 {
00031 private:
00032 T mSamples[sampleCount];
00033 float mTimeSamples[sampleCount];
00034
00035 CyclicNumber<int> mCurrentIndex;
00036 T mCurrentValue;
00037 T mInitialValue;
00038
00039 IntegrableNumber<T, sampleCount, maxOrder - 1> mSum;
00040 float mTotalTime;
00041
00042 public:
00048 IntegrableNumber(T initialValue);
00049
00054 void setValue(T x, float elapsedTime = 1.0f);
00055
00063 void forceValue(T x, float elapsedTime = 1.0f);
00064
00075 T getValue(unsigned int order) const;
00076
00083 T getSample(int i) const;
00084 };
00085
00086 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00087 IntegrableNumber<T, sampleCount, maxOrder>::IntegrableNumber(T initialValue):
00088 mInitialValue(initialValue),
00089 mCurrentValue(initialValue),
00090 mCurrentIndex(0, 0, sampleCount, 1),
00091 mSum(initialValue),
00092 mTotalTime(sampleCount * TIME_UNIT)
00093 {
00094 for(int i = 0; i < sampleCount; i++)
00095 {
00096 mSamples[i] = initialValue;
00097 mTimeSamples[i] = TIME_UNIT;
00098 }
00099 }
00100
00101 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00102 void IntegrableNumber<T, sampleCount, maxOrder>::setValue(T x, float elapsedTime)
00103 {
00104 T sum = mSum.getValue(0);
00105
00106 mCurrentIndex++;
00107
00108 int index = mCurrentIndex;
00109 T newValue = x * elapsedTime;
00110
00111 mTotalTime += elapsedTime - mTimeSamples[index];
00112 sum += (newValue - mSamples[index]) / mTotalTime;
00113
00114 mSum.setValue(sum);
00115
00116 mSamples[index] = newValue;
00117 mCurrentValue = x;
00118
00119 }
00120
00121 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00122 void IntegrableNumber<T, sampleCount, maxOrder>::forceValue(T x, float elapsedTime)
00123 {
00124
00125 T newValue = x * elapsedTime;
00126
00127
00128 T sum = mInitialValue;
00129
00130 for(int i = 0; i < sampleCount; i++)
00131 {
00132 mSamples[i] = newValue;
00133 sum += newValue;
00134 }
00135
00136 mTotalTime = sampleCount * elapsedTime;
00137
00138 mSum.forceValue(sum / mTotalTime, elapsedTime);
00139
00140 mCurrentValue = x;
00141 }
00142
00143 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00144 T IntegrableNumber<T, sampleCount, maxOrder>::getValue(unsigned int order) const
00145 {
00146 if(order == 0)
00147 {
00148 return mCurrentValue;
00149 }
00150 else if(order > 0)
00151 {
00152 if(order <= maxOrder)
00153 {
00154 return mSum.getValue(order - 1);
00155 }
00156 }
00157
00158 return mInitialValue;
00159
00160 }
00161
00162 template <class T, unsigned int sampleCount, unsigned int maxOrder>
00163 T IntegrableNumber<T, sampleCount, maxOrder>::getSample(int i) const
00164 {
00165 return mSamples[i % sampleCount];
00166 }
00167
00173 template <class T, unsigned int sampleCount>
00174 class IntegrableNumber<T, sampleCount, 1>: public AbstractFilteredNumber<T, sampleCount, 1>
00175 {
00176 private:
00177 T mSamples[sampleCount];
00178 T mTimeSamples[sampleCount];
00179 CyclicNumber<int> mCurrentIndex;
00180 T mCurrentValue;
00181 T mInitialValue;
00182 T mSum;
00183 float mTotalTime;
00184
00185 public:
00189 IntegrableNumber(T initialValue);
00190
00194 void setValue(T x, float elapsedTime = 1.0f);
00195
00199 T getValue(unsigned int order) const;
00200
00201 T getSample(int i) const;
00202
00203 void forceValue(T x, float elapsedTime = 1.0f);
00204 };
00205
00206 template <class T, unsigned int sampleCount>
00207 IntegrableNumber<T, sampleCount, 1>::IntegrableNumber(T initialValue):
00208 mInitialValue(initialValue),
00209 mCurrentValue(initialValue),
00210 mCurrentIndex(0, 0, sampleCount, 1),
00211 mSum(initialValue),
00212 mTotalTime(sampleCount * TIME_UNIT)
00213 {
00214 for(int i = 0; i < sampleCount; i++)
00215 {
00216 mSamples[i] = initialValue;
00217 mTimeSamples[i] = TIME_UNIT;
00218 }
00219 }
00220
00221 template <class T, unsigned int sampleCount>
00222 void IntegrableNumber<T, sampleCount, 1>::setValue(T x, float elapsedTime)
00223 {
00224 mCurrentIndex++;
00225
00226 int index = mCurrentIndex;
00227
00228 T newValue = x * elapsedTime;
00229
00230 mTotalTime += elapsedTime - mTimeSamples[index];
00231 mSum += (newValue - mSamples[index]) / mTotalTime;
00232
00233
00234 mSamples[index] = newValue;
00235 mTimeSamples[index] = elapsedTime;
00236
00237 mCurrentValue = x;
00238 }
00239
00240 template <class T, unsigned int sampleCount>
00241 void IntegrableNumber<T, sampleCount, 1>::forceValue(T x, float elapsedTime)
00242 {
00243 T newValue = x * elapsedTime;
00244
00245 mSum = mInitialValue;
00246
00247 for(int i = 0; i < sampleCount; i++)
00248 {
00249 mSamples[i] = newValue;
00250 mTimeSamples[i] = elapsedTime;
00251
00252 mSum += newValue;
00253 }
00254
00255 mTotalTime = sampleCount * elapsedTime;
00256 mSum /= mTotalTime;
00257
00258
00259 mCurrentValue = x;
00260 }
00261
00262 template <class T, unsigned int sampleCount>
00263 T IntegrableNumber<T, sampleCount, 1>::getValue(unsigned int order) const
00264 {
00265 if(order == 0)
00266 {
00267 return mCurrentValue;
00268 }
00269 else if(order == 1)
00270 {
00271 return mSum;
00272 }
00273
00274 return mInitialValue;
00275 }
00276
00277 template <class T, unsigned int sampleCount>
00278 T IntegrableNumber<T, sampleCount, 1>::getSample(int i) const
00279 {
00280 return mSamples[i % sampleCount];
00281 }
00282
00288 template <class T, unsigned int sampleCount>
00289 class IntegrableNumber<T, sampleCount, 0>: public AbstractFilteredNumber<T, sampleCount, 0>
00290 {
00291 public:
00292 IntegrableNumber(T initialValue);
00293 };
00294
00295 template <class T, unsigned int sampleCount>
00296 IntegrableNumber<T, sampleCount, 0>::IntegrableNumber(T initialValue):
00297 AbstractFilteredNumber(initialValue)
00298 {
00299 }
00300
00301 }}
00302
00303 #endif //_INTEGRABLE_NUMBER_H_