00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef ArmageTron_tPolynomial_H
00029 #define ArmageTron_tPolynomial_H
00030
00031 #include "tError.h"
00032 #include <math.h>
00033 #include "tArray.h"
00034
00035 #include <iostream>
00036 #include <string>
00037
00038 #define REAL float
00039 #define MAX(a, b) ((a>b)?a:b)
00040 #define MIN(a, b) ((a<b)?a:b)
00041
00042
00044 template <typename T>
00045 class tPolynomial
00046 {
00047 public:
00048
00049 tPolynomial();
00050 explicit tPolynomial(int count);
00051 tPolynomial(REAL newCoefs[], int count);
00052 tPolynomial(REAL value);
00053 tPolynomial(tArray<REAL> newCoefs);
00054 tPolynomial(const tPolynomial<T> &tf);
00055 tPolynomial(std::string str);
00056
00057 virtual ~tPolynomial()
00058 {
00059 }
00060
00061 void parse(std::string str);
00062
00063 virtual REAL evaluate( REAL currentVarValue ) const;
00064 inline REAL operator()( REAL currentVarValue ) const;
00065
00066 tPolynomial<T> const operator*( REAL constant ) const;
00067 tPolynomial<T> const operator*( const tPolynomial<T> & tfRight ) const ;
00068 tPolynomial<T> const operator+( REAL constant ) const ;
00069 tPolynomial<T> const operator+( const tPolynomial<T> &tfRight ) const ;
00070 tPolynomial<T> & operator+=( const tPolynomial<T> &tfRight ) ;
00071
00072 tPolynomial<T> const substitute( const tPolynomial<T> &other ) const;
00073
00074 REAL &operator[](int index);
00075 REAL const &operator[](int index) const;
00076 void operator=(tPolynomial<T> const &other);
00077
00078 void addConstant(REAL constant) {
00079 if (coefs.Len()==0) {
00080 coefs.SetLen(1);
00081 coefs[0] = 0;
00082 }
00083 coefs[0] += constant;
00084 }
00085
00086 tPolynomial<T> adaptToNewReferenceVarValue(REAL currentVarValue) const;
00087 tPolynomial<T> translate(REAL currentVarValue) const;
00088 void changeRate(REAL newRate, int newRateLength, REAL currentVarValue);
00089
00090 void setRates(REAL newValues[], int newValuesLength, REAL currentVarValue);
00091 void setRates(tArray<REAL> newValues, REAL currentVarValue);
00092
00093 virtual T & ReadSync( T & m );
00094 virtual T & WriteSync( T & m ) const;
00095
00096 template<typename D>
00097 friend bool operator == (const tPolynomial<D> & left, const tPolynomial<D> & right);
00098 template<typename D>
00099 friend bool operator != (const tPolynomial<D> & left, const tPolynomial<D> & right);
00100
00101 virtual std::string toString() const;
00102 tPolynomial<T> const clamp(REAL min, REAL max, REAL currentVarValue);
00103
00104 int Len() const{
00105 return coefs.Len();
00106 };
00107
00108 void setAtSameReferenceVarValue(const tPolynomial<T> & other);
00109 protected:
00110 void setReferenceVarValue(REAL newReferenceVarValue) {
00111 referenceVarValue = newReferenceVarValue;
00112 }
00113 void growCoefsArray(int newLength);
00114
00115
00116 REAL referenceVarValue;
00117 tArray<REAL> coefs;
00118 };
00119
00120
00121
00122
00123
00124
00125
00126 template<typename T>
00127 T & operator << ( T & m, tPolynomial<T> const & f );
00128 template<typename T>
00129 T & operator >> ( T & m, tPolynomial<T> & f );
00130 template<typename T>
00131 bool operator == (const tPolynomial<T> & left, const tPolynomial<T> & right);
00132 template<typename T>
00133 bool operator != (const tPolynomial<T> & left, const tPolynomial<T> & right);
00134
00135 template <typename T>
00136 tPolynomial<T>::tPolynomial(int count)
00137 : referenceVarValue(0.0),
00138 coefs(count)
00139 {
00140
00141 for (int i=0; i<coefs.Len(); i++)
00142 coefs[i] = 0.0f;
00143 }
00144
00145 template <typename T>
00146 tPolynomial<T>::tPolynomial()
00147 : referenceVarValue(0.0),
00148 coefs(0)
00149 {
00150
00151 }
00152
00153 template <typename T>
00154 tPolynomial<T>::tPolynomial(REAL newCoefs[], int count)
00155 : referenceVarValue(0.0),
00156 coefs(count)
00157 {
00158 for (int i=0; i<coefs.Len(); i++)
00159 coefs[i] = newCoefs[i];
00160 }
00161
00162 template <typename T>
00163 tPolynomial<T>::tPolynomial(REAL value)
00164 : referenceVarValue(0.0),
00165 coefs(1)
00166 {
00167 coefs[0] = value;
00168 }
00169
00170 template <typename T>
00171 tPolynomial<T>::tPolynomial(tArray<REAL> newCoefs)
00172 : referenceVarValue(0.0),
00173 coefs(newCoefs)
00174 {
00175
00176 }
00177
00178 template <typename T>
00179 tPolynomial<T>::tPolynomial(const tPolynomial<T> &tf)
00180 : referenceVarValue(tf.referenceVarValue),
00181 coefs(tf.coefs)
00182 {
00183
00184 }
00185
00186
00187
00188
00189
00190
00194
00195
00196 template <typename T>
00197 REAL tPolynomial<T>::operator ( )( REAL currentVarValue ) const
00198 {
00199 return evaluate( currentVarValue );
00200 }
00201
00202
00203
00204
00205
00206
00212
00213
00214 template<typename T> T & operator << ( T & m, tPolynomial<T> const & f )
00215 {
00216
00217 unsigned short ID = 1;
00218 m.Write( ID );
00219
00220 return f.WriteSync(m);
00221 }
00222
00223
00224
00225
00226
00227
00233
00234
00235 template<typename T> T & operator >> ( T & m, tPolynomial<T> & f )
00236 {
00237
00238 unsigned short ID;
00239 m.Read(ID);
00240 tASSERT( ID == 1 ) ;
00241
00242 return f.ReadSync(m);
00243 }
00244
00248 #define DELTA 1e-3
00249
00250 template<typename T>
00251 bool operator == (const tPolynomial<T> & left, const tPolynomial<T> & right)
00252 {
00253 tPolynomial<T> tRebasedRight;
00254
00255
00256 if (false == ( fabs(left.referenceVarValue - right.referenceVarValue) < DELTA)) {
00257
00258 tRebasedRight = right.adaptToNewReferenceVarValue(left.referenceVarValue);
00259 }
00260 else {
00261
00262 tRebasedRight = right;
00263 }
00264
00265
00266
00267 int maxLength = MAX(left.coefs.Len(), right.coefs.Len());
00268 int minLength = MIN(left.coefs.Len(), right.coefs.Len());
00269
00270 bool res = true;
00271
00272
00273 for (int i=0; i<minLength; i++) {
00274 if ( fabs(left[i] - tRebasedRight[i]) >= DELTA ) {
00275 res = false;
00276 break;
00277 }
00278 }
00279
00280 for (int i=minLength; i<maxLength; i++) {
00281
00282 if (left.coefs.Len()>tRebasedRight.coefs.Len()) {
00283 if (fabs(left[i]) >= DELTA) {
00284 res = false;
00285 break;
00286 }
00287 }
00288 else {
00289 if (fabs(tRebasedRight[i]) >= DELTA) {
00290 res = false;
00291 break;
00292 }
00293 }
00294 }
00295 return res;
00296 }
00297
00298 template<typename T>
00299 bool operator != (const tPolynomial<T> & left, const tPolynomial<T> & right)
00300 {
00301 return !(left == right);
00302 }
00303
00304
00308 template <typename T>
00309 tPolynomial<T> tPolynomial<T>::adaptToNewReferenceVarValue(REAL currentVarValue) const
00310 {
00311 tPolynomial<T> tf(*this);
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 REAL deltaVariableValue = currentVarValue - referenceVarValue;
00326
00327
00328 for (int coefIndex=0; coefIndex<coefs.Len(); coefIndex++) {
00329 REAL newCoefValue = 0.0;
00330 for (int j=coefs.Len()-1; j>coefIndex; j--) {
00331 newCoefValue = (newCoefValue + coefs[j] ) * deltaVariableValue /(j - coefIndex);
00332 }
00333 tf.coefs[coefIndex] += newCoefValue;
00334 }
00335
00336 tf.setReferenceVarValue(currentVarValue);
00337 return tf;
00338 }
00339
00343 template <typename T>
00344 tPolynomial<T> tPolynomial<T>::translate(REAL currentVarValue) const
00345 {
00346 tPolynomial<T> tf(*this);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 REAL deltaVariableValue = currentVarValue - referenceVarValue;
00361
00362
00363 for (int coefIndex=0; coefIndex<coefs.Len(); coefIndex++) {
00364 REAL newCoefValue = 0.0;
00365 for (int j=coefs.Len()-1; j>coefIndex; j--) {
00366 newCoefValue = (newCoefValue + coefs[j] ) * deltaVariableValue;
00367 }
00368 tf.coefs[coefIndex] += newCoefValue;
00369 }
00370
00371 tf.setReferenceVarValue(currentVarValue);
00372 return tf;
00373 }
00374
00378 template <typename T>
00379 void tPolynomial<T>::changeRate(REAL newRate, int newRateIndex, REAL currentVarValue)
00380 {
00381 if (coefs.Len() <= newRateIndex) {
00382 int oldLength = coefs.Len();
00383 coefs.SetLen(newRateIndex + 1);
00384 for (int i=oldLength; i<newRateIndex; i++) {
00385 coefs[i] = 0.0;
00386 }
00387 }
00388
00389 *this = adaptToNewReferenceVarValue(currentVarValue);
00390
00391 coefs[newRateIndex] = newRate;
00392 }
00393
00397 template <typename T>
00398 void tPolynomial<T>::setRates(REAL newValues[], int newValuesLength, REAL currentVarValue)
00399 {
00400 if (coefs.Len() < newValuesLength) {
00401 int oldLength = coefs.Len();
00402 coefs.SetLen(newValuesLength + 1);
00403 for (int i=oldLength; i<newValuesLength; i++) {
00404 coefs[i] = 0.0;
00405 }
00406 }
00407
00408 setReferenceVarValue(currentVarValue);
00409
00410 for (int i=0; i<newValuesLength; i++) {
00411 coefs[i] = newValues[i];
00412 }
00413 }
00414
00415 template <typename T>
00416 void tPolynomial<T>::setRates(tArray<REAL> newValues, REAL currentVarValue)
00417 {
00418 coefs = newValues;
00419 setReferenceVarValue(currentVarValue);
00420 }
00421
00422 template <typename T>
00423 REAL tPolynomial<T>::evaluate( REAL currentVarValue ) const
00424 {
00425 REAL deltaVariableValue = (currentVarValue - referenceVarValue);
00426
00427 REAL res = 0.0;
00428
00429
00430 for (int i=coefs.Len()-1; i>0; i--) {
00431 res = (res + coefs[i]/i) * deltaVariableValue;
00432 }
00433 if (coefs.Len()!=0)
00434 res += (coefs[0]);
00435
00436 return res;
00437
00438 }
00439
00440 template <typename T>
00441 T & tPolynomial<T>::WriteSync( T & m ) const
00442 {
00443 m << referenceVarValue;
00444
00445 m << coefs.Len();
00446
00447 for (int i=0; i<coefs.Len(); i++)
00448 {
00449 m << coefs[i];
00450 }
00451
00452 return m;
00453 }
00454
00455 template <typename T>
00456 T & tPolynomial<T>::ReadSync( T & m )
00457 {
00458 m >> referenceVarValue;
00459
00460
00461 int newLength = 0;
00462 m >> newLength;
00463 coefs.SetLen(newLength);
00464
00465 for (int i=0; i<coefs.Len(); i++)
00466 {
00467 m >> coefs[i];
00468 }
00469
00470 return m;
00471 }
00472
00473 template <typename T>
00474 tPolynomial<T> const tPolynomial<T>::operator*( REAL constant ) const {
00475 tPolynomial<T> tf(*this);
00476
00477 for (int i=0; i<coefs.Len(); i++) {
00478 tf[i] *= constant;
00479 }
00480 return tf;
00481 }
00482
00483 template <typename T>
00484 tPolynomial<T> const tPolynomial<T>::operator*( const tPolynomial<T> & tfRight ) const {
00485 tPolynomial<T> tf;
00486 tf.setAtSameReferenceVarValue(tfRight);
00487
00488
00489
00490 int newLength =
00491 (0 == this->coefs.Len() || 0 == tfRight.coefs.Len())
00492 ? 0
00493 : (this->coefs.Len() + tfRight.coefs.Len() - 1);
00494
00495 int oldLength = tf.coefs.Len();
00496 tf.coefs.SetLen(newLength);
00497 for (int i=oldLength; i<newLength; i++) {
00498 tf[i] = 0.0;
00499 }
00500
00501 if (0 == newLength) {
00502
00503 }
00504 else {
00505 for (int i=0; i<this->coefs.Len(); i++) {
00506 for (int j=0; j<tfRight.coefs.Len(); j++) {
00507 tf[i+j] += (this->coefs[i]) * tfRight[j];
00508 }
00509 }
00510 }
00511 return tf;
00512 }
00513
00514 template <typename T>
00515 tPolynomial<T> const tPolynomial<T>::operator+( REAL constant ) const {
00516 tPolynomial<T> tf(*this);
00517 tf[0] += constant;
00518 return tf;
00519 }
00520
00521 template <typename T>
00522 tPolynomial<T> const tPolynomial<T>::operator+( const tPolynomial<T> &tfRight ) const {
00523
00524 tPolynomial<T> tRebasedRight(tfRight.adaptToNewReferenceVarValue(this->referenceVarValue));
00525
00526 int maxLength = MAX(this->coefs.Len(), tfRight.coefs.Len());
00527
00528
00529 tRebasedRight.coefs.SetLen(maxLength);
00530
00531 for (int i=0; i<this->coefs.Len(); i++) {
00532 tRebasedRight[i] += coefs[i];
00533 }
00534
00535 return tRebasedRight;
00536 }
00537
00538 template <typename T>
00539 tPolynomial<T> & tPolynomial<T>::operator+=( const tPolynomial<T> &tfRight ) {
00540
00541 tPolynomial<T> tRebasedRight = tfRight.adaptToNewReferenceVarValue(this->referenceVarValue);
00542
00543 int maxLength = MAX(this->coefs.Len(), tfRight.coefs.Len());
00544
00545 coefs.SetLen(maxLength);
00546
00547 for (int i=0; i<maxLength; i++) {
00548 coefs[i] += tRebasedRight[i];
00549 }
00550
00551 return *this;
00552 }
00553
00557 template <typename T>
00558 tPolynomial<T> const tPolynomial<T>::substitute( const tPolynomial<T> &other ) const {
00559 tPolynomial<T> tf(0);
00560 tf.setAtSameReferenceVarValue(other);
00561 for(int i=this->Len()-1; i>0; i--) {
00562 tf = (tf + (*this)[i]) * other;
00563 }
00564 if(0 != this->Len()) {
00565 tf = tf + (*this)[0];
00566 }
00567
00568 return tf;
00569 }
00570
00571 template<typename T>
00572 REAL &tPolynomial<T>::operator[](int index)
00573 {
00574
00575 if (index >= coefs.Len()) {
00576 int previousLength = coefs.Len();
00577 coefs.SetLen(index + 1);
00578 for (int i=previousLength; i<coefs.Len(); i++) {
00579 coefs[i] = 0.0;
00580 }
00581 }
00582
00583 return coefs[index];
00584 }
00585
00586 template <typename T>
00587 REAL const &tPolynomial<T>::operator[](int index) const
00588 {
00589 return coefs[index];
00590 }
00591
00592 template <typename T>
00593 void tPolynomial<T>::operator=(tPolynomial<T> const &other)
00594 {
00595 coefs = other.coefs;
00596 referenceVarValue = other.referenceVarValue;
00597 }
00598
00599 template <typename T>
00600 tPolynomial<T>::tPolynomial(std::string str)
00601 : referenceVarValue(0.0),
00602 coefs(0)
00603 {
00604 parse(str);
00605 }
00606
00607 template <typename T>
00608 void tPolynomial<T>::parse(std::string str)
00609 {
00610 int pos;
00611 int prevPos = 0;
00612 int index = 0;
00613
00614 #define TPOLYNOMIAL_DELIMITER ';'
00615
00616 pos = str.find(TPOLYNOMIAL_DELIMITER, 0);
00617 if(-1 != pos) {
00618 do{
00619 REAL value = atof(str.substr(prevPos, pos).c_str());
00620 coefs.SetLen(index + 2);
00621 coefs[index] = value;
00622
00623 prevPos = pos + 1;
00624 index ++;
00625 }
00626 while ( (pos = str.find(TPOLYNOMIAL_DELIMITER, prevPos)) != -1) ;
00627
00628 coefs[index] = atof(str.substr(prevPos, pos).c_str());
00629
00630 }
00631 else {
00632 coefs.SetLen(1);
00633 coefs[0] = atof(str.c_str());
00634 }
00635 }
00636
00637 template <typename T>
00638 std::string tPolynomial<T>::toString() const {
00639 std::ostringstream ostr("");
00640
00641 ostr << "base :" << referenceVarValue << " lenght:" << coefs.Len();
00642
00643 for (int i=0; i<coefs.Len(); i++) {
00644 ostr << " c[" << i << "]:" << coefs[i];
00645 }
00646 return ostr.str();
00647 }
00648
00649
00654 template <typename T>
00655 tPolynomial<T> const tPolynomial<T>::clamp(REAL minValue, REAL maxValue, REAL currentVarValue)
00656 {
00657 tPolynomial<T> tf(*this);
00658
00659 REAL valueAt = evaluate(currentVarValue);
00660 if (valueAt < minValue) {
00661 tf[0] = minValue;
00662 for (int i=1; i<coefs.Len(); i++) {
00663 if (tf[i] < 0) {
00664 tf[i] = 0.0;
00665 }
00666 }
00667 }
00668 if (maxValue < valueAt) {
00669 tf[0] = maxValue;
00670 for (int i=1; i<coefs.Len(); i++) {
00671 if (tf[i] > 0) {
00672 tf[i] = 0.0;
00673 }
00674 }
00675 }
00676
00677 return tf;
00678 }
00679
00683 template <typename T>
00684 void tPolynomial<T>::setAtSameReferenceVarValue(tPolynomial<T> const &other)
00685 {
00686 REAL a = other.referenceVarValue;
00687 referenceVarValue = a;
00688
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 #endif
00701