GtePolynomial1.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <LowLevel/GteLogger.h>
11 #include <algorithm>
12 #include <initializer_list>
13 #include <vector>
14 
15 namespace gte
16 {
17 
18 template <typename Real>
20 {
21 public:
22  // Construction and destruction. The first constructor creates a
23  // polynomial of degree 0. The first and second constructors do not
24  // initialize their coefficients. In the third constructor, the degree
25  // is the number of initializers plus 1, but then adjusted to ensure
26  // coefficient[degree] is not zero.
27  Polynomial1();
28  Polynomial1(unsigned int degree);
29  Polynomial1(std::initializer_list<Real> values);
30 
31  // Support for partial construction, where the default constructor is used
32  // when the degree is not yet known. The coefficients are uninitialized.
33  void SetDegree(unsigned int degree);
34 
35  // Set all coefficients to the specified value.
36  void SetCoefficients(Real value);
37 
38  // Member access.
39  inline unsigned int GetDegree() const;
40  inline Real const& operator[](unsigned int i) const;
41  inline Real& operator[](unsigned int i);
42 
43  // Comparisons.
44  inline bool operator==(Polynomial1<Real> const& p) const;
45  inline bool operator!=(Polynomial1<Real> const& p) const;
46  inline bool operator< (Polynomial1<Real> const& p) const;
47  inline bool operator<=(Polynomial1<Real> const& p) const;
48  inline bool operator> (Polynomial1<Real> const& p) const;
49  inline bool operator>=(Polynomial1<Real> const& p) const;
50 
51  // Evaluate the polynomial. If the polynomial is invalid, the function
52  // returns zero.
53  Real operator()(Real t) const;
54 
55  // Compute the derivative of the polynomial.
56  Polynomial1 GetDerivative() const;
57 
58  // Inversion (invpoly[i] = poly[degree-i] for 0 <= i <= degree).
59  Polynomial1 GetInversion() const;
60 
61  // Eliminate any leading zeros in the polynomial, except in the case the
62  // degree is 0 and the coefficient is 0. The elimination is necessary
63  // when arithmetic operations cause a decrease in the degree of the
64  // result. For example, (1 + x + x^2) + (1 + 2*x - x^2) = (2 + 3*x). The
65  // inputs both have degree 2, so the result is created with degree 2.
66  // After the addition we find that the degree is in fact 1 and resize the
67  // array of coefficients. This function is called internally by the
68  // arithmetic operators, but it is exposed in the public interface in case
69  // you need it for your own purposes.
70  void EliminateLeadingZeros();
71 
72  // If 'this' is P(t) and the divisor is D(t) with degree(P) >= degree(D),
73  // then P(t) = Q(t)*D(t)+R(t) where Q(t) is the quotient with
74  // degree(Q) = degree(P) - degree(D) and R(t) is the remainder with
75  // degree(R) < degree(D). If this routine is called with
76  // degree(P) < degree(D), then Q = 0 and R = P are returned.
77  void Divide(Polynomial1 const& divisor, Polynomial1& quotient,
78  Polynomial1& remainder) const;
79 
80 protected:
81  // The class is designed so that mCoefficient.size() >= 1.
82  std::vector<Real> mCoefficient;
83 };
84 
85 // Unary operations.
86 template <typename Real>
88 
89 template <typename Real>
91 
92 // Linear-algebraic operations.
93 template <typename Real>
95 operator+(Polynomial1<Real> const& p0, Polynomial1<Real> const& p1);
96 
97 template <typename Real>
99 operator-(Polynomial1<Real> const& p0, Polynomial1<Real> const& p1);
100 
101 template <typename Real>
103 operator*(Polynomial1<Real> const& p0, Polynomial1<Real> const& p1);
104 
105 template <typename Real>
106 Polynomial1<Real> operator+(Polynomial1<Real> const& p, Real scalar);
107 
108 template <typename Real>
109 Polynomial1<Real> operator+(Real scalar, Polynomial1<Real> const& p);
110 
111 template <typename Real>
112 Polynomial1<Real> operator-(Polynomial1<Real> const& p, Real scalar);
113 
114 template <typename Real>
115 Polynomial1<Real> operator-(Real scalar, Polynomial1<Real> const& p);
116 
117 template <typename Real>
118 Polynomial1<Real> operator*(Polynomial1<Real> const& p, Real scalar);
119 
120 template <typename Real>
121 Polynomial1<Real> operator*(Real scalar, Polynomial1<Real> const& p);
122 
123 template <typename Real>
124 Polynomial1<Real> operator/(Polynomial1<Real> const& p, Real scalar);
125 
126 template <typename Real>
129 
130 template <typename Real>
133 
134 template <typename Real>
137 
138 template <typename Real>
140 
141 template <typename Real>
143 
144 template <typename Real>
146 
147 template <typename Real>
149 
150 
151 template <typename Real>
153  :
154  mCoefficient(1)
155 {
156  // uninitialized
157 }
158 
159 template <typename Real>
160 Polynomial1<Real>::Polynomial1(unsigned int degree)
161  :
162  mCoefficient(degree + 1)
163 {
164  // uninitialized
165 }
166 
167 template <typename Real>
168 Polynomial1<Real>::Polynomial1(std::initializer_list<Real> values)
169 {
170  // C++ 11 will call the default constructor for Polynomial1<Real> p{},
171  // so it is guaranteed that values.size() > 0.
172  mCoefficient.resize(values.size());
173  std::copy(values.begin(), values.end(), mCoefficient.begin());
175 }
176 
177 template <typename Real>
178 void Polynomial1<Real>::SetDegree(unsigned int degree)
179 {
180  mCoefficient.resize(degree + 1);
181 }
182 
183 template <typename Real>
185 {
186  std::fill(mCoefficient.begin(), mCoefficient.end(), value);
187 }
188 
189 template <typename Real> inline
190 unsigned int Polynomial1<Real>::GetDegree() const
191 {
192  // By design, mCoefficient.size() > 0.
193  return static_cast<unsigned int>(mCoefficient.size() - 1);
194 }
195 
196 template <typename Real> inline
197 Real const& Polynomial1<Real>::operator[](unsigned int i) const
198 {
199  return mCoefficient[i];
200 }
201 
202 template <typename Real> inline
203 Real& Polynomial1<Real>::operator[](unsigned int i)
204 {
205  return mCoefficient[i];
206 }
207 
208 template <typename Real> inline
210 {
211  return mCoefficient == p.mCoefficient;
212 }
213 
214 template <typename Real> inline
216 {
217  return mCoefficient != p.mCoefficient;
218 }
219 
220 template <typename Real> inline
222 {
223  return mCoefficient < p.mCoefficient;
224 }
225 
226 template <typename Real> inline
228 {
229  return mCoefficient <= p.mCoefficient;
230 }
231 
232 template <typename Real> inline
234 {
235  return mCoefficient > p.mCoefficient;
236 }
237 
238 template <typename Real> inline
240 {
241  return mCoefficient >= p.mCoefficient;
242 }
243 
244 template <typename Real>
246 {
247  int i = static_cast<int>(mCoefficient.size());
248  Real result = mCoefficient[--i];
249  for (--i; i >= 0; --i)
250  {
251  result *= t;
252  result += mCoefficient[i];
253  }
254  return result;
255 }
256 
257 template <typename Real>
259 {
260  unsigned int const degree = GetDegree();
261  if (degree > 0)
262  {
263  Polynomial1 result(degree - 1);
264  for (unsigned int i0 = 0, i1 = 1; i0 < degree; ++i0, ++i1)
265  {
266  result.mCoefficient[i0] = mCoefficient[i1] * (Real)i1;
267  }
268  return result;
269  }
270  else
271  {
272  Polynomial1 result(0);
273  result[0] = (Real)0;
274  return result;
275  }
276 }
277 
278 template <typename Real>
280 {
281  unsigned int const degree = GetDegree();
282  Polynomial1 result(degree);
283  for (unsigned int i = 0; i <= degree; ++i)
284  {
285  result.mCoefficient[i] = mCoefficient[degree - i];
286  }
287  return result;
288 }
289 
290 template <typename Real>
292 {
293  size_t size = mCoefficient.size();
294  if (size > 1)
295  {
296  Real const zero = (Real)0;
297  int leading;
298  for (leading = static_cast<int>(size) - 1; leading > 0; --leading)
299  {
300  if (mCoefficient[leading] != zero)
301  {
302  break;
303  }
304  }
305 
306  mCoefficient.resize(++leading);
307  }
308 }
309 
310 template <typename Real>
312  Polynomial1& quotient, Polynomial1& remainder) const
313 {
314  Real const zero = (Real)0;
315  int divisorDegree = static_cast<int>(divisor.GetDegree());
316  int quotientDegree = static_cast<int>(GetDegree()) - divisorDegree;
317  if (quotientDegree >= 0)
318  {
319  quotient.SetDegree(quotientDegree);
320 
321  // Temporary storage for the remainder.
322  Polynomial1 tmp = *this;
323 
324  // Do the division using the Euclidean algorithm.
325  Real inv = ((Real)1) / divisor[divisorDegree];
326  for (int i = quotientDegree; i >= 0; --i)
327  {
328  int j = divisorDegree + i;
329  quotient[i] = inv*tmp[j];
330  for (j--; j >= i; j--)
331  {
332  tmp[j] -= quotient[i] * divisor[j - i];
333  }
334  }
335 
336  // Calculate the correct degree for the remainder.
337  int remainderDegree = divisorDegree - 1;
338  while (remainderDegree > 0 && tmp[remainderDegree] == zero)
339  {
340  --remainderDegree;
341  }
342 
343  remainder.SetDegree(remainderDegree);
344  for (int i = 0; i <= remainderDegree; ++i)
345  {
346  remainder[i] = tmp[i];
347  }
348  }
349  else
350  {
351  quotient.SetDegree(0);
352  quotient[0] = zero;
353  remainder = *this;
354  }
355 }
356 
357 
358 
359 template <typename Real>
361 {
362  return p;
363 }
364 
365 template <typename Real>
367 {
368  unsigned int const degree = p.GetDegree();
369  Polynomial1<Real> result(degree);
370  for (unsigned int i = 0; i <= degree; ++i)
371  {
372  result[i] = -p[i];
373  }
374  return result;
375 }
376 
377 template <typename Real>
379  Polynomial1<Real> const& p1)
380 {
381  unsigned int const p0Degree = p0.GetDegree(), p1Degree = p1.GetDegree();
382  unsigned int i;
383  if (p0Degree >= p1Degree)
384  {
385  Polynomial1<Real> result(p0Degree);
386  for (i = 0; i <= p1Degree; ++i)
387  {
388  result[i] = p0[i] + p1[i];
389  }
390  for (; i <= p0Degree; ++i)
391  {
392  result[i] = p0[i];
393  }
394  result.EliminateLeadingZeros();
395  return result;
396  }
397  else
398  {
399  Polynomial1<Real> result(p1Degree);
400  for (i = 0; i <= p0Degree; ++i)
401  {
402  result[i] = p0[i] + p1[i];
403  }
404  for (; i <= p1Degree; ++i)
405  {
406  result[i] = p1[i];
407  }
408  result.EliminateLeadingZeros();
409  return result;
410  }
411 }
412 
413 template <typename Real>
415  Polynomial1<Real> const& p1)
416 {
417  unsigned int const p0Degree = p0.GetDegree(), p1Degree = p1.GetDegree();
418  unsigned int i;
419  if (p0Degree >= p1Degree)
420  {
421  Polynomial1<Real> result(p0Degree);
422  for (i = 0; i <= p1Degree; ++i)
423  {
424  result[i] = p0[i] - p1[i];
425  }
426  for (; i <= p0Degree; ++i)
427  {
428  result[i] = p0[i];
429  }
430  result.EliminateLeadingZeros();
431  return result;
432  }
433  else
434  {
435  Polynomial1<Real> result(p1Degree);
436  for (i = 0; i <= p0Degree; ++i)
437  {
438  result[i] = p0[i] - p1[i];
439  }
440  for (; i <= p1Degree; ++i)
441  {
442  result[i] = -p1[i];
443  }
444  result.EliminateLeadingZeros();
445  return result;
446  }
447 }
448 
449 template <typename Real>
451  Polynomial1<Real> const& p1)
452 {
453  unsigned int const p0Degree = p0.GetDegree(), p1Degree = p1.GetDegree();
454  Polynomial1<Real> result(p0Degree + p1Degree);
455  result.SetCoefficients((Real)0);
456  for (unsigned int i0 = 0; i0 <= p0Degree; ++i0)
457  {
458  for (unsigned int i1 = 0; i1 <= p1Degree; ++i1)
459  {
460  result[i0 + i1] += p0[i0] * p1[i1];
461  }
462  }
463  return result;
464 }
465 
466 template <typename Real>
468 {
469  unsigned int const degree = p.GetDegree();
470  Polynomial1<Real> result(degree);
471  result[0] = p[0] + scalar;
472  for (unsigned int i = 1; i <= degree; ++i)
473  {
474  result[i] = p[i];
475  }
476  return result;
477 }
478 
479 template <typename Real>
481 {
482  unsigned int const degree = p.GetDegree();
483  Polynomial1<Real> result(degree);
484  result[0] = p[0] + scalar;
485  for (unsigned int i = 1; i <= degree; ++i)
486  {
487  result[i] = p[i];
488  }
489  return result;
490 }
491 
492 template <typename Real>
494 {
495  unsigned int const degree = p.GetDegree();
496  Polynomial1<Real> result(degree);
497  result[0] = p[0] - scalar;
498  for (unsigned int i = 1; i <= degree; ++i)
499  {
500  result[i] = p[i];
501  }
502  return result;
503 }
504 
505 template <typename Real>
507 {
508  unsigned int const degree = p.GetDegree();
509  Polynomial1<Real> result(degree);
510  result[0] = scalar - p[0];
511  for (unsigned int i = 1; i <= degree; ++i)
512  {
513  result[i] = -p[i];
514  }
515  return result;
516 }
517 
518 template <typename Real>
520 {
521  unsigned int const degree = p.GetDegree();
522  Polynomial1<Real> result(degree);
523  for (unsigned int i = 0; i <= degree; ++i)
524  {
525  result[i] = scalar * p[i];
526  }
527  return result;
528 }
529 
530 template <typename Real>
532 {
533  unsigned int const degree = p.GetDegree();
534  Polynomial1<Real> result(degree);
535  for (unsigned int i = 0; i <= degree; ++i)
536  {
537  result[i] = scalar * p[i];
538  }
539  return result;
540 }
541 
542 template <typename Real>
544 {
545  if (scalar == (Real)0)
546  {
547  LogWarning("Division by zero in operator/(p,scalar).");
548  }
549 
550  unsigned int const degree = p.GetDegree();
551  Real invScalar = ((Real)1) / scalar;
552  Polynomial1<Real> result(degree);
553  for (unsigned int i = 0; i <= degree; ++i)
554  {
555  result[i] = invScalar * p[i];
556  }
557  return result;
558 }
559 
560 template <typename Real>
562  Polynomial1<Real> const& p1)
563 {
564  p0 = p0 + p1;
565  return p0;
566 }
567 
568 template <typename Real>
570  Polynomial1<Real> const& p1)
571 {
572  p0 = p0 - p1;
573  return p0;
574 }
575 
576 template <typename Real>
578  Polynomial1<Real> const& p1)
579 {
580  p0 = p0 * p1;
581  return p0;
582 }
583 
584 template <typename Real>
586 {
587  p[0] += scalar;
588  return p;
589 }
590 
591 template <typename Real>
593 {
594  p[0] -= scalar;
595  return p;
596 }
597 
598 template <typename Real>
600 {
601  p = p * scalar;
602  return p;
603 }
604 
605 template <typename Real>
607 {
608  p = p / scalar;
609  return p;
610 }
611 
612 
613 }
Real const & operator[](unsigned int i) const
INT64 INT64 INT64 remainder
Definition: wglext.h:822
unsigned int GetDegree() const
void SetDegree(unsigned int degree)
Polynomial1 GetDerivative() const
DualQuaternion< Real > & operator*=(DualQuaternion< Real > &d, Real scalar)
bool operator<=(Polynomial1< Real > const &p) const
void SetCoefficients(Real value)
GLsizei const GLfloat * value
Definition: glcorearb.h:819
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
void Divide(Polynomial1 const &divisor, Polynomial1 &quotient, Polynomial1 &remainder) const
GLsizeiptr size
Definition: glcorearb.h:659
std::vector< Real > mCoefficient
DualQuaternion< Real > operator+(DualQuaternion< Real > const &d)
DualQuaternion< Real > & operator-=(DualQuaternion< Real > &d0, DualQuaternion< Real > const &d1)
bool operator<(Polynomial1< Real > const &p) const
#define LogWarning(message)
Definition: GteLogger.h:95
GLdouble GLdouble t
Definition: glext.h:239
Real operator()(Real t) const
bool operator!=(Polynomial1< Real > const &p) const
void EliminateLeadingZeros()
GLuint divisor
Definition: glcorearb.h:1665
Polynomial1 GetInversion() const
DualQuaternion< Real > operator-(DualQuaternion< Real > const &d)
bool operator>(Polynomial1< Real > const &p) const
bool operator==(Polynomial1< Real > const &p) const
DualQuaternion< Real > & operator+=(DualQuaternion< Real > &d0, DualQuaternion< Real > const &d1)
DualQuaternion< Real > & operator/=(DualQuaternion< Real > &d, Real scalar)
bool operator>=(Polynomial1< Real > const &p) const
GLfloat GLfloat p
Definition: glext.h:11668
Vector4< float > operator*(Transform const &M, Vector4< float > const &V)
GLuint64EXT * result
Definition: glext.h:10003
DualQuaternion< Real > operator/(DualQuaternion< Real > const &d, Real scalar)


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01