libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo es el conjunto de objetos y funciones, que permiten ejecutar las operaciones básicas de la plataforma Moldeo, y que compone su núcleo.
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Amigas 'defines' Grupos Páginas
moMathPolynomial.cpp
Ir a la documentación de este archivo.
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
moTypes MOint moText moParamIndex moParamReference int iRow int int i int i
Definition: all_f.js:18
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