Wm4Polynomial1.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
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         // default creation
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>();  // invalid in, invalid out
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         // temporary storage for the remainder
00440         Polynomial1 kTmp = *this;
00441 
00442         // do the division (Euclidean algorithm)
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         // calculate the correct degree for the remainder
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 } //namespace Wm4

Generated on Wed Nov 23 19:01:06 2011 for FreeCAD by  doxygen 1.6.1