Library of Assembled Shared Sources
polynomial.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_POLYNOMIAL_INL
44#define LASS_GUARDIAN_OF_INCLUSION_NUM_POLYNOMIAL_INL
45
46#include "num_common.h"
47#include "polynomial.h"
48
49namespace lass
50{
51namespace num
52{
53
54// --- public --------------------------------------------------------------------------------------
55
56template <typename T>
57Polynomial<T>::Polynomial()
58{
59}
60
61
62template <typename T>
63Polynomial<T>::Polynomial(TParam iScalar):
64 a_(1, iScalar)
65{
66}
67
68
69
70template <typename T>
71Polynomial<T>::Polynomial(const TCoefficients& iCoefficients):
72 a_(iCoefficients)
73{
74}
75
76
77template <typename T>
78template <typename InputIterator>
79Polynomial<T>::Polynomial(InputIterator iBegin, InputIterator iEnd):
80 a_(iBegin, iEnd)
81{
82}
83
84
85
86template <typename T> inline
87const typename Polynomial<T>::TCoefficients&
88Polynomial<T>::coefficients() const
89{
90 return a_;
91}
92
93
94
95template <typename T> inline
96const typename Polynomial<T>::TValue
97Polynomial<T>::operator[](size_t iIndex) const
98{
99 LASS_ASSERT(iIndex < a_.size());
100 return a_[iIndex];
101}
102
103
104
105template <typename T> inline
106const typename Polynomial<T>::TValue
107Polynomial<T>::at(size_t iIndex) const
108{
109 return iIndex < a_.size() ? a_[iIndex] : TNumTraits::zero;
110}
111
112
113
114template <typename T>
115const typename Polynomial<T>::TValue
116Polynomial<T>::operator()(TParam iX) const
117{
118 TValue result = TNumTraits::zero;
119 TValue x = TNumTraits::one;
120 const size_t n = a_.size();
121 for (size_t i = 0; i < n; ++i)
122 {
123 result += a_[i] * x;
124 x *= iX;
125 }
126 return result;
127}
128
129
130
131template <typename T>
132const Polynomial<T>& Polynomial<T>::operator+() const
133{
134 return *this;
135}
136
137
138
139template <typename T>
140const Polynomial<T> Polynomial<T>::operator-() const
141{
142 const size_t n = a_.size();
143 TCoefficients result(n);
144 for (size_t i = 0; i < n; ++i)
145 {
146 result[i] = -a_[i];
147 }
148 return Polynomial<T>(result);
149}
150
151
152
153template <typename T>
154Polynomial<T>& Polynomial<T>::operator+=(const Polynomial<T>& iOther)
155{
156 const size_t n = iOther.a_.size();
157 if (a_.size() < n)
158 {
159 a_.resize(n, TNumTraits::zero);
160 }
161 for (size_t i = 0; i < n; ++i)
162 {
163 a_[i] += iOther.a_[i];
164 }
165 return *this;
166}
167
168
169
170template <typename T>
171Polynomial<T>& Polynomial<T>::operator-=(const Polynomial<T>& iOther)
172{
173 const size_t n = iOther.a_.size();
174 if (a_.size() < n)
175 {
176 a_.resize(n, TNumTraits::zero);
177 }
178 for (size_t i = 0; i < n; ++i)
179 {
180 a_[i] -= iOther.a_[i];
181 }
182 return *this;
183}
184
185
186
187template <typename T>
188Polynomial<T>& Polynomial<T>::operator*=(const Polynomial<T>& iOther)
189{
190 const size_t m = a_.size();
191 const size_t n = iOther.a_.size();
192 TCoefficients result(m + n - 1, TNumTraits::zero);
193 for (size_t i = 0; i < m; ++i)
194 {
195 const TValue a = a_[i];
196 for (size_t k = 0; k < n; ++k)
197 {
198 result[i + k] += a * iOther.a_[k];
199 }
200 }
201 a_.swap(result);
202 return *this;
203}
204
205
206
207template <typename T>
208Polynomial<T>& Polynomial<T>::operator+=(TParam iScalar)
209{
210 if (a_.empty())
211 {
212 a_.resize(1, iScalar);
213 }
214 else
215 {
216 a_[0] += iScalar;
217 }
218 return *this;
219}
220
221
222
223template <typename T>
224Polynomial<T>& Polynomial<T>::operator-=(TParam iScalar)
225{
226 if (a_.empty())
227 {
228 a_.resize(1, -iScalar);
229 }
230 else
231 {
232 a_[0] -= iScalar;
233 }
234 return *this;
235}
236
237
238
239template <typename T>
240Polynomial<T>& Polynomial<T>::operator*=(TParam iScalar)
241{
242 const size_t n = a_.size();
243 for (size_t i = 0; i < n; ++i)
244 {
245 a_[i] *= iScalar;
246 }
247 return *this;
248}
249
250
251
252template <typename T>
253Polynomial<T>& Polynomial<T>::operator/=(TParam iScalar)
254{
255 const size_t n = a_.size();
256 for (size_t i = 0; i < n; ++i)
257 {
258 a_[i] /= iScalar;
259 }
260 return *this;
261}
262
263
264
265template <typename T>
266Polynomial<T> Polynomial<T>::derivative() const
267{
268 const size_t n = a_.size();
269 if (n < 2)
270 {
271 return Polynomial<T>();
272 }
273 TCoefficients result(n - 1);
274 for (size_t i = 1; i < n; ++i)
275 {
276 result[i - 1] = static_cast<typename TNumTraits::baseType>(i) * a_[i];
277 }
278 return Polynomial<T>(result);
279}
280
281
282
283template <typename T>
284Polynomial<T> Polynomial<T>::integral() const
285{
286 const size_t n = a_.size();
287 if (n == 0)
288 {
289 return Polynomial<T>();
290 }
291 TCoefficients result(n + 1);
292 result[0] = TNumTraits::zero;
293 for (size_t i = 0; i < n; ++i)
294 {
295 result[i + 1] = a_[i] / static_cast<typename TNumTraits::baseType>(i);
296 }
297 return Polynomial<T>(result);
298}
299
300
301
302template <typename T>
303Polynomial<T> Polynomial<T>::pow(size_t iPower) const
304{
305 Polynomial<T> result(1);
306 for (size_t i = 0; i < iPower; ++i)
307 {
308 result *= *this;
309 }
310 return result;
311}
312
313
314
315/** return size of coefficients.
316 */
317template <typename T>
318const typename Polynomial<T>::size_type Polynomial<T>::size() const
319{
320 return a_.size();
321}
322
323
324
325/** return iterator to first (lowest) coefficient
326 */
327template <typename T>
328const typename Polynomial<T>::const_iterator Polynomial<T>::begin() const
329{
330 return a_.begin();
331}
332
333
334
335/** return iterator to last (highest) coefficient
336 */
337template <typename T>
338const typename Polynomial<T>::const_iterator Polynomial<T>::end() const
339{
340 return a_.end();
341}
342
343
344
345/** return constant polynomial 1
346 */
347template <typename T>
348Polynomial<T> Polynomial<T>::one()
349{
350 static Polynomial<T> result(1);
351 return result;
352}
353
354
355
356/** return linear polynomial x
357 */
358template <typename T>
359Polynomial<T> Polynomial<T>::x()
360{
361 static TValue coefficients[2] = { 0, 1 };
362 static Polynomial<T> result(coefficients, coefficients + 2);
363 return result;
364}
365
366
367
368// --- free ----------------------------------------------------------------------------------------
369
370template <typename T>
371bool operator==(const Polynomial<T>& iA, const Polynomial<T>& iB)
372{
373 typedef typename Polynomial<T>::TCoefficients TCoefficients;
374 const TCoefficients& a = iA.coefficients();
375 const TCoefficients& b = iB.coefficients();
376 const size_t m = a.size();
377 const size_t n = b.size();
378 if (m != n)
379 {
380 return false;
381 }
382 for (size_t i = 0; i < n; ++i)
383 {
384 if (a[i] != b[i])
385 {
386 return false;
387 }
388 }
389 return true;
390}
391
392
393
394template <typename T> inline
395bool operator!=(const Polynomial<T>& iA, const Polynomial<T>& iB)
396{
397 return !(iA == iB);
398}
399
400
401
402template <typename T> inline
403Polynomial<T> operator+(const Polynomial<T>& iA, const Polynomial<T>& iB)
404{
405 Polynomial<T> result(iA);
406 result += iB;
407 return result;
408}
409
410
411
412template <typename T> inline
413Polynomial<T> operator-(const Polynomial<T>& iA, const Polynomial<T>& iB)
414{
415 Polynomial<T> result(iA);
416 result -= iB;
417 return result;
418}
419
420
421
422template <typename T> inline
423Polynomial<T> operator*(const Polynomial<T>& iA, const Polynomial<T>& iB)
424{
425 Polynomial<T> result(iA);
426 result *= iB;
427 return result;
428}
429
430
431
432template <typename T> inline
433Polynomial<T> operator+(const T& iA, const Polynomial<T>& iB)
434{
435 Polynomial<T> result(iB);
436 result += iA;
437 return result;
438}
439
440
441
442template <typename T> inline
443Polynomial<T> operator-(const T& iA, const Polynomial<T>& iB)
444{
445 Polynomial<T> result(-iB);
446 result += iA;
447 return result;
448}
449
450
451
452template <typename T> inline
453Polynomial<T> operator*(const T& iA, const Polynomial<T>& iB)
454{
455 Polynomial<T> result(iB);
456 result *= iA;
457 return result;
458}
459
460
461
462template <typename T> inline
463Polynomial<T> operator+(const Polynomial<T>& iA, const T& iB)
464{
465 Polynomial<T> result(iA);
466 result += iB;
467 return result;
468}
469
470
471
472template <typename T> inline
473Polynomial<T> operator-(const Polynomial<T>& iA, const T& iB)
474{
475 Polynomial<T> result(iA);
476 result -= iB;
477 return result;
478}
479
480
481
482template <typename T> inline
483Polynomial<T> operator*(const Polynomial<T>& iA, const T& iB)
484{
485 Polynomial<T> result(iA);
486 result *= iB;
487 return result;
488}
489
490
491
492template <typename T> inline
493Polynomial<T> operator/(const Polynomial<T>& iA, const T& iB)
494{
495 Polynomial<T> result(iA);
496 result /= iB;
497 return result;
498}
499
500
501
502template <typename T, typename Char, typename Traits>
503std::basic_ostream<Char, Traits>&
504operator<<(std::basic_ostream<Char, Traits>& iS, const Polynomial<T>& iA)
505{
506 typedef typename Polynomial<T>::TCoefficients TCoefficients;
507 const TCoefficients& a = iA.coefficients();
508 const size_t n = a.size();
509 if (n == 0)
510 {
511 iS << T();
512 return iS;
513 }
514 iS << a[0];
515 for (size_t i = 1; i < n; ++i)
516 {
517 iS << " + " << a[i] << "x^" << static_cast<unsigned long>(i);
518 }
519 return iS;
520}
521
522
523
524}
525
526}
527
528#endif
529
530// EOF
an univariate polynomial.
Definition polynomial.h:68
const const_iterator end() const
return iterator to last (highest) coefficient
static Polynomial< T > x()
return linear polynomial x
static Polynomial< T > one()
return constant polynomial 1
const size_type size() const
return size of coefficients.
const const_iterator begin() const
return iterator to first (lowest) coefficient
numeric types and traits.
Definition basic_ops.h:70
Library for Assembled Shared Sources.
Definition config.h:53