libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moMathPolynomial.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moMathPolynomial.cpp
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright(C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28  Andrés Colubri
29 
30  Portions taken from
31  Wild Magic Source Code
32  David Eberly
33  http://www.geometrictools.com
34  Copyright (c) 1998-2007
35 
36 *******************************************************************************/
37 
38 #include "moMathPolynomial.h"
39 
40 template <class Real>
42 {
43  if (iDegree >= 0)
44  {
45  m_iDegree = iDegree;
46  m_afCoeff = new Real[m_iDegree+1];
47  }
48  else
49  {
50  // default creation
51  m_iDegree = -1;
52  m_afCoeff = 0;
53  }
54 }
55 
56 template <class Real>
58 {
59  m_iDegree = rkPoly.m_iDegree;
60  m_afCoeff = new Real[m_iDegree+1];
61  for (int i = 0; i <= m_iDegree; i++)
62  {
63  m_afCoeff[i] = rkPoly.m_afCoeff[i];
64  }
65 }
66 
67 template <class Real>
69 {
70  delete[] m_afCoeff;
71 }
72 
73 template <class Real>
75 {
76  m_iDegree = iDegree;
77  delete[] m_afCoeff;
78 
79  if (m_iDegree >= 0)
80  {
81  m_afCoeff = new Real[m_iDegree+1];
82  }
83  else
84  {
85  m_afCoeff = 0;
86  }
87 }
88 
89 template <class Real>
91 {
92  return m_iDegree;
93 }
94 
95 template <class Real>
96 moPolynomial1<Real>::operator const Real* () const
97 {
98  return m_afCoeff;
99 }
100 
101 template <class Real>
103 {
104  return m_afCoeff;
105 }
106 
107 template <class Real>
109 {
110  return m_afCoeff[i];
111 }
112 
113 template <class Real>
115 {
116  return m_afCoeff[i];
117 }
118 
119 template <class Real>
121 {
122  delete[] m_afCoeff;
123  m_iDegree = rkPoly.m_iDegree;
124 
125  if (m_iDegree >= 0)
126  {
127  m_afCoeff = new Real[m_iDegree+1];
128  for (int i = 0; i <= m_iDegree; i++)
129  {
130  m_afCoeff[i] = rkPoly.m_afCoeff[i];
131  }
132  }
133 
134  return *this;
135 }
136 
137 template <class Real>
139 {
140  if (m_iDegree < 0) return 0;
141 
142  Real fResult = m_afCoeff[m_iDegree];
143  for (int i = m_iDegree-1; i >= 0; i--)
144  {
145  fResult *= fT;
146  fResult += m_afCoeff[i];
147  }
148  return fResult;
149 }
150 
151 template <class Real>
153  const
154 {
155  moPolynomial1 kSum;
156  int i;
157 
158  if (m_iDegree > rkPoly.m_iDegree)
159  {
160  kSum.SetDegree(m_iDegree);
161  for (i = 0; i <= rkPoly.m_iDegree; i++)
162  {
163  kSum.m_afCoeff[i] = m_afCoeff[i] + rkPoly.m_afCoeff[i];
164  }
165  for (i = rkPoly.m_iDegree+1; i <= m_iDegree; i++)
166  {
167  kSum.m_afCoeff[i] = m_afCoeff[i];
168  }
169 
170  }
171  else
172  {
173  kSum.SetDegree(rkPoly.m_iDegree);
174  for (i = 0; i <= m_iDegree; i++)
175  {
176  kSum.m_afCoeff[i] = m_afCoeff[i] + rkPoly.m_afCoeff[i];
177  }
178  for (i = m_iDegree+1; i <= rkPoly.m_iDegree; i++)
179  {
180  kSum.m_afCoeff[i] = rkPoly.m_afCoeff[i];
181  }
182  }
183 
184  return kSum;
185 }
186 
187 template <class Real>
189  const
190 {
191  moPolynomial1 kDiff;
192  int i;
193 
194  if (m_iDegree > rkPoly.m_iDegree)
195  {
196  kDiff.SetDegree(m_iDegree);
197  for (i = 0; i <= rkPoly.m_iDegree; i++)
198  {
199  kDiff.m_afCoeff[i] = m_afCoeff[i] - rkPoly.m_afCoeff[i];
200  }
201  for (i = rkPoly.m_iDegree+1; i <= m_iDegree; i++)
202  {
203  kDiff.m_afCoeff[i] = m_afCoeff[i];
204  }
205 
206  }
207  else
208  {
209  kDiff.SetDegree(rkPoly.m_iDegree);
210  for (i = 0; i <= m_iDegree; i++)
211  {
212  kDiff.m_afCoeff[i] = m_afCoeff[i] - rkPoly.m_afCoeff[i];
213  }
214  for (i = m_iDegree+1; i <= rkPoly.m_iDegree; i++)
215  {
216  kDiff.m_afCoeff[i] = -rkPoly.m_afCoeff[i];
217  }
218  }
219 
220  return kDiff;
221 }
222 
223 template <class Real>
225  const
226 {
227  moPolynomial1 kProd(m_iDegree + rkPoly.m_iDegree);
228 
229  memset(kProd.m_afCoeff,0,(kProd.m_iDegree+1)*sizeof(Real));
230  for (int i0 = 0; i0 <= m_iDegree; i0++)
231  {
232  for (int i1 = 0; i1 <= rkPoly.m_iDegree; i1++)
233  {
234  int i2 = i0 + i1;
235  kProd.m_afCoeff[i2] += m_afCoeff[i0]*rkPoly.m_afCoeff[i1];
236  }
237  }
238 
239  return kProd;
240 }
241 
242 template <class Real>
244 {
245  moPolynomial1 kSum(m_iDegree);
246  kSum.m_afCoeff[0] += fScalar;
247  return kSum;
248 }
249 
250 template <class Real>
252 {
253  moPolynomial1 kDiff(m_iDegree);
254  kDiff.m_afCoeff[0] -= fScalar;
255  return kDiff;
256 }
257 
258 template <class Real>
260 {
261  moPolynomial1 kProd(m_iDegree);
262  for (int i = 0; i <= m_iDegree; i++)
263  {
264  kProd.m_afCoeff[i] = fScalar*m_afCoeff[i];
265  }
266  return kProd;
267 }
268 
269 template <class Real>
271 {
272  moPolynomial1 kProd(m_iDegree);
273  int i;
274 
275  if (fScalar != (Real)0.0)
276  {
277  Real fInvScalar = ((Real)1.0)/fScalar;
278  for (i = 0; i <= m_iDegree; i++)
279  {
280  kProd.m_afCoeff[i] = fInvScalar*m_afCoeff[i];
281  }
282  }
283  else
284  {
285  for (i = 0; i <= m_iDegree; i++)
286  {
288  }
289  }
290 
291  return kProd;
292 }
293 
294 template <class Real>
296 {
297  moPolynomial1 kNeg(m_iDegree);
298  for (int i = 0; i <= m_iDegree; i++)
299  {
300  kNeg.m_afCoeff[i] = -m_afCoeff[i];
301  }
302 
303  return kNeg;
304 }
305 
306 template <class Real>
308 {
309  *this = *this + rkPoly;
310  return *this;
311 }
312 
313 template <class Real>
315 {
316  *this = *this - rkPoly;
317  return *this;
318 }
319 
320 template <class Real>
322 {
323  *this = (*this)*rkPoly;
324  return *this;
325 }
326 
327 template <class Real>
329 {
330  m_afCoeff[0] += fScalar;
331  return *this;
332 }
333 
334 template <class Real>
336 {
337  m_afCoeff[0] -= fScalar;
338  return *this;
339 }
340 
341 template <class Real>
343 {
344  *this = (*this)*fScalar;
345  return *this;
346 }
347 
348 template <class Real>
350 {
351  *this = (*this)/fScalar;
352  return *this;
353 }
354 
355 template <class Real>
357 {
358  if (m_iDegree > 0)
359  {
360  moPolynomial1 kDeriv(m_iDegree-1);
361  for (int i0 = 0, i1 = 1; i0 < m_iDegree; i0++, i1++)
362  {
363  kDeriv.m_afCoeff[i0] = i1*m_afCoeff[i1];
364  }
365  return kDeriv;
366  }
367  else if (m_iDegree == 0)
368  {
369  moPolynomial1 kConst(0);
370  kConst.m_afCoeff[0] = (Real)0.0;
371  return kConst;
372  }
373  return moPolynomial1<Real>(); // invalid in, invalid out
374 }
375 
376 template <class Real>
378 {
379  moPolynomial1 kInvPoly(m_iDegree);
380  for (int i = 0; i <= m_iDegree; i++)
381  {
382  kInvPoly.m_afCoeff[i] = m_afCoeff[m_iDegree-i];
383  }
384  return kInvPoly;
385 }
386 
387 template <class Real>
388 void moPolynomial1<Real>::Compress (Real fEpsilon)
389 {
390  int i;
391  for (i = m_iDegree; i >= 0; i--)
392  {
393  if (moMath<Real>::FAbs(m_afCoeff[i]) <= fEpsilon)
394  {
395  m_iDegree--;
396  }
397  else
398  {
399  break;
400  }
401  }
402 
403  if (m_iDegree >= 0)
404  {
405  Real fInvLeading = ((Real)1.0)/m_afCoeff[m_iDegree];
406  m_afCoeff[m_iDegree] = (Real)1.0;
407  for (i = 0; i < m_iDegree; i++)
408  {
409  m_afCoeff[i] *= fInvLeading;
410  }
411  }
412 }
413 
414 template <class Real>
416  moPolynomial1& rkRem, Real fEpsilon) const
417 {
418  int iQuotDegree = m_iDegree - rkDiv.m_iDegree;
419  if (iQuotDegree >= 0)
420  {
421  rkQuot.SetDegree(iQuotDegree);
422 
423  // temporary storage for the remainder
424  moPolynomial1 kTmp = *this;
425 
426  // do the division (Euclidean algorithm)
427  Real fInv = ((Real)1.0)/rkDiv[rkDiv.m_iDegree];
428  for (int iQ = iQuotDegree; iQ >= 0; iQ--)
429  {
430  int iR = rkDiv.m_iDegree + iQ;
431  rkQuot[iQ] = fInv*kTmp[iR];
432  for (iR--; iR >= iQ; iR--)
433  {
434  kTmp[iR] -= rkQuot[iQ]*rkDiv[iR-iQ];
435  }
436  }
437 
438  // calculate the correct degree for the remainder
439  int iRemDeg = rkDiv.m_iDegree - 1;
440  while (iRemDeg > 0 && moMath<Real>::FAbs(kTmp[iRemDeg]) < fEpsilon)
441  {
442  iRemDeg--;
443  }
444 
445  if (iRemDeg == 0 && moMath<Real>::FAbs(kTmp[0]) < fEpsilon)
446  {
447  kTmp[0] = (Real)0.0;
448  }
449 
450  rkRem.SetDegree(iRemDeg);
451  size_t uiSize = (iRemDeg+1)*sizeof(Real);
452  memcpy(rkRem.m_afCoeff,kTmp.m_afCoeff,uiSize);
453  }
454  else
455  {
456  rkQuot.SetDegree(0);
457  rkQuot[0] = (Real)0.0;
458  rkRem = *this;
459  }
460 }
461 
moPolynomial1 operator*(const moPolynomial1 &rkPoly) const
moPolynomial1 & operator*=(const moPolynomial1 &rkPoly)
moPolynomial1 operator+(const moPolynomial1 &rkPoly) const
moPolynomial1(int iDegree=-1)
moPolynomial1 & operator=(const moPolynomial1 &rkPoly)
Real operator[](int i) const
moPolynomial1 & operator/=(Real fScalar)
void SetDegree(int iDegree)
void Divide(const moPolynomial1 &rkDiv, moPolynomial1 &rkQuot, moPolynomial1 &rkRem, Real fEpsilon) const
moPolynomial1 & operator-=(const moPolynomial1 &rkPoly)
Clase base abstracta de donde deben derivar los objetos [virtual pura].
Definition: moAbstract.h:191
void Compress(Real fEpsilon)
int GetDegree() const
moPolynomial1 operator/(Real fScalar) const
Real operator()(Real fT) const
moPolynomial1 operator-() const
moPolynomial1 GetDerivative() const
Definition: moMath.h:64
moPolynomial1 & operator+=(const moPolynomial1 &rkPoly)
moPolynomial1 GetInversion() const