Polymetic  1.1
A c++ library for polynomial and matrix arithmetic, focused on applications in Kinematics.
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
Polynomial_impl.ipp
Go to the documentation of this file.
1 // Copyright 2018 Dhruvesh Nikhilkumar Patel
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
19 #ifndef _POLYNOMIAL_IMPL_IPP_
20 #define _POLYNOMIAL_IMPL_IPP_
21 
22 #include "../include/Polynomial.hpp"
23 #include <stdexcept>
24 #include <iterator>
25 #ifdef VERBOSE
26 #include <iostream>
27 #endif
28 
31 template <typename FieldT>
32 Polynomial<FieldT>::Polynomial(std::initializer_list<FieldT> in_list)
33  :m_coefs{in_list},m_size{in_list.size()}
34 {
35  trim();
36 }
40 template <typename FieldT>
41 template <typename InputIt>
42 Polynomial<FieldT>::Polynomial(InputIt first, InputIt last)
43 {
44  for(auto it=first; it != last; ++it) {
45  m_coefs.push_back(*it);
46  m_size++;
47  }
48  trim();
49 }
53 template <typename FieldT>
55  :m_coefs{c},m_size{1}
56 {
57  trim();
58 }
61 template <typename FieldT>
62 template <typename convertibleToFieldT>
63 Polynomial<FieldT>::Polynomial(convertibleToFieldT v)
64  :m_coefs{static_cast<FieldT>(v)},m_size{1}
65 {
66  trim();
67 }
68 
72 template<typename FieldT>
74 {
75  m_coefs.push_back(coeff);
76  ++m_size;
77 }
81 template <typename FieldT>
82 const FieldT& Polynomial<FieldT>::operator[] (size_t i) const
83 {
84  if(i>=m_size){
85  throw std::out_of_range("");
86  }
87  return *(std::next(m_coefs.begin(),i));
88 }
89 
93 template <typename FieldT>
95 {
96  /* calling the const version of the operator to avoid code duplication */
97  return const_cast<FieldT&>((static_cast<Polynomial<FieldT> const*>(this)->operator[](i)));
98 }
99 
104 template <typename FieldT>
106 {
107  #ifdef VERBOSE
108  std::cout<<"=(&)"<<std::endl;
109  #endif
110  /* Provide self assignment protection if the use cases demand. Skipping for now.*/
111  Polynomial<FieldT> rhs (rhs_ref);
112  using std::swap; // Just incase we need ADL
113  swap(*this,rhs);
114  return *this;
115 
116 }
120 template <typename FieldT>
122 {
123  /* Provide self assignment protection if the use caandses demand. Skipping for now.*/
124  #ifdef VERBOSE
125  std::cout<<"=(&&)"<<std::endl;
126  #endif
127 
128  using std::swap; // Just incase we need ADL
129  swap(*this,rhs);
130  return *this;
131 
132 }
133 
134 
135 
136 
142 template <typename FieldT>
144 {
145  #ifdef VERBOSE
146  std::cout<<"+=(&) "<<std::endl;
147  #endif
148  /* identify the polynomial which has higher degree*/
149  Polynomial<FieldT> const& bigger_polynomial = p2.size() > this->size() ? p2 : *this;
150  Polynomial<FieldT> const& smaller_polynomial = p2.size() <= this->size() ? p2 : *this;
151  /* copy the bigger polynomial */
152  Polynomial<FieldT> copy_for_swap(bigger_polynomial);
153  /* \todo Coefficient iterator class for Polynomial */
154  auto s_it = smaller_polynomial.m_coefs.begin();
155  auto b_it = copy_for_swap.m_coefs.begin();
156  for( ;s_it != smaller_polynomial.m_coefs.end();) {
157  *b_it+=*s_it;
158  ++s_it;
159  ++b_it;
160  }
161  /* ensure that the invariant is maintained */
162  copy_for_swap.trim();
163  /* swap this */
164  swap(*this,copy_for_swap);
165  return *this;
166 }
169 template <typename FieldT>
171 {
172  #ifdef VERBOSE
173  std::cout<<"+=(&&) "<<std::endl;
174  #endif
175  /* identify the polynomial which has higher degree*/
176  Polynomial<FieldT>& bigger_polynomial = p2.size() > this->size() ? p2 : *this;
177  Polynomial<FieldT> const& smaller_polynomial = p2.size() <= this->size() ? p2 : *this;
178  /* \todo Coefficient iterator class for Polynomial */
179  auto s_it = smaller_polynomial.m_coefs.begin();
180  auto b_it = bigger_polynomial.m_coefs.begin();
181  for( ;s_it != smaller_polynomial.m_coefs.end();) {
182  *b_it+=*s_it;
183  ++s_it;
184  ++b_it;
185  }
186  /* ensure that the invariant is maintained */
187  bigger_polynomial.trim();
188  /* swap this */
189  swap(*this,bigger_polynomial);
190  return *this;
191 }
196 template <typename FieldT>
198 {
199  #ifdef VERBOSE
200  std::cout<<"-=(&) "<<std::endl;
201  #endif
202  return (*this+=-p2);
203 }
204 
207 template <typename FieldT>
209 {
210  #ifdef VERBOSE
211  std::cout<<"-=(&&) "<<std::endl;
212  #endif
213 
214  return (*this+=-std::move(p2));
215 }
216 
219 template <typename FieldT>
221 {
222  #ifdef VERBOSE
223  std::cout<<"this+(value) "<<std::endl;
224  #endif
225  p2+=(*this);
226  return std::move(p2);
227 }
230 template <typename FieldT>
232 {
233  return static_cast<const Polynomial<FieldT>*>(this)->operator+(p2);
234 }
235 
238 template <typename FieldT>
240 {
241  #ifdef VERBOSE
242  std::cout<<"this-(value) "<<std::endl;
243  #endif
244  Polynomial<FieldT> temp (-std::move(p2));
245  temp+=*this;
246  return std::move(temp);
247 }
248 
251 template <typename FieldT>
253 {
254  return static_cast<const Polynomial<FieldT>*>(this)->operator-(p2);
255 }
256 /******************* Helpers **********************/
257 template <typename FieldT>
259 {
260  for(typename std::list<FieldT>::reverse_iterator r_it = m_coefs.rbegin(); r_it != m_coefs.rend(); ) {
261  /* remove trailing zeros but if there is only one coefficient and that is zero then leave it to be a
262  * zero polynomial */
263  if ( *r_it == 0 && size() >1) {
264  typename std::list<FieldT>::reverse_iterator to_delete_it = r_it;
265  ++r_it; // reverse iterator decremented
266  m_coefs.erase(--to_delete_it.base()); //pre-decrement necessary as base points to an element ahead of rit which would be end()
267  m_size--;
268  }
269  else {
270  break; // break as soon as we find first non-zero coeff from behind
271  }
272  }
273 }
274 
275 template <typename FieldT>
277  for(auto& coef : m_coefs) {
278  coef = ::minus(coef);
279  }
280  return *this;
281 }
282 
283 
284 #endif// _POLYNOMIAL_IPP_
void appendTerm(FieldT coeff)
Append new terms by pushing back coefficients.
std::list< FieldT > m_coefs
Definition: Polynomial.hpp:169
Polynomial()
The default constructor to make the class default constructible.
Definition: Polynomial.hpp:47
Polynomial operator+(const Polynomial &p2)
operator
friend Polynomial operator-(Polynomial const &rhs)
The unary (-) operator.
Definition: Polynomial.hpp:114
size_t size()
Definition: Polynomial.hpp:155
const FieldT & operator[](size_t i) const
Operator to fetch coefficients. Checks range.
friend void swap(Polynomial &lhs, Polynomial &rhs) noexcept
A non-template friend swap to aid in the implementation of copy-and-swap.
Definition: Polynomial.hpp:97
const Polynomial & operator+=(Polynomial const &p2)
The += operator for polynomials.
size_t m_size
Definition: Polynomial.hpp:170
void trim()
Use to maintain the invariant 1.
Polynomial & minus()
Flip the sign of all coefs.
Contains the definition for the abstract base class which will be used by different multiplication al...
Definition: Polynomial.hpp:40
const Polynomial & operator-=(Polynomial const &p2)
The -= operator for polynomials.
Polynomial const & operator=(const Polynomial &rhs)
The assignemnt operator.