CUGL
Cornell University Game Library
CUPolynomial.h
1 //
2 // CUPolynomial.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides a class that represents a polynomial. It has basic
6 // methods for evaluation and root finding. The primary purpose of this class
7 // is to support CubicSpline and other beziers. However, we provide it publicly
8 // in case it is useful for other applications.
9 //
10 // Because math objects are intended to be on the stack, we do not provide
11 // any shared pointer support in this class.
12 //
13 // CUGL zlib License:
14 // This software is provided 'as-is', without any express or implied
15 // warranty. In no event will the authors be held liable for any damages
16 // arising from the use of this software.
17 //
18 // Permission is granted to anyone to use this software for any purpose,
19 // including commercial applications, and to alter it and redistribute it
20 // freely, subject to the following restrictions:
21 //
22 // 1. The origin of this software must not be misrepresented; you must not
23 // claim that you wrote the original software. If you use this software
24 // in a product, an acknowledgment in the product documentation would be
25 // appreciated but is not required.
26 //
27 // 2. Altered source versions must be plainly marked as such, and must not
28 // be misrepresented as being the original software.
29 //
30 // 3. This notice may not be removed or altered from any source distribution.
31 //
32 // Author: Walker White
33 // Version: 6/20/16
34 
35 #ifndef __CU_POLYNOMIAL_H__
36 #define __CU_POLYNOMIAL_H__
37 
38 #include "CUMathBase.h"
39 #include "../util/CUDebug.h"
40 #include <iostream>
41 #include <vector>
42 
43 namespace cugl {
44 
67 class Polynomial : public std::vector<float>{
68 public:
69 #pragma mark Constants
70 
71  static const Polynomial ZERO;
73  static const Polynomial ONE;
74 
75 #pragma mark -
76 #pragma mark Constructors
77 
80  Polynomial() : std::vector<float>(1,0) { }
81 
89  Polynomial(long degree) : vector<float>(degree+1,0) {
90  (*this)[0] = 1;
91  }
92 
105  Polynomial(long degree, float value) : vector<float>(degree+1,value) {
106  }
107 
113  Polynomial(const Polynomial& poly) : vector<float>(poly) {
114  }
115 
128  Polynomial(const_iterator first, const_iterator last) : vector<float>(first,last) {
129  CUAssertLog(isValid(), "The array data is invalid");
130  }
131 
142  Polynomial(float* array, unsigned int size, unsigned int offset=0) : vector<float>() {
143  assign(array+offset,array+size+offset);
144  CUAssertLog(isValid(), "The array data is invalid");
145  }
146 
150  virtual ~Polynomial() { }
151 
152 #pragma mark -
153 #pragma mark Attributes
154 
163  long degree() const { return (long)size()-1; }
164 
170  bool isConstant() const { return size() == 1; }
171 
180  bool isValid() const { return size() == 1 || (size() > 1 && at(0) != 0); }
181 
190  bool isZero() const { return size() == 1 && at(0) == 0; }
191 
192 
193 #pragma mark -
194 #pragma mark Calculation Methods
195 
203  Polynomial derivative() const;
204 
212  float evaluate(float value) const;
213 
220  void validate();
221 
230  float normalize();
231 
253  bool roots(vector<float>& roots, float epsilon=CU_MATH_EPSILON) const;
254 
255 #pragma mark -
256 #pragma mark Setters
257 
264  Polynomial& operator=(float value) {
265  return set(value);
266  }
267 
276  Polynomial& set(float* array, int size);
277 
285  Polynomial& set(float value) {
286  resize(1); at(0) = value;
287  return *this;
288  }
289 
290 #pragma mark -
291 #pragma mark Comparisons
292 
303  bool operator<(const Polynomial& p) const;
304 
316  bool operator<(float value) const {
317  return size() == 1 && at(0) < value;
318  }
319 
331  bool operator<=(const Polynomial& p) const;
332 
344  bool operator<=(float value) const {
345  return size() == 1 && at(0) <= value;
346  }
347 
359  bool operator>(const Polynomial& p) const;
360 
372  bool operator>(float value) const {
373  return size() > 1 || at(0) > value;
374  }
375 
387  bool operator>=(const Polynomial& p) const;
388 
400  bool operator>=(float value) const {
401  return size() > 1 || at(0) >= value;
402  }
403 
411  bool operator==(float value) const {
412  return size() == 1 && at(0) == value;
413  }
414 
422  bool operator!=(float value) const {
423  return size() > 1 || at(0) != value;
424  }
425 
426 #pragma mark -
427 #pragma mark Operators
428 
435  Polynomial& operator+=(const Polynomial& other);
436 
444  Polynomial& operator-=(const Polynomial& other);
445 
454  return *this = (*this)*other;
455  }
456 
466  Polynomial& operator/=(const Polynomial& other);
467 
477  Polynomial& operator%=(const Polynomial& other);
478 
486  Polynomial operator+(const Polynomial& other) const {
487  return Polynomial(*this) += other;
488  }
489 
497  Polynomial operator-(const Polynomial& other) const {
498  return Polynomial(*this) -= other;
499  }
500 
508  Polynomial operator*(const Polynomial& other) const;
509 
517  Polynomial operator/(const Polynomial& other) const {
518  return Polynomial(*this) /= other;
519  }
520 
528  Polynomial operator%(const Polynomial& other) const {
529  return Polynomial(*this) %= other;
530  }
531 
539  Polynomial& operator+=(float value);
540 
548  Polynomial& operator-=(float value);
549 
557  Polynomial& operator*=(float value);
558 
568  Polynomial& operator/=(float value);
569 
579  Polynomial& operator%=(float value);
580 
588  Polynomial operator+(float value) const {
589  return Polynomial(*this) += value;
590  }
591 
599  Polynomial operator-(float value) const {
600  return Polynomial(*this) -= value;
601  }
602 
610  Polynomial operator*(float value) const {
611  return Polynomial(*this) *= value;
612  }
613 
621  Polynomial operator/(float value) const {
622  return Polynomial(*this) /= value;
623  }
624 
632  Polynomial operator%(float value) const {
633  return Polynomial(*this) %= value;
634  }
635 
641  Polynomial operator-() const;
642 
643 #pragma mark -
644 #pragma mark Friend Functions
645 
653  friend Polynomial operator+(float left, const Polynomial& right);
654 
663  friend Polynomial operator-(float left, const Polynomial& right);
664 
673  friend Polynomial operator*(float left, const Polynomial& right);
674 
686  friend Polynomial operator/(float left, const Polynomial& right);
687 
698  friend Polynomial operator%(float left, const Polynomial& right);
699 
712  friend bool operator<(float left, const Polynomial& right) {
713  return right.size() > 1 || right[0] > left;
714  }
715 
728  friend bool operator<=(float left, const Polynomial& right) {
729  return right.size() > 1 || right[0] >= left;
730  }
731 
744  friend bool operator>(float left, const Polynomial& right) {
745  return right.size() == 1 && right[0] < left;
746  }
747 
760  friend bool operator>=(float left, const Polynomial& right) {
761  return right.size() == 1 && right[0] <= left;
762  }
763 
764 
765 #pragma mark -
766 #pragma mark Conversion Methods
767 
781  std::string toString(bool format=true) const;
782 
784  operator std::string() const { return toString(); }
785 
786 
787 #pragma mark -
788 #pragma mark Internal Helpers
789 protected:
802  static Polynomial iterative_multiply(const Polynomial& a, const Polynomial& b);
803 
820  static Polynomial recursive_multiply(const Polynomial& a, const Polynomial& b);
821 
838  Polynomial& synthetic_divide(const Polynomial& other);
839 
860  bool bairstow_factor(Polynomial& quad, Polynomial& result, float epsilon) const;
861 
872  void solve_quadratic(vector<float>& roots) const;
873 };
874 
875 }
876 
877 #endif /* __CU_POLYNOMIAL_H__ */
bool operator!=(float value) const
Definition: CUPolynomial.h:422
Polynomial & operator/=(const Polynomial &other)
Polynomial()
Definition: CUPolynomial.h:80
Polynomial & set(float *array, int size)
Polynomial(long degree)
Definition: CUPolynomial.h:89
Polynomial operator%(const Polynomial &other) const
Definition: CUPolynomial.h:528
Polynomial & set(float value)
Definition: CUPolynomial.h:285
bool operator>(float value) const
Definition: CUPolynomial.h:372
Polynomial operator-() const
friend bool operator>=(float left, const Polynomial &right)
Definition: CUPolynomial.h:760
static const Polynomial ZERO
Definition: CUPolynomial.h:71
Polynomial & synthetic_divide(const Polynomial &other)
friend bool operator<(float left, const Polynomial &right)
Definition: CUPolynomial.h:712
bool operator<=(float value) const
Definition: CUPolynomial.h:344
std::string toString(bool format=true) const
static const Polynomial ONE
Definition: CUPolynomial.h:73
long degree() const
Definition: CUPolynomial.h:163
static Polynomial recursive_multiply(const Polynomial &a, const Polynomial &b)
Polynomial(const_iterator first, const_iterator last)
Definition: CUPolynomial.h:128
Definition: CUPolynomial.h:67
Polynomial operator*(const Polynomial &other) const
bool isValid() const
Definition: CUPolynomial.h:180
Polynomial derivative() const
bool isConstant() const
Definition: CUPolynomial.h:170
bool operator==(float value) const
Definition: CUPolynomial.h:411
Polynomial(const Polynomial &poly)
Definition: CUPolynomial.h:113
bool roots(vector< float > &roots, float epsilon=CU_MATH_EPSILON) const
friend bool operator>(float left, const Polynomial &right)
Definition: CUPolynomial.h:744
Polynomial & operator%=(const Polynomial &other)
void solve_quadratic(vector< float > &roots) const
Polynomial operator-(float value) const
Definition: CUPolynomial.h:599
bool operator>=(float value) const
Definition: CUPolynomial.h:400
virtual ~Polynomial()
Definition: CUPolynomial.h:150
bool operator<(float value) const
Definition: CUPolynomial.h:316
Polynomial(float *array, unsigned int size, unsigned int offset=0)
Definition: CUPolynomial.h:142
Polynomial & operator*=(const Polynomial &other)
Definition: CUPolynomial.h:453
float evaluate(float value) const
static Polynomial iterative_multiply(const Polynomial &a, const Polynomial &b)
Polynomial & operator+=(const Polynomial &other)
Polynomial operator*(float value) const
Definition: CUPolynomial.h:610
friend bool operator<=(float left, const Polynomial &right)
Definition: CUPolynomial.h:728
bool operator<(const Polynomial &p) const
Polynomial operator%(float value) const
Definition: CUPolynomial.h:632
Polynomial & operator=(float value)
Definition: CUPolynomial.h:264
bool isZero() const
Definition: CUPolynomial.h:190
Polynomial & operator-=(const Polynomial &other)
bool operator>=(const Polynomial &p) const
Definition: CUAnimationNode.h:52
bool bairstow_factor(Polynomial &quad, Polynomial &result, float epsilon) const
Polynomial operator-(const Polynomial &other) const
Definition: CUPolynomial.h:497
Polynomial(long degree, float value)
Definition: CUPolynomial.h:105
Polynomial operator+(const Polynomial &other) const
Definition: CUPolynomial.h:486
Polynomial operator/(const Polynomial &other) const
Definition: CUPolynomial.h:517
bool operator>(const Polynomial &p) const
Polynomial operator+(float value) const
Definition: CUPolynomial.h:588
bool operator<=(const Polynomial &p) const
Polynomial operator/(float value) const
Definition: CUPolynomial.h:621