polynomial.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #include "polynomial.hpp"
27 #include "casadi_misc.hpp"
28 #include <sstream>
29 
30 namespace casadi {
31 
32  Polynomial::Polynomial(double scalar) : p_(1, scalar) {
33  }
34 
35  Polynomial::Polynomial(double p0, double p1) {
36  p_.resize(2);
37  p_[0] = p0;
38  p_[1] = p1;
39  }
40 
41  Polynomial::Polynomial(double p0, double p1, double p2) {
42  p_.resize(3);
43  p_[0] = p0;
44  p_[1] = p1;
45  p_[2] = p2;
46  }
47 
48  Polynomial::Polynomial(double p0, double p1, double p2, double p3) {
49  p_.resize(4);
50  p_[0] = p0;
51  p_[1] = p1;
52  p_[2] = p2;
53  p_[3] = p3;
54  }
55 
56  void Polynomial::disp(std::ostream& stream, bool more) const {
57  if (more) {
58  for (casadi_int d=0; d<p_.size(); ++d) {
59  if (d==0) {
60  stream << p_[d];
61  } else if (d==1) {
62  stream << " + " << p_[d] << "*x";
63  } else {
64  stream << " + " << p_[d] << "*x^" << d;
65  }
66  }
67  } else {
68  stream << p_;
69  }
70  }
71 
72  casadi_int Polynomial::degree() const {
73  return p_.size()-1;
74  }
75 
76  double Polynomial::scalar() const {
77  casadi_assert_dev(degree()==0);
78  return p_.front();
79  }
80 
82  std::vector<double> p_ret(p_.size() + a.p_.size() - 1, 0);
83  for (casadi_int d=0; d<p_.size(); ++d) {
84  for (casadi_int d_a=0; d_a<a.p_.size(); ++d_a) {
85  p_ret[d+d_a] += p_[d] * a.p_[d_a];
86  }
87  }
88  return Polynomial(p_ret);
89  }
90 
92  return *this = *this*d;
93  }
94 
96  Polynomial ret = *this;
97  ret/=d;
98  return ret;
99  }
100 
102  for (std::vector<double>::iterator it=p_.begin(); it!=p_.end(); ++it) {
103  *it /= d;
104  }
105  return *this;
106  }
107 
109  Polynomial ret = *this;
110  return ret+=b;
111  }
112 
114  p_.resize(std::max(p_.size(), b.p_.size()), 0);
115  transform(b.p_.begin(), b.p_.end(), p_.begin(), p_.begin(), std::plus<double>());
116  trim();
117  return *this;
118  }
119 
121  Polynomial ret = *this;
122  return ret-=b;
123  }
124 
126  p_.resize(std::max(p_.size(), b.p_.size()), 0);
127  transform(p_.begin(), p_.begin()+b.p_.size(),
128  b.p_.begin(), p_.begin(), std::minus<double>());
129  trim();
130  return *this;
131  }
132 
134  // Remove trailing zeros
135  size_t new_size = p_.size();
136  std::vector<double>::const_reverse_iterator it=p_.rbegin();
137  while (it!=p_.rend() && 0==*it++) new_size--;
138  p_.resize(new_size);
139  }
140 
142  std::vector<double> ret_p(p_.size()-1);
143  for (casadi_int k=1; k<p_.size(); ++k) {
144  ret_p[k-1] = static_cast<double>(k)*p_[k];
145  }
146  return Polynomial(ret_p);
147  }
148 
150  std::vector<double> ret_p(p_.size()+1);
151  ret_p[0] = 0;
152  for (casadi_int k=0; k<p_.size(); ++k) {
153  ret_p[k+1] = p_[k]/static_cast<double>(k+1);
154  }
155  return Polynomial(ret_p);
156  }
157 
158 
159 } // namespace casadi
Helper class for differentiating and integrating polynomials.
Definition: polynomial.hpp:39
Polynomial operator+(const Polynomial &b) const
Definition: polynomial.cpp:108
double scalar() const
Get scalar value (error if degree()!=0)
Definition: polynomial.cpp:76
Polynomial(double scalar=1)
Construct a constant polynomial.
Definition: polynomial.cpp:32
void trim()
Remove excess zeros.
Definition: polynomial.cpp:133
Polynomial & operator/=(double b)
Definition: polynomial.cpp:101
Polynomial & operator+=(const Polynomial &b)
Definition: polynomial.cpp:113
Polynomial operator*(const Polynomial &b) const
Definition: polynomial.cpp:81
Polynomial anti_derivative() const
Create a new polynomial for the anti-derivative (primitive function)
Definition: polynomial.cpp:149
Polynomial operator-(const Polynomial &b) const
Definition: polynomial.cpp:120
Polynomial derivative() const
Create a new polynomial for the derivative.
Definition: polynomial.cpp:141
void disp(std::ostream &stream, bool more=false) const
Print a description of the object.
Definition: polynomial.cpp:56
Polynomial operator/(double b) const
Definition: polynomial.cpp:95
Polynomial & operator-=(const Polynomial &b)
Definition: polynomial.cpp:125
Polynomial & operator*=(const Polynomial &b)
Definition: polynomial.cpp:91
std::vector< double > p_
Definition: polynomial.hpp:120
casadi_int degree() const
Degree of the polynomial.
Definition: polynomial.cpp:72
The casadi namespace.
Definition: archiver.cpp:28