Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
polynomial.h
Go to the documentation of this file.
1/*
2 * Polynomial<CoeffT> class template
3 *
4 * Authors:
5 * Marco Cecchetti <mrcekets at gmail.com>
6 *
7 * Copyright 2008 authors
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it either under the terms of the GNU Lesser General Public
11 * License version 2.1 as published by the Free Software Foundation
12 * (the "LGPL") or, at your option, under the terms of the Mozilla
13 * Public License Version 1.1 (the "MPL"). If you do not alter this
14 * notice, a recipient may use your version of this file under either
15 * the MPL or the LGPL.
16 *
17 * You should have received a copy of the LGPL along with this library
18 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * You should have received a copy of the MPL along with this library
21 * in the file COPYING-MPL-1.1
22 *
23 * The contents of this file are subject to the Mozilla Public License
24 * Version 1.1 (the "License"); you may not use this file except in
25 * compliance with the License. You may obtain a copy of the License at
26 * http://www.mozilla.org/MPL/
27 *
28 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
29 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
30 * the specific language governing rights and limitations.
31 */
32
33#ifndef _GEOM_SL_POLYNOMIAL_H_
34#define _GEOM_SL_POLYNOMIAL_H_
35
36
38
39#include <vector>
40#include <string>
41
42#include <2geom/exception.h>
43
44
45
46
47namespace Geom { namespace SL {
48
49/*
50 * Polynomial<CoeffT> class template
51 *
52 * It represents a generic univariate polynomial with coefficients
53 * of type CoeffT. One way to get a multi-variate polynomial is
54 * to utilize a Polynomial instantiation as coefficient type
55 * in a recursive style.
56 *
57 */
58
59template< typename CoeffT >
61{
62 public:
63 typedef CoeffT coeff_type;
64 typedef std::vector<coeff_type> coeff_container_t;
65 typedef typename coeff_container_t::iterator iterator;
66 typedef typename coeff_container_t::const_iterator const_iterator;
67
68 /*
69 * a Polynomial should be never empty
70 */
72 {
73 m_coeff.push_back(zero_coeff);
74 }
75
76 explicit
77 Polynomial(CoeffT const& c, size_t i = 0)
78 {
79 m_coeff.resize(i, zero_coeff);
80 m_coeff.push_back(c);
81 }
82
83 /*
84 * forwarding of some std::vector methods
85 */
86
87 size_t size() const
88 {
89 return m_coeff.size();
90 }
91
93 {
94 return m_coeff.begin();
95 }
96
98 {
99 return m_coeff.end();
100 }
101
103 {
104 return m_coeff.begin();
105 }
106
108 {
109 return m_coeff.end();
110 }
111
112 void reserve(size_t n)
113 {
114 m_coeff.reserve(n);
115 }
116
117 size_t capacity() const
118 {
119 return m_coeff.capacity();
120 }
121
122 /*
123 * degree of the term with the highest degree
124 * and an initialized coefficient (even if zero)
125 */
126 size_t max_degree() const
127 {
128 if (size() == 0)
129 THROW_INVARIANTSVIOLATION (0);
130
131 return (size() - 1);
132 }
133
134 void max_degree(size_t n)
135 {
136 m_coeff.resize(n+1, zero_coeff);
137 }
138
139 /*
140 * degree of the term with the highest degree
141 * and an initialized coefficient that is not null
142 */
143 size_t real_degree() const
144 {
145 if (size() == 0)
146 THROW_INVARIANTSVIOLATION (0);
147
148 const_iterator it = end() - 1;
149 for (; it != begin(); --it)
150 {
151 if (*it != zero_coeff) break;
152 }
153 size_t i = static_cast<size_t>(it - begin());
154 return i;
155 }
156
157 bool is_zero() const
158 {
159 if (size() == 0)
160 THROW_INVARIANTSVIOLATION (0);
161
162 if (real_degree() != 0) return false;
163 if (m_coeff[0] != zero_coeff) return false;
164 return true;
165 }
166
167 /*
168 * trim leading zero coefficients
169 * after calling normalize max_degree == real_degree
170 */
172 {
173 size_t rd = real_degree();
174 if (rd != max_degree())
175 {
176 m_coeff.erase(begin() + rd + 1, end());
177 }
178 }
179
180 coeff_type const& operator[] (size_t i) const
181 {
182 return m_coeff[i];
183 }
184
186 {
187 return m_coeff[i];
188 }
189
190 // safe coefficient getter routine
191 coeff_type const& coefficient(size_t i) const
192 {
193 if (i > max_degree())
194 {
195 return zero_coeff;
196 }
197 else
198 {
199 return m_coeff[i];
200 }
201 }
202
203 // safe coefficient setter routine
204 void coefficient(size_t i, coeff_type const& c)
205 {
206 //std::cerr << "i: " << i << " c: " << c << std::endl;
207 if (i > max_degree())
208 {
209 if (c == zero_coeff) return;
210 reserve(i+1);
211 m_coeff.resize(i, zero_coeff);
212 m_coeff.push_back(c);
213 }
214 else
215 {
216 m_coeff[i] = c;
217 }
218 }
219
221 {
222 return m_coeff[real_degree()];
223 }
224
226 {
227 return m_coeff[real_degree()];
228 }
229
230 /*
231 * polynomail evaluation:
232 * T can be any type that is able to be + and * with the coefficient type
233 */
234 template <typename T>
235 T operator() (T const& x) const
236 {
237 T r = zero<T>()();
238 for(size_t i = max_degree(); i > 0; --i)
239 {
240 r += (*this)[i];
241 r *= x;
242 }
243 r += (*this)[0];
244 return r;
245 }
246
247 // opposite polynomial
249 {
250 Polynomial r;
251 // we need r.m_coeff to be empty so we can utilize push_back
252 r.m_coeff.pop_back();
253 r.reserve(size());
254 for(size_t i = 0; i < size(); ++i)
255 {
256 r.m_coeff.push_back( -(*this)[i] );
257 }
258 return r;
259 }
260
261 /*
262 * polynomial-polynomial mutating operators
263 */
264
266 {
267 size_t sz = std::min(size(), p.size());
268 for (size_t i = 0; i < sz; ++i)
269 {
270 (*this)[i] += p[i];
271 }
272 if (size() < p.size())
273 {
274 m_coeff.insert(end(), p.begin() + size(), p.end());
275 }
276 return (*this);
277 }
278
280 {
281 size_t sz = std::min(size(), p.size());
282 for (size_t i = 0; i < sz; ++i)
283 {
284 (*this)[i] -= p[i];
285 }
286 reserve(p.size());
287 for(size_t i = sz; i < p.size(); ++i)
288 {
289 m_coeff.push_back( -p[i] );
290 }
291 return (*this);
292 }
293
295 {
296 Polynomial r;
297 r.m_coeff.resize(size() + p.size() - 1, zero_coeff);
298
299 for (size_t i = 0; i < size(); ++i)
300 {
301 for (size_t j = 0; j < p.size(); ++j)
302 {
303 r[i+j] += (*this)[i] * p[j];
304 }
305 }
306 (*this) = r;
307 return (*this);
308 }
309
310 /*
311 * equivalent to multiply by x^n
312 */
314 {
315 m_coeff.insert(begin(), n, zero_coeff);
316 return (*this);
317 }
318
319 /*
320 * polynomial-coefficient mutating operators
321 */
322
324 {
325 m_coeff[0] = c;
326 return (*this);
327 }
328
330 {
331 (*this)[0] += c;
332 return (*this);
333 }
334
336 {
337 (*this)[0] -= c;
338 return (*this);
339 }
340
342 {
343 for (size_t i = 0; i < size(); ++i)
344 {
345 (*this)[i] *= c;
346 }
347 return (*this);
348 }
349
350 // return the poly in a string form
351 std::string str() const;
352
353 private:
354 // with zero_coeff defined as a static data member
355 // coefficient(size_t i) safe get method can always
356 // return a (const) reference
357 static const coeff_type zero_coeff;
359
360}; // end class Polynomial
361
362
363/*
364 * zero and one element spezcialization for Polynomial
365 */
366
367template< typename CoeffT >
368struct zero<Polynomial<CoeffT>, false>
369{
370 Polynomial<CoeffT> operator() () const
371 {
372 CoeffT zc = zero<CoeffT>()();
373 Polynomial<CoeffT> z(zc);
374 return z;
375 }
376};
377
378template< typename CoeffT >
379struct one<Polynomial<CoeffT>, false>
380{
381 Polynomial<CoeffT> operator() ()
382 {
383 CoeffT _1c = one<CoeffT>()();
384 Polynomial<CoeffT> _1(_1c);
385 return _1;
386 }
387};
388
389
390/*
391 * initialization of Polynomial static data members
392 */
393
394template< typename CoeffT >
396 = zero<typename Polynomial<CoeffT>::coeff_type>()();
397
398/*
399 * Polynomial - Polynomial binary mathematical operators
400 */
401
402template< typename CoeffT >
403inline
405{
406 size_t d = p.real_degree();
407 if (d != q.real_degree()) return false;
408 for (size_t i = 0; i <= d; ++i)
409 {
410 if (p[i] != q[i]) return false;
411 }
412 return true;
413}
414
415template< typename CoeffT >
416inline
418{
419 return !(p == q);
420}
421
422template< typename CoeffT >
423inline
424Polynomial<CoeffT>
426{
428 r += q;
429 return r;
430}
431
432template< typename CoeffT >
433inline
434Polynomial<CoeffT>
436{
438 r -= q;
439 return r;
440}
441
442template< typename CoeffT >
443inline
444Polynomial<CoeffT>
446{
448 r *= q;
449 return r;
450}
451
452template< typename CoeffT >
453inline
454Polynomial<CoeffT> operator<<(Polynomial<CoeffT> const& p, size_t n)
455{
456 Polynomial<CoeffT> r(p);
457 r <<= n;
458 return r;
459}
460
461
462/*
463 * polynomial-coefficient and coefficient-polynomial mathematical operators
464 */
465
466template< typename CoeffT >
467inline
468Polynomial<CoeffT>
469operator+( Polynomial<CoeffT> const& p, CoeffT const& c )
470{
472 r += c;
473 return r;
474}
475
476template< typename CoeffT >
477inline
478Polynomial<CoeffT>
479operator+( CoeffT const& c, Polynomial<CoeffT> const& p)
480{
481 return (p + c);
482}
483
484template< typename CoeffT >
485inline
486Polynomial<CoeffT>
487operator-( Polynomial<CoeffT> const& p, CoeffT const& c )
488{
490 r -= c;
491 return r;
492}
493
494template< typename CoeffT >
495inline
496Polynomial<CoeffT>
497operator-( CoeffT const& c, Polynomial<CoeffT> const& p)
498{
499 return (p - c);
500}
501
502template< typename CoeffT >
503inline
504Polynomial<CoeffT>
505operator*( Polynomial<CoeffT> const& p, CoeffT const& c )
506{
508 r *= c;
509 return r;
510}
511
512template< typename CoeffT >
513inline
514Polynomial<CoeffT>
515operator*( CoeffT const& c, Polynomial<CoeffT> const& p)
516{
517 return (p * c);
518}
519
520
521/*
522 * operator<< extension for printing Polynomial
523 * and str() method for transforming a Polynomial into a string
524 */
525
526template< typename charT, typename CoeffT >
527inline
528std::basic_ostream<charT> &
529operator<< (std::basic_ostream<charT> & os, const Polynomial<CoeffT> & p)
530{
531 if (p.size() == 0) return os;
532 os << "{" << p[0];
533 for (size_t i = 1; i < p.size(); ++i)
534 {
535 os << ", " << p[i];
536 }
537 os << "}";
538 return os;
539}
540
541
542template< typename CoeffT >
543inline
544std::string Polynomial<CoeffT>::str() const
545{
546 std::ostringstream oss;
547 oss << (*this);
548 return oss.str();
549}
550
551
552} /*end namespace Geom*/ } /*end namespace SL*/
553
554
555
556
557#endif // _GEOM_SL_POLYNOMIAL_H_
558
559
560/*
561 Local Variables:
562 mode:c++
563 c-file-style:"stroustrup"
564 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
565 indent-tabs-mode:nil
566 fill-column:99
567 End:
568*/
569// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Defines the different types of exceptions that 2geom can throw.
Polynomial & operator*=(coeff_type const &c)
Definition polynomial.h:341
coeff_type const & operator[](size_t i) const
Definition polynomial.h:180
coeff_type const & leading_coefficient() const
Definition polynomial.h:220
Polynomial & operator<<=(size_t n)
Definition polynomial.h:313
void max_degree(size_t n)
Definition polynomial.h:134
coeff_container_t::const_iterator const_iterator
Definition polynomial.h:66
void reserve(size_t n)
Definition polynomial.h:112
static const coeff_type zero_coeff
Definition polynomial.h:357
coeff_type & leading_coefficient()
Definition polynomial.h:225
const_iterator end() const
Definition polynomial.h:97
coeff_container_t::iterator iterator
Definition polynomial.h:65
std::string str() const
Definition polynomial.h:544
void coefficient(size_t i, coeff_type const &c)
Definition polynomial.h:204
coeff_container_t m_coeff
Definition polynomial.h:358
size_t size() const
Definition polynomial.h:87
Polynomial & operator+=(coeff_type const &c)
Definition polynomial.h:329
size_t capacity() const
Definition polynomial.h:117
Polynomial operator-() const
Definition polynomial.h:248
Polynomial & operator+=(Polynomial const &p)
Definition polynomial.h:265
T operator()(T const &x) const
Definition polynomial.h:235
Polynomial & operator*=(Polynomial const &p)
Definition polynomial.h:294
Polynomial(CoeffT const &c, size_t i=0)
Definition polynomial.h:77
Polynomial & operator=(coeff_type const &c)
Definition polynomial.h:323
std::vector< coeff_type > coeff_container_t
Definition polynomial.h:64
const_iterator begin() const
Definition polynomial.h:92
Polynomial & operator-=(coeff_type const &c)
Definition polynomial.h:335
size_t real_degree() const
Definition polynomial.h:143
size_t max_degree() const
Definition polynomial.h:126
Polynomial & operator-=(Polynomial const &p)
Definition polynomial.h:279
coeff_type const & coefficient(size_t i) const
Definition polynomial.h:191
bool is_zero() const
Definition polynomial.h:157
RectangularCluster rd
double c[8][4]
std::enable_if_t<(M > 0) &&(M<=N), MultiPoly< N, CoeffT > > operator-(MultiPoly< N, CoeffT > const &p, MultiPoly< M, CoeffT > const &q)
Definition multipoly.h:508
std::enable_if_t<(M > 0) &&(M<=N), MultiPoly< N, CoeffT > > operator+(MultiPoly< N, CoeffT > const &p, MultiPoly< M, CoeffT > const &q)
Definition multipoly.h:486
bool operator!=(Polynomial< CoeffT > const &p, Polynomial< CoeffT > const &q)
Definition polynomial.h:417
std::enable_if_t<(M > 0) &&(M<=N), MultiPoly< N, CoeffT > > operator*(MultiPoly< N, CoeffT > const &p, MultiPoly< M, CoeffT > const &q)
Definition multipoly.h:531
Various utility functions.
Definition affine.h:22
std::ostream & operator<<(std::ostream &os, const Bezier &b)
Definition bezier.h:372
bool operator==(D2< T > const &a, D2< T > const &b)
Definition d2.h:177