Wm4Polynomial1.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <class Real>
00021 Polynomial1<Real>::Polynomial1 (int iDegree)
00022 {
00023 if (iDegree >= 0)
00024 {
00025 m_iDegree = iDegree;
00026 m_afCoeff = WM4_NEW Real[m_iDegree+1];
00027 }
00028 else
00029 {
00030
00031 m_iDegree = -1;
00032 m_afCoeff = 0;
00033 }
00034 }
00035
00036 template <class Real>
00037 Polynomial1<Real>::Polynomial1 (const Polynomial1& rkPoly)
00038 {
00039 m_iDegree = rkPoly.m_iDegree;
00040 m_afCoeff = WM4_NEW Real[m_iDegree+1];
00041 for (int i = 0; i <= m_iDegree; i++)
00042 {
00043 m_afCoeff[i] = rkPoly.m_afCoeff[i];
00044 }
00045 }
00046
00047 template <class Real>
00048 Polynomial1<Real>::~Polynomial1 ()
00049 {
00050 WM4_DELETE[] m_afCoeff;
00051 }
00052
00053 template <class Real>
00054 void Polynomial1<Real>::SetDegree (int iDegree)
00055 {
00056 m_iDegree = iDegree;
00057 WM4_DELETE[] m_afCoeff;
00058
00059 if (m_iDegree >= 0)
00060 {
00061 m_afCoeff = WM4_NEW Real[m_iDegree+1];
00062 }
00063 else
00064 {
00065 m_afCoeff = 0;
00066 }
00067 }
00068
00069 template <class Real>
00070 int Polynomial1<Real>::GetDegree () const
00071 {
00072 return m_iDegree;
00073 }
00074
00075 template <class Real>
00076 Polynomial1<Real>::operator const Real* () const
00077 {
00078 return m_afCoeff;
00079 }
00080
00081 template <class Real>
00082 Polynomial1<Real>::operator Real* ()
00083 {
00084 return m_afCoeff;
00085 }
00086
00087 template <class Real>
00088 Real Polynomial1<Real>::operator[] (int i) const
00089 {
00090 assert(0 <= i && i <= m_iDegree);
00091 return m_afCoeff[i];
00092 }
00093
00094 template <class Real>
00095 Real& Polynomial1<Real>::operator[] (int i)
00096 {
00097 assert(0 <= i && i <= m_iDegree);
00098 return m_afCoeff[i];
00099 }
00100
00101 template <class Real>
00102 Polynomial1<Real>& Polynomial1<Real>::operator= (const Polynomial1& rkPoly)
00103 {
00104 WM4_DELETE[] m_afCoeff;
00105 m_iDegree = rkPoly.m_iDegree;
00106
00107 if (m_iDegree >= 0)
00108 {
00109 m_afCoeff = WM4_NEW Real[m_iDegree+1];
00110 for (int i = 0; i <= m_iDegree; i++)
00111 {
00112 m_afCoeff[i] = rkPoly.m_afCoeff[i];
00113 }
00114 }
00115
00116 return *this;
00117 }
00118
00119 template <class Real>
00120 Real Polynomial1<Real>::operator() (Real fT) const
00121 {
00122 assert(m_iDegree >= 0);
00123
00124 Real fResult = m_afCoeff[m_iDegree];
00125 for (int i = m_iDegree-1; i >= 0; i--)
00126 {
00127 fResult *= fT;
00128 fResult += m_afCoeff[i];
00129 }
00130 return fResult;
00131 }
00132
00133 template <class Real>
00134 Polynomial1<Real> Polynomial1<Real>::operator+ (const Polynomial1& rkPoly)
00135 const
00136 {
00137 assert(m_iDegree >= 0 && rkPoly.m_iDegree >= 0);
00138
00139 Polynomial1 kSum;
00140 int i;
00141
00142 if (m_iDegree > rkPoly.m_iDegree)
00143 {
00144 kSum.SetDegree(m_iDegree);
00145 for (i = 0; i <= rkPoly.m_iDegree; i++)
00146 {
00147 kSum.m_afCoeff[i] = m_afCoeff[i] + rkPoly.m_afCoeff[i];
00148 }
00149 for (i = rkPoly.m_iDegree+1; i <= m_iDegree; i++)
00150 {
00151 kSum.m_afCoeff[i] = m_afCoeff[i];
00152 }
00153
00154 }
00155 else
00156 {
00157 kSum.SetDegree(rkPoly.m_iDegree);
00158 for (i = 0; i <= m_iDegree; i++)
00159 {
00160 kSum.m_afCoeff[i] = m_afCoeff[i] + rkPoly.m_afCoeff[i];
00161 }
00162 for (i = m_iDegree+1; i <= rkPoly.m_iDegree; i++)
00163 {
00164 kSum.m_afCoeff[i] = rkPoly.m_afCoeff[i];
00165 }
00166 }
00167
00168 return kSum;
00169 }
00170
00171 template <class Real>
00172 Polynomial1<Real> Polynomial1<Real>::operator- (const Polynomial1& rkPoly)
00173 const
00174 {
00175 assert(m_iDegree >= 0 && rkPoly.m_iDegree >= 0);
00176
00177 Polynomial1 kDiff;
00178 int i;
00179
00180 if (m_iDegree > rkPoly.m_iDegree)
00181 {
00182 kDiff.SetDegree(m_iDegree);
00183 for (i = 0; i <= rkPoly.m_iDegree; i++)
00184 {
00185 kDiff.m_afCoeff[i] = m_afCoeff[i] - rkPoly.m_afCoeff[i];
00186 }
00187 for (i = rkPoly.m_iDegree+1; i <= m_iDegree; i++)
00188 {
00189 kDiff.m_afCoeff[i] = m_afCoeff[i];
00190 }
00191
00192 }
00193 else
00194 {
00195 kDiff.SetDegree(rkPoly.m_iDegree);
00196 for (i = 0; i <= m_iDegree; i++)
00197 {
00198 kDiff.m_afCoeff[i] = m_afCoeff[i] - rkPoly.m_afCoeff[i];
00199 }
00200 for (i = m_iDegree+1; i <= rkPoly.m_iDegree; i++)
00201 {
00202 kDiff.m_afCoeff[i] = -rkPoly.m_afCoeff[i];
00203 }
00204 }
00205
00206 return kDiff;
00207 }
00208
00209 template <class Real>
00210 Polynomial1<Real> Polynomial1<Real>::operator* (const Polynomial1& rkPoly)
00211 const
00212 {
00213 assert(m_iDegree >= 0 && rkPoly.m_iDegree >= 0);
00214
00215 Polynomial1 kProd(m_iDegree + rkPoly.m_iDegree);
00216
00217 memset(kProd.m_afCoeff,0,(kProd.m_iDegree+1)*sizeof(Real));
00218 for (int i0 = 0; i0 <= m_iDegree; i0++)
00219 {
00220 for (int i1 = 0; i1 <= rkPoly.m_iDegree; i1++)
00221 {
00222 int i2 = i0 + i1;
00223 kProd.m_afCoeff[i2] += m_afCoeff[i0]*rkPoly.m_afCoeff[i1];
00224 }
00225 }
00226
00227 return kProd;
00228 }
00229
00230 template <class Real>
00231 Polynomial1<Real> Polynomial1<Real>::operator+ (Real fScalar) const
00232 {
00233 assert(m_iDegree >= 0);
00234 Polynomial1 kSum(m_iDegree);
00235 kSum.m_afCoeff[0] += fScalar;
00236 return kSum;
00237 }
00238
00239 template <class Real>
00240 Polynomial1<Real> Polynomial1<Real>::operator- (Real fScalar) const
00241 {
00242 assert(m_iDegree >= 0);
00243 Polynomial1 kDiff(m_iDegree);
00244 kDiff.m_afCoeff[0] -= fScalar;
00245 return kDiff;
00246 }
00247
00248 template <class Real>
00249 Polynomial1<Real> Polynomial1<Real>::operator* (Real fScalar) const
00250 {
00251 assert(m_iDegree >= 0);
00252 Polynomial1 kProd(m_iDegree);
00253 for (int i = 0; i <= m_iDegree; i++)
00254 {
00255 kProd.m_afCoeff[i] = fScalar*m_afCoeff[i];
00256 }
00257 return kProd;
00258 }
00259
00260 template <class Real>
00261 Polynomial1<Real> Polynomial1<Real>::operator/ (Real fScalar) const
00262 {
00263 assert(m_iDegree >= 0);
00264 Polynomial1 kProd(m_iDegree);
00265 int i;
00266
00267 if (fScalar != (Real)0.0)
00268 {
00269 Real fInvScalar = ((Real)1.0)/fScalar;
00270 for (i = 0; i <= m_iDegree; i++)
00271 {
00272 kProd.m_afCoeff[i] = fInvScalar*m_afCoeff[i];
00273 }
00274 }
00275 else
00276 {
00277 for (i = 0; i <= m_iDegree; i++)
00278 {
00279 kProd.m_afCoeff[i] = Math<Real>::MAX_REAL;
00280 }
00281 }
00282
00283 return kProd;
00284 }
00285
00286 template <class Real>
00287 Polynomial1<Real> Polynomial1<Real>::operator- () const
00288 {
00289 assert(m_iDegree >= 0);
00290
00291 Polynomial1 kNeg(m_iDegree);
00292 for (int i = 0; i <= m_iDegree; i++)
00293 {
00294 kNeg.m_afCoeff[i] = -m_afCoeff[i];
00295 }
00296
00297 return kNeg;
00298 }
00299
00300 template <class Real>
00301 Polynomial1<Real> operator* (Real fScalar,
00302 const Polynomial1<Real>& rkPoly)
00303 {
00304 assert(rkPoly.GetDegree() >= 0);
00305
00306 Polynomial1<Real> kProd(rkPoly.GetDegree());
00307 for (int i = 0; i <= rkPoly.GetDegree(); i++)
00308 {
00309 kProd[i] = fScalar*rkPoly[i];
00310 }
00311
00312 return kProd;
00313 }
00314
00315 template <class Real>
00316 Polynomial1<Real>& Polynomial1<Real>::operator += (const Polynomial1& rkPoly)
00317 {
00318 assert(m_iDegree >= 0);
00319 *this = *this + rkPoly;
00320 return *this;
00321 }
00322
00323 template <class Real>
00324 Polynomial1<Real>& Polynomial1<Real>::operator -= (const Polynomial1& rkPoly)
00325 {
00326 assert(m_iDegree >= 0);
00327 *this = *this - rkPoly;
00328 return *this;
00329 }
00330
00331 template <class Real>
00332 Polynomial1<Real>& Polynomial1<Real>::operator *= (const Polynomial1& rkPoly)
00333 {
00334 assert(m_iDegree >= 0);
00335 *this = (*this)*rkPoly;
00336 return *this;
00337 }
00338
00339 template <class Real>
00340 Polynomial1<Real>& Polynomial1<Real>::operator += (Real fScalar)
00341 {
00342 assert(m_iDegree >= 0);
00343 m_afCoeff[0] += fScalar;
00344 return *this;
00345 }
00346
00347 template <class Real>
00348 Polynomial1<Real>& Polynomial1<Real>::operator -= (Real fScalar)
00349 {
00350 assert(m_iDegree >= 0);
00351 m_afCoeff[0] -= fScalar;
00352 return *this;
00353 }
00354
00355 template <class Real>
00356 Polynomial1<Real>& Polynomial1<Real>::operator *= (Real fScalar)
00357 {
00358 assert(m_iDegree >= 0);
00359 *this = (*this)*fScalar;
00360 return *this;
00361 }
00362
00363 template <class Real>
00364 Polynomial1<Real>& Polynomial1<Real>::operator /= (Real fScalar)
00365 {
00366 assert(m_iDegree >= 0);
00367 *this = (*this)/fScalar;
00368 return *this;
00369 }
00370
00371 template <class Real>
00372 Polynomial1<Real> Polynomial1<Real>::GetDerivative () const
00373 {
00374 if (m_iDegree > 0)
00375 {
00376 Polynomial1 kDeriv(m_iDegree-1);
00377 for (int i0 = 0, i1 = 1; i0 < m_iDegree; i0++, i1++)
00378 {
00379 kDeriv.m_afCoeff[i0] = i1*m_afCoeff[i1];
00380 }
00381 return kDeriv;
00382 }
00383 else if (m_iDegree == 0)
00384 {
00385 Polynomial1 kConst(0);
00386 kConst.m_afCoeff[0] = (Real)0.0;
00387 return kConst;
00388 }
00389 return Polynomial1<Real>();
00390 }
00391
00392 template <class Real>
00393 Polynomial1<Real> Polynomial1<Real>::GetInversion () const
00394 {
00395 Polynomial1 kInvPoly(m_iDegree);
00396 for (int i = 0; i <= m_iDegree; i++)
00397 {
00398 kInvPoly.m_afCoeff[i] = m_afCoeff[m_iDegree-i];
00399 }
00400 return kInvPoly;
00401 }
00402
00403 template <class Real>
00404 void Polynomial1<Real>::Compress (Real fEpsilon)
00405 {
00406 int i;
00407 for (i = m_iDegree; i >= 0; i--)
00408 {
00409 if (Math<Real>::FAbs(m_afCoeff[i]) <= fEpsilon)
00410 {
00411 m_iDegree--;
00412 }
00413 else
00414 {
00415 break;
00416 }
00417 }
00418
00419 if (m_iDegree >= 0)
00420 {
00421 Real fInvLeading = ((Real)1.0)/m_afCoeff[m_iDegree];
00422 m_afCoeff[m_iDegree] = (Real)1.0;
00423 for (i = 0; i < m_iDegree; i++)
00424 {
00425 m_afCoeff[i] *= fInvLeading;
00426 }
00427 }
00428 }
00429
00430 template <class Real>
00431 void Polynomial1<Real>::Divide (const Polynomial1& rkDiv, Polynomial1& rkQuot,
00432 Polynomial1& rkRem, Real fEpsilon) const
00433 {
00434 int iQuotDegree = m_iDegree - rkDiv.m_iDegree;
00435 if (iQuotDegree >= 0)
00436 {
00437 rkQuot.SetDegree(iQuotDegree);
00438
00439
00440 Polynomial1 kTmp = *this;
00441
00442
00443 Real fInv = ((Real)1.0)/rkDiv[rkDiv.m_iDegree];
00444 for (int iQ = iQuotDegree; iQ >= 0; iQ--)
00445 {
00446 int iR = rkDiv.m_iDegree + iQ;
00447 rkQuot[iQ] = fInv*kTmp[iR];
00448 for (iR--; iR >= iQ; iR--)
00449 {
00450 kTmp[iR] -= rkQuot[iQ]*rkDiv[iR-iQ];
00451 }
00452 }
00453
00454
00455 int iRemDeg = rkDiv.m_iDegree - 1;
00456 while (iRemDeg > 0 && Math<Real>::FAbs(kTmp[iRemDeg]) < fEpsilon)
00457 {
00458 iRemDeg--;
00459 }
00460
00461 if (iRemDeg == 0 && Math<Real>::FAbs(kTmp[0]) < fEpsilon)
00462 {
00463 kTmp[0] = (Real)0.0;
00464 }
00465
00466 rkRem.SetDegree(iRemDeg);
00467 size_t uiSize = (iRemDeg+1)*sizeof(Real);
00468 System::Memcpy(rkRem.m_afCoeff,uiSize,kTmp.m_afCoeff,uiSize);
00469 }
00470 else
00471 {
00472 rkQuot.SetDegree(0);
00473 rkQuot[0] = (Real)0.0;
00474 rkRem = *this;
00475 }
00476 }
00477
00478 }