Polynomial
 
Betöltés...
Keresés...
Nincs egyezés
polynomial.hpp
Ugrás a fájl dokumentációjához.
1
5#ifndef POLYNOMIAL_H
6#define POLYNOMIAL_H
7
8#include <vector>
9#include <iostream>
10using namespace std;
11
12namespace bme {
13
18 template <typename T>
19 class Polynomial {
20 private:
22 vector<T> coef;
24 int dg;
25
26 void deg_check() {
27 dg = -1;
28 for (int k = coef.size()-1; k >= 0 ; k--) {
29 if (coef[k] != T(0)) {
30 dg = k;
31 break;
32 }
33 }
34 setCoefVectorSize(dg);
35 }
36
37 void setCoefVectorSize(int _dg) {
38 if (_dg < -1) {
39 return;
40 }
41 else if (_dg == -1) {
42 clear();
43 return;
44 }
45 size_t new_deg = static_cast<size_t>(_dg);
46 coef.resize(new_deg + 1);
47 }
48
49 static Polynomial<T> InvalidPoly() {
50 Polynomial<T> ans;
51 ans.dg = -2;
52 return ans;
53 }
54
55
56 public:
58
63 clear();
64 }
65
67
71 template <typename U>
72 Polynomial<T>(U a) {
73 coef.resize(1);
74 coef[0] = T(a);
75 deg_check();
76 }
77
79
85 template<typename U, typename V, typename W>
86 Polynomial<T>(U a, V b, W c) {
87 coef.resize(3);
88 coef[2] = T(a);
89 coef[1] = T(b);
90 coef[0] = T(c);
91 deg_check();
92 }
93
95
101 template <typename U>
102 Polynomial<T>(int array_size, const U * array) {
103 if (array_size <= 0) {
104 coef.clear();
105 return;
106 }
107 coef.resize(array_size);
108 for (int k = 0; k < array_size; k++) {
109 coef[k] = T(array[k]);
110 }
111 deg_check();
112 }
113
115
120 int deg() const {
121 return dg;
122 }
123
125
128 bool isInvalid()const {
129 return dg == -2;
130 }
131
134 coef.resize(1);
135 coef[0] = T(0);
136 dg = -2;
137 }
138
140
146 const T& getCoef(int deg) const {
147 if ((deg < 0) || (deg > dg)) { return T(0); }
148 return coef[deg];
149 }
150
152
158 const T& operator[](int deg) const {
159 return getCoef(deg);
160 }
161
163
169 void set(int deg, const T& val) {
170 if (isInvalid()) {
171 return;
172 }
173 if (deg < 0) { return; }
174 const size_t ix = static_cast<size_t>(deg);
175 if (ix + 1 > coef.size()) {
176 coef.resize(ix + 1);
177 }
178 coef[ix] = val;
179 deg_check();
180 }
181
183
186 void clear() {
187 coef.resize(1);
188 dg = -1;
189 coef[0] = T(0);
190 }
191
193
196 void minimize() {
197 if (isInvalid()) {
198 return;
199 }
200 const size_t rsize = static_cast<size_t>(deg()) + 1;
201 coef.reserve(rsize);
202 }
203
205
208 bool isZero() const {
209 return (deg() == -1);
210 }
211
213
220 void shift(int n = 1) {
221 if (n == 0 || isInvalid()) return;
222 if (n < -dg) {
223 clear();
224 return;
225 }
226 else if (n < 0) {
227 for (int k = 0; k <= dg + n; k++) coef[k] = coef[k - n];
228 for (int k = dg + n + 1; k <= dg; k++) coef[k] = T(0);
229 deg_check();
230 return;
231 }
232 if (static_cast<size_t>(n) + static_cast<size_t>(deg()) > INT_MAX) {
234 return;
235 }
236 const int old_deg = deg();
237 setCoefVectorSize(n + old_deg);
238 for (int k = old_deg; k >= 0; k--) coef[k + n] = coef[k];
239 for (int k = 0; k < n; k++) coef[k] = T(0);
240 dg += n;
241 }
242
243 // FUNCTION APPLICATION //
244
246
251 T of(const T& a) const {
252 if (isInvalid()) {
253 return T(0);
254 }
255 if (deg() <= 0) { return coef[0]; }
256 T ans;
257 ans = T(0);
258 for (int k = deg(); k >= 0; k--) {
259 ans *= a;
260 ans += coef[k];
261 }
262 return ans;
263 }
264
266
271 T operator()(const T& a) const { return of(a); }
272
274
279 Polynomial<T> of(const Polynomial<T>& other) const {
280 if (isInvalid() || other.isInvaid()) {
281 return InvalidPoly();
282 }
283 if (deg() <= 0) { return Polynomial<T>(coef[0]); }
284 Polynomial<T> ans(T(0));
285 for (int k = deg(); k >= 0; k--) {
286 ans *= other;
287 ans += Polynomial<T>(coef[k]);
288 }
289 return ans;
290 }
291
293
299 return of(other);
300 }
301
302 // COMPARISON //
303
304
306
313 bool operator==(const Polynomial<T>& other) const {
314 if (deg() != other.deg()) return false;
315 for (int k = 0; k <= dg; k++) {
316 if (coef[k] != other.coef[k]) return false;
317 }
318 return true;
319 }
320
321 bool operator!=(const Polynomial<T>& other) const {
322 return !(*this == other);
323 }
324
326
335 bool operator<(const Polynomial<T>& other) const {
336 if (isInvalid()) {
337 return false;
338 }
339 else if (deg() < other.deg()) {
340 return true;
341 }
342 else if (deg() > other.deg()) {
343 return false;
344 }
345 for (int i = 0; i <= deg(); ++i) {
346 const T& c1 = getCoef(i);
347 const T& c2 = other.getCoef(i);
348 if (c1 < c2) {
349 return true;
350 }
351 else if (c1 > c2) {
352 return false;
353 }
354 }
355 return false;
356 }
357
358 bool operator<=(const Polynomial<T>& other) const {
359 return (*this) < other || (*this) == other;
360 }
361
362 bool operator>(const Polynomial<T>& other) const {
363 return !((*this) <= other);
364 }
365
366 bool operator>=(const Polynomial<T>& other) const {
367 return !((*this) < other);
368 }
369
370 // ARITHMETIC //
371
373 if (isInvalid() || other.isInvalid()) {
374 return InvalidPoly();
375 }
376 Polynomial<T> ans;
377 const int dmax = (deg() > other.deg()) ? deg() : other.deg();
378 ans.setCoefVectorSize(dmax);
379 for (int k = 0; k <= dmax; k++) {
380 ans.coef[k] = getCoef(k) + other.getCoef(k);
381 }
382 ans.deg_check();
383 return ans;
384 }
385
387 (*this) = (*this) + other;
388 return *this;
389 }
390
392 if (isInvalid()) {
393 return InvalidPoly();
394 }
395 Polynomial<T> ans;
396 ans.setCoefVectorSize(deg());
397 for (int k = 0; k <= dg; k++) { ans.coef[k] = -coef[k]; }
398 ans.deg_check();
399 return ans;
400 }
401
403 if (isInvalid() || other.isInvalid()) {
404 return InvalidPoly();
405 }
406 Polynomial<T> ans;
407 const int dmax = (deg() > other.deg()) ? deg() : other.deg();
408 ans.setCoefVectorSize(dmax);
409 for (int k = 0; k <= dmax; k++) {
410 ans.coef[k] = getCoef(k) - other.getCoef(k);
411 }
412 ans.deg_check();
413 return ans;
414 }
415
417 (*this) = (*this) - other;
418 return *this;
419 }
420
422
429 if (isInvalid() || other.isInvalid()) {
430 return InvalidPoly();
431 }
432 Polynomial<T> ans;
433 if (isZero() || other.isZero()) { return ans; }
434 if (static_cast<size_t>(deg()) + static_cast<size_t>(other.deg()) > INT_MAX) {
435 return InvalidPoly();
436 }
437 const int dans = deg() + other.deg();
438 ans.setCoefVectorSize(dans);
439 for (int k = 0; k <= dans; k++) {
440 T c(0);
441 for (int j = 0; j <= k; j++) {
442 if ((j <= dg) && (k - j <= other.dg)) {
443 c += coef[j] * other.coef[k - j];
444 }
445 }
446 ans.coef[k] = c;
447 }
448 ans.deg_check();
449 return ans;
450 }
451
453 *this = (*this) * other;
454 return *this;
455 }
456
458
464 Polynomial<T> pow(int k) const {
465 if (k < 0 || isInvalid()) {
466 Polynomial<T> ans;
467 return InvalidPoly();
468 }
469 if (k == 0) { return Polynomial<T>(1); }
470 if (k == 1) { return *this; }
471
472 if (k % 2 == 0) {
473 int half_k = k / 2;
474 Polynomial<T> ans = (*this).pow(half_k);
475 ans *= ans;
476 return ans;
477 }
478 int half_k = (k - 1) / 2;
479 Polynomial<T> ans = (*this).pow(half_k);
480 ans *= ans;
481 ans *= *this;
482 return ans;
483 }
484
486
495 if (other.isZero() || isInvalid() || other.isInvalid()) {
496 return InvalidPoly();
497 }
498 Polynomial<T> Q, R;
499 quot_rem(*this, other, Q, R);
500 return Q;
501 }
502
504 *this = (*this) / other;
505 return *this;
506 }
507
509
518 if (isInvalid() || other.isInvalid() || other.isZero()) {
519 return InvalidPoly();
520 }
521 Polynomial<T> Q, R;
522 quot_rem(*this, other, Q, R);
523 return R;
524 }
525
527 (*this) = (*this) % other;
528 return *this;
529 }
530
532
536 void make_monic() {
537 if (deg() < 0) { return; }
538 T lead = coef[dg];
539 for (int j = 0; j <= dg; j++) { coef[j] /= lead; }
540 }
541
547 bool is_monic() const {
548 if (deg() < 0) { return false; }
549 return coef[dg] == T(1);
550 }
551
552 }; // end of Polynomial<T> class template
553
555 template<typename T>
556 ostream& operator<<(ostream & os, const Polynomial<T>& P) {
557 if (P.isInvalid()) {
558 os << "INVALID" << endl;
559 return os;
560 }
561 if (P.deg() <= 0) {
562 os << "(" << P[0] << ")";
563 return os;
564 }
565 for (int k = P.deg(); k >= 0; k--) {
566 if (P[k] != T(0)) {
567 if (k < P.deg()) os << " + ";
568 os << "(" << P[k] << ")";
569 if (k > 1) {
570 os << "X^" << k;
571 continue;
572 }
573 if (k == 1) {
574 os << "X";
575 }
576 }
577 }
578 return os;
579 }
580
581 template<typename U, typename T>
583 return P + T(x);
584 }
585
586 template<typename U, typename T>
588 return (-P) + T(x);
589 }
590
591 template<typename U, typename T>
593 return P * T(x);
594 }
595
597
605 template<typename T>
606 void quot_rem(const Polynomial<T>& A, const Polynomial<T>& B,
608 if (B.isZero() || B.isInvalid() || A.isInvalid()) {
609 Q.setInvalidPoly();
610 R.setInvalidPoly();
611 return;
612 }
613 Q.clear();
614 R.clear();
615 Polynomial<T> AA(A); // az A másolata
616 while (AA.deg() >= B.deg()) {
617 int k = AA.deg() - B.deg();
618 Polynomial<T> BB = B;
619 BB.shift(k);
620 T a_lead = AA[AA.deg()];
621 T b_lead = BB[BB.deg()];
622 for (int j = 0; j <= BB.deg(); j++) {
623 BB.set(j, BB[j] * a_lead / b_lead);
624 }
625 AA -= BB;
626 Q.set(k, a_lead / b_lead);
627 }
628 R = A - Q * B;
629 }
630
632
639 template<typename T>
641 if (A.isInvalid() || B.isInvalid() || (A.isZero() && B.isZero())) {
642 Polynomial<T> ans;
643 ans.setInvalidPoly();
644 return ans;
645 }
646 if (B.isZero()) {
647 if (A.is_monic()) { return A; }
648 Polynomial<T> AA(A);
649 AA.make_monic();
650 return AA;
651 }
653 C = A % B;
654 return gcd(B, C);
655 }
656
658
668 template<typename T>
671 Polynomial<T> D; // ebbe kerül a visszatérési érték
672
673 if ((A.isZero() && B.isZero()) || A.isInvalid || B.isInvalid()) {
674 X.setInvalidPoly();
675 Y.setInvalidPoly();
676 D.setInvalidPoly();
677 return D;
678 }
679
680 // Ha A nem 0, de B igen, D = A/a_lead, X = a_lead, Y = 0
681 if (B.isZero()) {
682 D = A;
683 T a_lead = A[A.deg()];
684 D.make_monic();
685 X = Polynomial<T>(T(1) / a_lead);
686 Y.clear();
687 return D;
688 }
689
690 // ha sem A, sem B nem 0, akkor rekurzívan számolunk
693 quot_rem(A, B, Q, R);
694 Polynomial<T> XX;
695 Polynomial<T> YY;
696 D = gcd(B, R, XX, YY);
697
698 X = YY;
699 Y = XX - Q * YY;
700
701 return D;
702 }
703
704}//namespace bme
705
706#endif
Polynomial()
Default konstruktor.
bool operator!=(const Polynomial< T > &other) const
Polynomial< T > operator()(const Polynomial< T > &other) const
Polinom behelyettesítése.
T operator()(const T &a) const
Behelyettesítés.
Polynomial< T > & operator-=(const Polynomial< T > &other)
Polynomial< T > operator*(const Polynomial< T > &other) const
Polinomok szorzása.
const T & getCoef(int deg) const
Polinom együtthatóinak lekérdezése.
void clear()
Nullpolinom beállítása.
bool isZero() const
Nullpolinom vizsgálata.
void setInvalidPoly()
Invalid polinom beállítása.
bool operator<(const Polynomial< T > &other) const
Polinomok összehasonlítása.
Polynomial< T > pow(int k) const
Polinomok hatványozása.
bool operator==(const Polynomial< T > &other) const
Polinomok egyenlősége.
int deg() const
Polinom foka.
void shift(int n=1)
Shift (X^n)-nel.
void set(int deg, const T &val)
Polinom együtthatóinak beállítása.
bool is_monic() const
bool operator>=(const Polynomial< T > &other) const
Polynomial< T > operator+(const Polynomial< T > &other) const
void minimize()
Memória felszabadítása.
T of(const T &a) const
Behelyettesítés.
Polynomial< T > operator-(const Polynomial< T > &other) const
Polynomial< T > & operator%=(const Polynomial< T > &other)
Polynomial< T > of(const Polynomial< T > &other) const
Polinom behelyettesítése.
bool operator<=(const Polynomial< T > &other) const
Polynomial< T > operator%(const Polynomial< T > &other) const
Polinomok maradékos osztása.
Polynomial< T > & operator/=(const Polynomial< T > &other)
bool operator>(const Polynomial< T > &other) const
Polynomial< T > & operator+=(const Polynomial< T > &other)
const T & operator[](int deg) const
Polinom együtthatóinak lekérdezése.
bool isInvalid() const
Invalid polinom vizsgálata.
Polynomial< T > operator-() const
void make_monic()
Polinom normálása.
Polynomial< T > operator/(const Polynomial< T > &other) const
Polinomok osztása.
Polynomial< T > & operator*=(const Polynomial< T > &other)
void quot_rem(const Polynomial< T > &A, const Polynomial< T > &B, Polynomial< T > &Q, Polynomial< T > &R)
Polinom maradékos osztása.
Polynomial< T > gcd(const Polynomial< T > &A, const Polynomial< T > &B)
Polinomok legnagyobb közös osztója.
ostream & operator<<(ostream &os, const Polynomial< T > &P)
Polinom kiírása a képernyőre.
Polynomial< T > operator+(U x, const Polynomial< T > &P)
Polynomial< T > operator*(U x, const Polynomial< T > &P)
Polynomial< T > operator-(U x, const Polynomial< T > &P)